32 বিট অ্যাপ্লিকেশন থেকে 64 বিট রেজিস্ট্রি পড়া


100

আমার এসি # ইউনিট পরীক্ষার প্রকল্প রয়েছে যা যে কোনও সিসিপিইউয়ের জন্য সংকলিত। আমাদের বিল্ড সার্ভারটি একটি 64 বিট মেশিন এবং এতে একটি 64 বিবিট এসকিউএল এক্সপ্রেস ইনস্টলস রয়েছে।

এমডিএফ ফাইলগুলির পথ চিহ্নিত করতে পরীক্ষার প্রকল্পটি নিম্নলিখিতগুলির মতো কোড ব্যবহার করে:

private string GetExpressPath()
{
    RegistryKey sqlServerKey = Registry.LocalMachine.OpenSubKey( @"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL" );
    string sqlExpressKeyName = (string) sqlServerKey.GetValue( "SQLEXPRESS" );
    RegistryKey sqlInstanceSetupKey = sqlServerKey.OpenSubKey( sqlExpressKeyName + @"\Setup" );
    return sqlInstanceSetupKey.GetValue( "SQLDataRoot" ).ToString();
}

এই কোডটি আমাদের 32 বিট ওয়ার্কস্টেশনগুলিতে দুর্দান্ত কাজ করে এবং বিল্ড সার্ভারে ঠিক কাজ করে যতক্ষণ না আমি সম্প্রতি এনসিওভারের সাথে কোড কভারেজ বিশ্লেষণ সক্ষম করেছিলাম enabled যেহেতু এনকোভার 32 বিবিট সিওএম উপাদান ব্যবহার করে, টেস্ট রানার (গ্যালিও) 32 বিট প্রক্রিয়া হিসাবে চলে।

রেজিস্ট্রিটি পরীক্ষা করা হচ্ছে, কোনও "ইনস্ট্যান্স নাম" কী এর অধীনে নেই

HKEY_LOCAL_MACHINE OF সফ্টওয়্যার ow Wow6432 নোড \ মাইক্রোসফ্ট \ মাইক্রোসফ্ট এসকিউএল সার্ভার

Wow6432Node এর বাইরে রেজিস্ট্রি অ্যাক্সেস করার জন্য 32 বিট মোডে চলমান কোনও অ্যাপ্লিকেশনটির কি কোনও উপায় আছে?

উত্তর:


21

রেজিস্ট্রি কী তৈরি করার সময় / খোলার সময় আপনাকে KEY_WOW64_64KEY প্যারাম ব্যবহার করতে হবে। তবে এএফআইএকি এটি রেজিস্ট্রি ক্লাসের সাথে সম্ভব নয় তবে কেবলমাত্র সরাসরি এপিআই ব্যবহার করার সময়।

এটি আপনাকে শুরু করতে সহায়তা করতে পারে।


152

.NET ফ্রেমওয়ার্ক 4.x ব্যবহার করে bit৪ বিট উইন্ডোজের নিচে রেজিস্ট্রি অ্যাক্সেসের জন্য স্থানীয় সমর্থন রয়েছে । নিম্নলিখিত কোডটি উইন্ডোজ 7, ​​64 বিট   এবং উইন্ডোজ 10, 64 বিটের সাথেও   পরীক্ষা করা হয়   ।

ব্যবহারের পরিবর্তে "Wow6432Node", যা কোনও রেজিস্ট্রি গাছকে অন্যটিতে ম্যাপিং করে কোনও নোডকে অনুকরণ করে সেখানে কার্যত প্রদর্শিত হয়, আপনি ফলউইং করতে পারেন:

আপনার যদি 64 বিট বা 32 বিট রেজিস্ট্রি অ্যাক্সেস করতে হবে এবং নীচে বর্ণিত হিসাবে এটি ব্যবহার করুন কিনা তা স্থির করুন। আপনি পরে উল্লিখিত কোডটি (অতিরিক্ত তথ্য বিভাগ) ব্যবহার করতে পারেন, যা একটি কোয়েরিতে উভয় নোড থেকে রেজিস্ট্রি কীগুলি পেতে ইউনিয়ন কোয়েরি তৈরি করে - যাতে আপনি তাদের আসল পথটি ব্যবহার করে এখনও তাদের জিজ্ঞাসা করতে পারেন।

64 বিট রেজিস্ট্রি

64 বিট রেজিস্ট্রি অ্যাক্সেস করতে, আপনি RegistryView.Registry64নিম্নলিখিত হিসাবে ব্যবহার করতে পারেন :

string value64 = string.Empty; 
RegistryKey localKey = 
    RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, 
        RegistryView.Registry64); 
localKey = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion"); 
if (localKey != null) 
{ 
    value64 = localKey.GetValue("RegisteredOrganization").ToString(); 
    localKey.Close();
} 
Console.WriteLine(String.Format("RegisteredOrganization [value64]: {0}",value64));

32 বিট রেজিস্ট্রি

যদি আপনি 32 বিট রেজিস্ট্রি অ্যাক্সেস করতে চান তবে RegistryView.Registry32নীচের হিসাবে ব্যবহার করুন :

string value32 = string.Empty; 
RegistryKey localKey32 = 
    RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, 
        RegistryView.Registry32); 
localKey32 = localKey32.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion"); 
if (localKey32 != null) 
{ 
    value32 = localKey32.GetValue("RegisteredOrganization").ToString(); 
    localKey32.Close();
} 
Console.WriteLine(String.Format("RegisteredOrganization [value32]: {0}",value32));

বিভ্রান্ত হবেন না, উভয় সংস্করণই Microsoft.Win32.RegistryHive.LocalMachineপ্রথম প্যারামিটার হিসাবে ব্যবহার করছে , আপনি ২ য় প্যারামিটার ( বনাম ) দ্বারা bit৪ বিট বা 32 বিট ব্যবহার করবেন কিনা তা পার্থক্য তৈরি করেছেন ।RegistryView.Registry64RegistryView.Registry32

নোট যে

  • Bit৪ বিট উইন্ডোতে, 32৪ HKEY_LOCAL_MACHINE\Software\Wow6432Nodeবিট সিস্টেমে 32 বিট অ্যাপ্লিকেশন দ্বারা ব্যবহৃত মান রয়েছে। কেবল সত্য 64 বিট অ্যাপ্লিকেশনগুলি তাদের মানগুলি HKEY_LOCAL_MACHINE\Softwareসরাসরি সঞ্চয় করে । সাবট্রিটি Wow6432Node32 বিট অ্যাপ্লিকেশনগুলির জন্য সম্পূর্ণ স্বচ্ছ, 32 বিট অ্যাপ্লিকেশনগুলি এখনও HKEY_LOCAL_MACHINE\Softwareযেমনটি প্রত্যাশা করে ততক্ষণ দেখুন (এটি এক ধরণের পুনঃনির্দেশ)। পাশাপাশি 32 বিট উইন্ডোজ 7 যেমন উইন্ডোজের পুরোনো সংস্করণগুলি (এবং ভিস্তা 32 বিট) সাবট্রি Wow6432Nodeস্পষ্টত নেই না বিদ্যমান।

  • উইন্ডোজ in (bit৪ বিট) -র একটি বাগের কারণে, 32 বিট উত্স কোড সংস্করণ সর্বদা "মাইক্রোসফ্ট" ফিরিয়ে দেয় আপনি নির্বিশেষে কোন সংস্থায় registered৪ বিট উত্স কোড সংস্করণটি সঠিক সংস্থাটি ফিরিয়ে দেয়।

আপনি যে উদাহরণ সরবরাহ করেছেন তা ফিরে আসার জন্য, 64৪ বিট শাখাটি অ্যাক্সেস করার জন্য এটি নিম্নলিখিত উপায়ে করুন:

RegistryKey localKey = 
    RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, 
        RegistryView.Registry64); 
RegistryKey sqlServerKey = localKey.OpenSubKey(
    @"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL");
string sqlExpressKeyName = (string) sqlServerKey.GetValue("SQLEXPRESS");

ব্যবহারিক ব্যবহারের জন্য অতিরিক্ত তথ্য:

আমি জনি স্কোভডাল মন্তব্যগুলিতে একটি আকর্ষণীয় পন্থা যুক্ত করতে চাই , যা আমি তার পদ্ধতির সাহায্যে কিছু কার্যকর ফাংশন বিকাশের জন্য গ্রহণ করেছি: কিছু পরিস্থিতিতে আপনি সমস্ত কীগুলি 32 বিট বা নির্বিশেষে ফিরে পেতে চান 64 বিট। এসকিউএল উদাহরণগুলির নামগুলি এরকম একটি উদাহরণ। আপনি নিম্নলিখিত ক্ষেত্রে একটি ইউনিয়ন কোয়েরি ব্যবহার করতে পারেন (সি # 6 বা উচ্চতর):

// using Microsoft.Win32;
public static IEnumerable<string> GetRegValueNames(RegistryView view, string regPath,
                                  RegistryHive hive = RegistryHive.LocalMachine) 
{ 
    return RegistryKey.OpenBaseKey(hive, view)
                     ?.OpenSubKey(regPath)?.G‌​etValueNames();
}

public static IEnumerable<string> GetAllRegValueNames(string RegPath,
                                  RegistryHive hive = RegistryHive.LocalMachine) 
{
    var reg64 = GetRegValueNames(RegistryView.Registry64, RegPath, hive);
    var reg32 = GetRegValueNames(RegistryView.Re‌​gistry32, RegPath, hive);
    var result = (reg64 != null && reg32 != null) ? reg64.Union(reg32) : (reg64 ?? reg32);
    return (result ?? new List<string>().AsEnumerable()).OrderBy(x => x);
}

public static object GetRegValue(RegistryView view, string regPath, string ValueName="",
                                 RegistryHive hive = RegistryHive.LocalMachine)
{
    return RegistryKey.OpenBaseKey(hive, view)
                       ?.OpenSubKey(regPath)?.G‌​etValue(ValueName);
}

public static object GetRegValue(string RegPath, string ValueName="",
                                 RegistryHive hive = RegistryHive.LocalMachine)
{   
    return GetRegValue(RegistryView.Registry64, RegPath, ValueName, hive) 
                     ?? GetRegValue(RegistryView.Re‌​gistry32, RegPath, ValueName, hive);
}

public static IEnumerable<string> GetRegKeyNames(RegistryView view, string regPath,
                   RegistryHive hive = RegistryHive.LocalMachine)
{
    return RegistryKey.OpenBaseKey(hive, view)
        ?.OpenSubKey(regPath)?.GetSubKeyNames(); 
}

public static IEnumerable<string> GetAllRegKeyNames(string RegPath,
                                  RegistryHive hive = RegistryHive.LocalMachine)
{
    var reg64 = GetRegKeyNames(RegistryView.Registry64, RegPath, hive);
    var reg32 = GetRegKeyNames(RegistryView.Re‌​gistry32, RegPath, hive);
    var result = (reg64 != null && reg32 != null) ? reg64.Union(reg32) : (reg64 ?? reg32);
    return (result ?? new List<string>().AsEnumerable()).OrderBy(x => x);
}

এখন আপনি উপরের ফাংশনগুলি কেবল নীচের মতো ব্যবহার করতে পারেন:

উদাহরণ 1: এসকিউএল উদাহরণগুলির নাম পান

var sqlRegPath=@"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL";
foreach (var valueName in GetAllRegValueNames(sqlRegPath))
{
    var value=GetRegValue(sqlRegPath, valueName);
    Console.WriteLine($"{valueName}={value}");
}

sqlRegPath এ আপনাকে মান নাম এবং মানগুলির একটি তালিকা দেবে।

দ্রষ্টব্য: আপনি যদি উপরের সম্পর্কিত ফাংশনগুলিতে প্যারামিটার বাদ দেন তবে আপনি একটি কী ( ডিফল্ট কমান্ডলাইন সরঞ্জাম দ্বারা REGEDT32.EXEচিহ্নিত (Default)) এর মান নির্ধারণ করতে পারেন ValueName

একটি রেজিস্ট্রি কীতে সাবকিগুলির একটি তালিকা পেতে , ফাংশনটি ব্যবহার করুন GetRegKeyNamesবাGetAllRegKeyNames । আপনি রেজিস্ট্রিতে আরও কীগুলি অনুসরণ করতে এই তালিকাটি ব্যবহার করতে পারেন।

উদাহরণ 2: ইনস্টল করা সফ্টওয়্যারটির আনইনস্টল তথ্য পান

var currentVersionRegPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion";
var uninstallRegPath = $@"{currentVersionRegPath}\Uninstall";
var regKeys = Registry.GetAllRegKeyNames(RegPath: uninstallRegPath);

সমস্ত 32 বিট এবং 64 বিট আনইনস্টল কীগুলি পাবেন।

ফাংশনগুলিতে নাল হ্যান্ডলিংয়ের প্রয়োজনীয়তা লক্ষ্য করুন কারণ এসকিউএল সার্ভারটি 32 বিট বা 64৪ বিটের হিসাবে ইনস্টল করা যেতে পারে (উদাহরণস্বরূপ 1 টি)। ফাংশনগুলি ওভারলোড হয়ে গেছে যাতে প্রয়োজনে আপনি এখনও 32 বিট বা 64 বিট প্যারামিটারটি পাস করতে পারেন - তবে, আপনি যদি এটি বাদ দেন তবে এটি 64 বিট পড়ার চেষ্টা করবে, যদি এটি ব্যর্থ হয় (নাল মান), এটি 32 বিট মানগুলি পড়ে।

এখানে একটি বৈশিষ্ট্য রয়েছে: কারণ GetAllRegValueNamesসাধারণত লুপের প্রসঙ্গে ব্যবহৃত হয় (উপরে উদাহরণ 1 দেখুন), এটি লুপগুলি nullসরল করার পরিবর্তে একটি খালি গণনার ফিরিয়ে দেয় foreach: যদি এটি সেভাবে পরিচালনা করা না যায় তবে লুপটি উপস্থাপিত করতে হবে একটি ifবিবৃতি চেকnull করা অসুবিধাগুলি তা করানো হবে - যাতে ফাংশনে একবার মোকাবেলা করা হয়।

নাল সম্পর্কে কেন বিরক্ত করছেন? কারণ যদি আপনি যত্ন না পান তবে আপনার কোডটিতে কেন সেই নাল রেফারেন্স ব্যতিক্রম ছড়িয়ে দেওয়া হয়েছিল তা জানতে আপনার আরও অনেক মাথাব্যথা থাকবে - আপনি কোথায় এবং কেন এটি ঘটেছে তা খুঁজে বের করতে অনেক সময় ব্যয় করতে চাই। এবং যদি এটি উত্পাদনে ঘটে থাকে তবে আপনি লগ ফাইলগুলি বা ইভেন্টের লগগুলি অধ্যয়ন করতে খুব ব্যস্ত থাকবেন (আমি আশা করি আপনি লগিংটি কার্যকর করেছেন) ... নাল ইস্যুগুলি যেখানে আপনি একটি প্রতিরক্ষামূলক উপায়ে পারেন তা এড়ানো ভাল avoid অপারেটরগণ ?., ?[... ]এবং ??আপনাকে অনেক সহায়তা করতে পারে (উপরের কোডটি দেখুন)। সেখানে একটা চমৎকার সংশ্লিষ্ট নিবন্ধটি নতুন আলোচনা করছে C # nullable রেফারেন্স ধরনের , যা আমি পড়তে এবং সুপারিশ এই এক এলভিস অপারেটর সম্পর্কে।


ইঙ্গিত: উইন্ডোজ অধীনে সমস্ত উদাহরণ পরীক্ষা করতে আপনি লিনকপ্যাডের ফ্রি সংস্করণ ব্যবহার করতে পারেন । এটি একটি ইনস্টলেশন প্রয়োজন হয় না। নেমস্পেস আমদানি ট্যাবে টিপতে F4এবং প্রবেশ করতে ভুলবেন না Microsoft.Win32। ভিজ্যুয়াল স্টুডিওতে আপনার প্রয়োজনusing Microsoft.Win32; আপনার কোডের শীর্ষে ।

টিপ: নতুন নাল হ্যান্ডলিং অপারেটরগুলির সাথে নিজেকে পরিচিত করতে , লিনকপ্যাডে নিম্নলিখিত কোডটি চেষ্টা করুন (এবং ডিবাগ করুন):

উদাহরণ 3: নাল হ্যান্ডলিং অপারেটরগুলি প্রদর্শন করা

static string[] test { get { return null;} } // property used to return null
static void Main()
{
    test.Dump();                    // output: null
    // "elvis" operator:
    test?.Dump();                   // output: 
    // "elvis" operator for arrays
    test?[0].Dump();                // output: 
    (test?[0]).Dump();              // output: null
    // combined with null coalescing operator (brackets required):
    (test?[0]??"<null>").Dump();    // output: "<null>"
}

। নেট ফিজল দিয়ে এটি ব্যবহার করে দেখুন

আপনি যদি আগ্রহী হন তবে এই সরঞ্জামটির সাহায্যে আপনি আর কী করতে পারেন তা প্রদর্শন করার জন্য আমি এখানে কয়েকটি উদাহরণ রেখেছি।


4
যে বিস্তৃত উত্তরের জন্য ধন্যবাদ। স্মৃতি থেকে আমি মনে করি আমি প্রশ্ন পোস্ট করার সময় .NET 3.5 ব্যবহার করছিলাম, তবে দেখতে ভাল। নেট 4 পরিস্থিতি উন্নত করেছে
ডেভিড গার্ডিনার

4
আপনাকে স্বাগতম. সম্প্রতি 64৪ বিট রেজিস্ট্রি নিয়ে আমার একই সমস্যা ছিল যা আমি ইতিমধ্যে সমাধান করেছি তাই আমি ভেবেছিলাম সমাধানটি ভাগ করে নেওয়া ভাল sharing
ম্যাট

4
এটি ঠিক আমি যা খুঁজছিলাম। আমি উইন্ডোজ 9.1 এ এটি করছি এবং এটি দুর্দান্ত কাজ করে।
মিশিল বুগের

4
@ এজেড_ - সম্পাদনার জন্য আপনাকে ধন্যবাদ, আপনি ঠিক বলেছেন, কীটি বন্ধ করা দরকার!
ম্যাট

4
@ জোহনিস্কভডাল - আমি এই শিরোনামটি পরিবর্তন করেছি যে পরিষ্কার করার জন্য আমি কেবল অতিরিক্ত (alচ্ছিক) তথ্য দিচ্ছি - যারা এই বিষয়ে গভীরতর খোঁজ করতে চান তাদের জন্য।
ম্যাট

6

আমার মতামত দেওয়ার মতো যথেষ্ট প্রতিনিধি নেই তবে ওপেনরেমোটবেসেকে ব্যবহার করে রিমোট রেজিস্ট্রি খোলার সময় এটি কাজ করে তা উল্লেখ করার মতো worth রেজিস্ট্রিভিউ যোগ করুন e রেজিস্ট্রি 64৪ পরামিতি মেশিন বি-তে একটি 32-বিট প্রোগ্রামকে মেশিন বি-তে 64-বিট রেজিস্ট্রি অ্যাক্সেস করার অনুমতি দেয় আমি এই পরামিতিটি পাস করার আগে আমার প্রোগ্রামটি ওপেনরেটব্যাসেকির পরে 32-বিট পড়ছিল এবং আমি কীটি খুঁজে পাইনি I পরে ছিল।

দ্রষ্টব্য: আমার পরীক্ষায়, রিমোট মেশিনটি আসলে আমার মেশিন ছিল, তবে আমি ওপেন-রেমোটবেসেকির মাধ্যমে এটি অ্যাক্সেস করেছি, ঠিক যেমনটি আমি অন্য কোনও মেশিনের জন্য চাই।


4

এটি চেষ্টা করুন (32 বিট প্রক্রিয়া থেকে):

> %WINDIR%\sysnative\reg.exe query ...

(এটি এখানে পাওয়া গেছে )


4
দুর্দান্ত ইঙ্গিত, এটি একটি ব্যাচে রেজিস্ট্রি চালিত করতে দেয়। reg.exe /?আরও তথ্য পেতে ব্যবহার করুন ...
ম্যাট

4

আপনি এটি নেট। 4 ব্যবহার করতে না পারলে RegistryKey.OpenBaseKey(..., RegistryView.Registry64)আপনার সরাসরি উইন্ডোজ এপিআই ব্যবহার করা দরকার।

সর্বনিম্ন ইন্টারপটি হ'ল:

internal enum RegistryFlags
{
    ...
    RegSz = 0x02,
    ...
    SubKeyWow6464Key = 0x00010000,
    ...
}

internal enum RegistryType
{
    RegNone = 0,
    ...
}

[DllImport("advapi32", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int RegGetValue(
    UIntPtr hkey, string lpSubKey, string lpValue, RegistryFlags dwFlags, 
    out RegistryType pdwType, IntPtr pvData, ref uint pcbData);

এটি ব্যবহার করুন:

IntPtr data = IntPtr.Zero;
RegistryType type;
uint len = 0;
RegistryFlags flags = RegistryFlags.RegSz | RegistryFlags.SubKeyWow6464Key;
UIntPtr key = (UIntPtr)((uint)RegistryHive.LocalMachine);

const string subkey= @"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL";
const string value = "SQLEXPRESS";

if (RegGetValue(key, subkey, value, flags, out type, data, ref len) == 0)
{
    data = Marshal.AllocHGlobal((int)len);
    if (RegGetValue(key, subkey, value, flags, out type, data, ref len) == 0)
    {
        string sqlExpressKeyName = Marshal.PtrToStringUni(data);
    }
}

0

আমি যা পড়েছি এবং আমার নিজের পরীক্ষাগুলি থেকে আমার কাছে মনে হয় যে "সফটওয়্যার \ মাইক্রোসফ্ট \ উইন্ডোজ \ কারেন্ট ভার্সন \ আনইনস্টল" এই রেজিস্ট্রিটি পরীক্ষা করা উচিত। কারণ অন্যান্য পাথগুলিতে প্রোগ্রামগুলি আনইনস্টল করার পরে নিবন্ধগুলি মুছে ফেলা হয় না।

এইভাবে আমি 32 বিট কনফিগারেশন সহ 64 রেজিস্টার পেয়েছি।

string registryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
RegistryKey key64 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey key = key64.OpenSubKey(registryKey);
if (key != null)
{
    var list = key.GetSubKeyNames().Select(keyName => key.OpenSubKey(keyName).GetValue("DisplayName")).ToList();

    key.Close();
}

32 রেজিস্টারের জন্য:

registryKey = @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
key = Registry.LocalMachine.OpenSubKey(registryKey);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.