[英]How to read a REG_BINARY value from registry where installations of 32bit applications are found, but on a 64bit OS using C#
我想在Win7 64位計算機上使用C#獲取注冊表中此特定節點的值:
此值位於32位應用程序的安裝位置存儲其信息的注冊表中。 我面臨的問題不是到達節點,而是返回有意義的值作為數組(字符串或整數)。
我正在使用的代碼如下所示,並改編自
和
所以我的清單是這樣的:
public static UIntPtr HKEY_LOCAL_MACHINE = new UIntPtr(0x80000002u);
[DllImport("Advapi32.dll")]
public static extern int RegQueryValueEx(int hKey, string lpValueName, int lpReserved, ref uint lpType, byte[] lpData, ref uint lpcbData);
public enum RegSAM
{
QueryValue = 0x0001,
SetValue = 0x0002,
CreateSubKey = 0x0004,
EnumerateSubKeys = 0x0008,
Notify = 0x0010,
CreateLink = 0x0020,
WOW64_32Key = 0x0200,
WOW64_64Key = 0x0100,
WOW64_Res = 0x0300,
Read = 0x00020019,
Write = 0x00020006,
Execute = 0x00020019,
AllAccess = 0x000f003f
}
string path = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion";
RegistryKey rkTest = Registry.LocalMachine.OpenSubKey(path);
try
{
int hkey = 0;
uint lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, (int)RegSAM.QueryValue | (int)RegSAM.WOW64_32Key, out hkey);
if (0 != lResult) hkey = 0;
else
{
uint lpType = 0;
uint lpcbData = 1024;
byte[] Buffer = new Byte[1024];
RegQueryValueEx(hkey, "DigitalProductID", 0, ref lpType, Buffer, ref lpcbData);
... at this point the buffer returns empty.
}
}
catch (Exception exc) { };
但是當我執行它時,我的緩沖區是空的。
如果我將String []替換為StringBuilder類,則我在此處提供的代碼可以到達頂部圖像中所示注冊表的特定位置,並讀取普通的字符串值,前提是注冊表中的值是REG_SZ類型。 但是,如果它的類型為REG_BINARY,我們該怎么辦?
有人可以向我指出我該如何實現?
PS:
只是為了表明我已經在解決類似問題上工作了幾天,我已使用下面的代碼段成功地將REG_BINARY值從注冊表成功轉換為可讀的整數數組,但前提是該值位於WOW6432節點下。
byte[] bytes = (byte[])rkTest.GetValue("DigitalProductID");
string s = Convert.ToBase64String(bytes);
List<int> int_array = new List<int>();
int temp_int = 0, i = 0;
for (i = 0; i < bytes.Length; i++) { temp_int = bytes[i]; int_array.Add(temp_int); }
我要在這里解決的問題是注冊表中32位應用程序以REG_BINARY類型存儲其信息的區域。
謝謝。
解:
顯然,我提供的第二個鏈接正是該頁面上最后一個示例所需要的。 為了在我的代碼中適應該解決方案,我必須添加如下方法GetRegKey64AsByteArray():
static public byte[] GetRegKey64AsByteArray(UIntPtr inHive, String inKeyName, RegSAM in32or64key, String inPropertyName)
{
int hkey = 0;
try {
uint lResult = RegOpenKeyEx(inHive, inKeyName, 0, (int)RegSAM.QueryValue | (int)in32or64key, out hkey);
if (0 != lResult) return null;
RegistryValueKind lpType = 0;
uint lpcbData = 2048;
// Just make a big buffer the first time
byte[] byteBuffer = new byte[1000];
// The first time, get the real size
RegQueryValueEx(hkey, inPropertyName, 0, ref lpType, byteBuffer, ref lpcbData);
// Now create a correctly sized buffer
byteBuffer = new byte[lpcbData];
// now get the real value
RegQueryValueEx(hkey, inPropertyName, 0, ref lpType, byteBuffer, ref lpcbData);
return byteBuffer;
}
finally { if (0 != hkey) RegCloseKey(hkey); }
}
然后像下面這樣在字符串中獲取REG_BINARY代碼:
byte[] byteValue64 = new byte[1024];
RegistryKey localKey = Registry.LocalMachine;
localKey = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
if (localKey != null)
{
byteValue64 = GetRegKey64AsByteArray(HKEY_LOCAL_MACHINE, @"SOFTWARE\Microsoft\Windows NT\CurrentVersion", RegSAM.WOW64_64Key, "DigitalProductID");
string s = Convert.ToBase64String(byteValue64);
//Need to do the following operation because array returns inverted!
List<int> int_array = new List<int>();
int temp_int = 0, i = 0;
for (i = 0; i < byteValue64.Length; i++) { temp_int = byteValue64[i]; int_array.Add(temp_int); }
... do something with the INT values here
}
在最后一行,我將INT數組發送給一個函數,該函數使我可以讀取字母數字字符串。
感謝大家。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.