किसी भी व्यक्ति के लिए जो .NET के पिछले कुछ संस्करणों के लिए सी # समाधान में दिलचस्पी रखने के लिए बहुत अधिक कोड को दोबारा करने के लिए नहीं है, यह सुंदर नहीं है लेकिन यहां यह प्रतिबिंब का उपयोग करके पूरी तरह से करने योग्य है। मुझे यह चाल XSharper source code में मिली।
public static class RegistryExtensions
{
public enum RegistryHiveType
{
X86,
X64
}
static Dictionary<RegistryHive, UIntPtr> _hiveKeys = new Dictionary<RegistryHive, UIntPtr> {
{ RegistryHive.ClassesRoot, new UIntPtr(0x80000000u) },
{ RegistryHive.CurrentConfig, new UIntPtr(0x80000005u) },
{ RegistryHive.CurrentUser, new UIntPtr(0x80000001u) },
{ RegistryHive.DynData, new UIntPtr(0x80000006u) },
{ RegistryHive.LocalMachine, new UIntPtr(0x80000002u) },
{ RegistryHive.PerformanceData, new UIntPtr(0x80000004u) },
{ RegistryHive.Users, new UIntPtr(0x80000003u) }
};
static Dictionary<RegistryHiveType, RegistryAccessMask> _accessMasks = new Dictionary<RegistryHiveType, RegistryAccessMask> {
{ RegistryHiveType.X64, RegistryAccessMask.Wow6464 },
{ RegistryHiveType.X86, RegistryAccessMask.WoW6432 }
};
[Flags]
public enum RegistryAccessMask
{
QueryValue = 0x0001,
SetValue = 0x0002,
CreateSubKey = 0x0004,
EnumerateSubKeys = 0x0008,
Notify = 0x0010,
CreateLink = 0x0020,
WoW6432 = 0x0200,
Wow6464 = 0x0100,
Write = 0x20006,
Read = 0x20019,
Execute = 0x20019,
AllAccess = 0xF003F
}
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int RegOpenKeyEx(
UIntPtr hKey,
string subKey,
uint ulOptions,
uint samDesired,
out IntPtr hkResult);
public static RegistryKey OpenBaseKey(RegistryHive registryHive, RegistryHiveType registryType)
{
UIntPtr hiveKey = _hiveKeys[registryHive];
if (Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major > 5)
{
RegistryAccessMask flags = RegistryAccessMask.QueryValue | RegistryAccessMask.EnumerateSubKeys | RegistryAccessMask.SetValue | RegistryAccessMask.CreateSubKey | _accessMasks[registryType];
IntPtr keyHandlePointer = IntPtr.Zero;
int result = RegOpenKeyEx(hiveKey, String.Empty, 0, (uint)flags, out keyHandlePointer);
if (result == 0)
{
var safeRegistryHandleType = typeof(SafeHandleZeroOrMinusOneIsInvalid).Assembly.GetType("Microsoft.Win32.SafeHandles.SafeRegistryHandle");
var safeRegistryHandleConstructor = safeRegistryHandleType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(IntPtr), typeof(bool) }, null); // .NET < 4
if (safeRegistryHandleConstructor == null)
safeRegistryHandleConstructor = safeRegistryHandleType.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, new[] { typeof(IntPtr), typeof(bool) }, null); // .NET >= 4
var keyHandle = safeRegistryHandleConstructor.Invoke(new object[] { keyHandlePointer, true });
var net3Constructor = typeof(RegistryKey).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { safeRegistryHandleType, typeof(bool) }, null);
var net4Constructor = typeof(RegistryKey).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(IntPtr), typeof(bool), typeof(bool), typeof(bool), typeof(bool) }, null);
object key;
if (net4Constructor != null)
key = net4Constructor.Invoke(new object[] { keyHandlePointer, true, false, false, hiveKey == _hiveKeys[RegistryHive.PerformanceData] });
else if (net3Constructor != null)
key = net3Constructor.Invoke(new object[] { keyHandle, true });
else
{
var keyFromHandleMethod = typeof(RegistryKey).GetMethod("FromHandle", BindingFlags.Static | BindingFlags.Public, null, new[] { safeRegistryHandleType }, null);
key = keyFromHandleMethod.Invoke(null, new object[] { keyHandle });
}
var field = typeof(RegistryKey).GetField("keyName", BindingFlags.Instance | BindingFlags.NonPublic);
if (field != null)
field.SetValue(key, String.Empty);
return (RegistryKey)key;
}
else if (result == 2) // The key does not exist.
return null;
throw new Win32Exception(result);
}
throw new PlatformNotSupportedException("The platform or operating system must be Windows XP or later.");
}
}
उदाहरण उपयोग:
var key64 = RegistryExtensions.OpenBaseKey(RegistryHive.LocalMachine, RegistryExtensions.RegistryHiveType.X64);
var key32 = RegistryExtensions.OpenBaseKey(RegistryHive.LocalMachine, RegistryExtensions.RegistryHiveType.X86);
यह बहुत अच्छा है। काश मैं आपको अधिक अंक दे सकता हूं। –
@ ब्लैकफ्रोग खुशी है यह मेरे साथी देवताओं की मदद करता है :) – Alexandru
बहुत बढ़िया कोड! सहायता के लिए धन्यवाद। ऐसा लगता है कि हालांकि कोड और टिप्पणियों के बीच एक मेल नहीं है। यदि यह वास्तव में "विंडोज 2000 और बाद में" के लिए है, तो मुझे लगता है कि तुलना "पर्यावरण .OSVersion.Version.Major> = 5" –