2009-09-24 15 views
6

मुझे रजिस्ट्रीकी क्लास का उपयोग करके Windows Registry तक पहुंचने वाले .NET मॉड्यूल के साथ एक अजीब व्यवहार मिल रहा है।.NET का उपयोग कर Windows रजिस्ट्री तक पहुंच रहा है?

उदाहरण के लिए, मैंने एक .NET मॉड्यूल, testcom.dll लिखा है, जो रजिस्ट्री तक पहुंचता है। यह testcom.dll फ़ाइल देशी 32-बिट अनुप्रयोग और 64-बिट अनुप्रयोग दोनों द्वारा उपयोग की जाती है। मेरी आवश्यकता है कि एक regkey का मान प्राप्त करें (पथ HKEY_LOCAL_MACHINE\SOFTWARE\Test\MyParameters है और कुंजी नाम Age है)। यह "आयु" कुंजी 64-बिट मशीनों पर 32-बिट मशीनों और 64-बिट रजिस्ट्री (WOW64 नहीं) पर 32-बिट रजिस्ट्री में होगी।

64-बिट मशीन पर, जब 32-बिट अनुप्रयोग testcom.dll का उपयोग कर रहा है, तो कुंजी "आयु" WOW64 रजिस्ट्री में खोजी जाती है। जब 64-बिट अनुप्रयोग testcom.dll का उपयोग कर रहा है, तो 64-बिट रजिस्ट्री में कुंजी "आयु" की खोज की जाती है।

मेरी आवश्यकता 64-बिट मशीनों पर 64-बिट रजिस्ट्री में कुंजी को पढ़ने के लिए है जो भी अनुप्रयोग testcom.dll फ़ाइल का उपयोग करता है। मैं यह कैसे कर सकता हूँ?

+0

अजीब बात है। जब मैंने एक बार एक ऐप लिखा था जो रजिस्ट्री में कुंजियों और मानों को देखता था तो मुझे 64-बिट ओएस पर चलते समय 32-बिट अनुप्रयोग कुंजी के लिए मैन्युअल रूप से पथ बदलना पड़ा। क्या आप कुछ कोड पोस्ट कर सकते हैं? यह देखने के लिए कि क्या कुंजी लोड करने की आपकी विधि अलग है? –

+0

इसके अलावा एप्लिकेशन 32-बिट ऐप था। यह डिफ़ॉल्ट रूप से WOW64 नहीं खोजता था। –

उत्तर

4

मैं एक ऐसी ही समस्या पड़ा है, और सबसे अच्छा जवाब मैंने पाया वापस (इस तरह के RegOpenKeyEx के रूप में) करने के लिए Win32 रजिस्ट्री कार्य आते हैं और उचित Registry Key Security and Access Rights में पारित करने के लिए, विशेष रूप से KEY_WOW64_64KEY साथ samDesired पैरामीटर OR'ing है ।

यह भयानक था, और मुझे उम्मीद है कि आप यहां एक बेहतर जवाब सुनेंगे।

+0

आपके उत्तर के लिए धन्यवाद। मैं भी सर्वश्रेष्ठ के लिए आशा करता हूं :) –

+0

धन्यवाद अंततः एक उत्तर जो काम पर प्रतीत होता है। – rogerdpack

2

Win32 API पर वापस लौटने के संबंध में ब्लेयर का जवाब, और RegOpenKeyEx फ़ंक्शन को कॉल करने के बारे में यह जानकारी प्राप्त करने का सबसे अच्छा तरीका है।

विंडोज़ Registry Redirector और Registry Reflection का उपयोग करके तार्किक विचारों में विशिष्ट रजिस्ट्री स्थानों को मानचित्रित करेगा।

आप निम्न MSDN लेख में इस प्रक्रिया के बारे में अधिक पढ़ सकते हैं:
32-bit and 64-bit Application Data in the Registry

सबसे अच्छा तरीका है इस लक्ष्य को हासिल करने के लिए किया जा रहा है Win32 एपीआई के बावजूद, इस के "हार्ड-कोड" के स्थान संभावना है रजिस्ट्री जिसे आप पुनर्प्राप्त करना चाहते हैं, हालांकि यह संभावित समस्याओं से भरा हुआ है (माइक्रोसॉफ्ट स्वयं इस विधि का समर्थन नहीं करता है)। आप इस स्टैक ओवरफ़्लो प्रश्न में इस बारे में और अधिक पढ़ सकते हैं:
How to open a WOW64 registry key from a 64-bit .NET application

अंत में, Win32 एपीआई इस समय (यदि नहीं सबसे खूबसूरत) सबसे अच्छा समाधान के बारे में लगता है।
हीथ स्टीवर्ट Microsoft से this MSDN Social प्रश्न में निम्नलिखित जवाब देता है:

दुर्भाग्य से के लिए एक रास्ता Microsoft.Win32 नाम स्थान के अंतर्गत प्रबंधित रजिस्ट्री API को उन झंडे पास नहीं है। आप को मूल एपीआई जैसे को RegCreateKeyEx के रूप में संदर्भित करना होगा।

पर विचार करें, हालांकि, स्टोर डेटा को रजिस्ट्री के 32- या 64-बिट दृश्य में स्टोर डेटा की आवश्यकता है।MSDN में विषय रजिस्ट्री पुनर्निर्देशक चाबियाँ कि पुनः निर्देशित कर रहे हैं, जो आप शायद से परिचित हैं, और विषय रजिस्ट्री प्रतिबिंब कुंजी जिसमें मूल्यों 32- और 64-बिट कुंजी के बीच कॉपी कर रहे हैं है।

आप अलग विचारों की जरूरत है वास्तव में, आप भी रजिस्ट्री अपनी चाबी के लिए प्रतिबिंब को सक्षम करने के लिए यदि आप कम से कम कुछ रजिस्ट्री डेटा साझा करने के दोनों अपने 32- और 64-बिट अनुप्रयोगों इच्छा सोच सकते हैं। अधिक विवरण के लिए RegEnableReflectionKey के लिए प्रलेखन देखें।

2

निम्नलिखित कोड में, GetAge() आपकी कुंजी मान वापस कर देगा, या शून्य मौजूद नहीं होने पर शून्य हो जाएगा।

[DllImport("Advapi32.dll")] 
static extern uint RegOpenKeyEx(UIntPtr hKey, string lpSubKey, uint ulOptions, int samDesired, out int phkResult); 
[DllImport("Advapi32.dll")] 
static extern uint RegCloseKey(int hKey); 
[DllImport("advapi32.dll", EntryPoint = "RegQueryValueEx")] 
public static extern int RegQueryValueEx(int hKey, string lpValueName, int lpReserved, ref uint lpType, System.Text.StringBuilder lpData, ref uint lpcbData); 

public const int KEY_QUERY_VALUE = 0x0001; 
public const int KEY_WOW64_64KEY = 0x0100; 

static public string GetAge() 
{ 
    string EPG_REGKEY = @"SOFTWARE\Test\MyParameters"; 
    UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002; 
    int hkey = 0; 

    try 
    { 
     uint lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, EPG_REGKEY, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, out hkey); 
     if (0 != lResult) return null; 
     uint lpType = 0; 
     uint lpcbData = 1024; 
     StringBuilder AgeBuffer = new StringBuilder(1024); 
     RegQueryValueEx(hkey, "Age", 0, ref lpType, AgeBuffer, ref lpcbData); 
     string Age = AgeBuffer.ToString(); 
     return Age; 
    } 
    finally 
    { 
     if (0 != hkey) RegCloseKey(hkey); 
    } 
} 
9

यदि आप लक्ष्य को बदल सकते हैं .Net संस्करण v4 में, तो आप नए OpenBaseKey फ़ंक्शन का उपयोग कर सकते हैं उदा।

RegistryKey registryKey; 
if (Environment.Is64BitOperatingSystem == true) 
{ 
    registryKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64); 
} 
else 
{ 
    registryKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry32); 
} 
5

मैं इस पर व्यापक शोध किया और पाया कि .NET 4 में यह प्रबंधित कोड के साथ आसान नियंत्रित किया जाता है, लेकिन नेट 4 करने से पहले, आप DllImport advapi32.dll लोड करने के लिए की है।

यहां मेरा शोध है।

http://www.rhyous.com/2011/01/24/how-read-the-64-bit-registry-from-a-32-bit-application-or-vice-versa/