C#P / Invoke Win32函数RegQueryInfoKey
发布时间:2020-12-16 05:03:59 所属栏目:百科 来源:网络整理
导读:我想尝试移植以下C代码: BOOL SyskeyGetClassBytes(HKEY hKeyReg,LPSTR keyName,LPSTR valueName,LPBYTE classBytes) {HKEY hKey,hSubKey;DWORD dwDisposition=0,classSize;BYTE classStr[16];LONG ret;BOOL isSuccess = FALSE;ret = RegCreateKeyEx(hKeyRe
我想尝试移植以下C代码:
BOOL SyskeyGetClassBytes(HKEY hKeyReg,LPSTR keyName,LPSTR valueName,LPBYTE classBytes) { HKEY hKey,hSubKey; DWORD dwDisposition=0,classSize; BYTE classStr[16]; LONG ret; BOOL isSuccess = FALSE; ret = RegCreateKeyEx(hKeyReg,keyName,NULL,REG_OPTION_NON_VOLATILE,KEY_QUERY_VALUE,&hKey,&dwDisposition); if(ret!=ERROR_SUCCESS) return FALSE; else if(dwDisposition!=REG_OPENED_EXISTING_KEY) { RegCloseKey(hKey); return FALSE; } else { if(RegOpenKeyEx(hKey,valueName,KEY_READ,&hSubKey)==ERROR_SUCCESS) { classSize = 8+1; ret = RegQueryInfoKey(hSubKey,(LPTSTR)classStr,&classSize,NULL); if((ret==ERROR_SUCCESS)&&(classSize==8)) { classBytes[0]= (HexDigitToByte(classStr[0]) << 4) | HexDigitToByte(classStr[1]); classBytes[1]= (HexDigitToByte(classStr[2]) << 4) | HexDigitToByte(classStr[3]); classBytes[2]= (HexDigitToByte(classStr[4]) << 4) | HexDigitToByte(classStr[5]); classBytes[3]= (HexDigitToByte(classStr[6]) << 4) | HexDigitToByte(classStr[7]); isSuccess = TRUE; } RegCloseKey(hSubKey); } RegCloseKey(hKey); } return isSuccess; } 我花了5个小时试图弄清楚我的问题,没有成功.我知道我正在调用这种方法.我的C#代码是 unsafe static bool SyskeyGetClassBytes(RegistryHive hKeyReg,string keyName,string valueName,byte* classBytes) { UIntPtr hSubKey; UIntPtr hKey; RegResult tmp; ; uint classSize; StringBuilder classStr = new StringBuilder(); int ret; bool isSuccess = false; ret = RegCreateKeyEx(hKeyReg,null,RegOption.NonVolatile,RegSAM.QueryValue,UIntPtr.Zero,out hKey,out tmp); if (ret != 0) { return false; } else if (tmp != RegResult.OpenedExistingKey) { return false; } else { int res = RegOpenKeyEx(hKey,(int)RegSAM.Read,out hSubKey); if (res == 0) { classSize = 8 + 1; ret = RegQueryInfoKey(hSubKey,out classStr,ref classSize,IntPtr.Zero,IntPtr.Zero); if ((classSize == 8)) { classBytes[0] = (byte)((byte)(HexDigitToByte(classStr[0]) << (byte)4) | HexDigitToByte(classStr[1])); classBytes[1] = (byte)((byte)(HexDigitToByte(classStr[2]) << (byte)4) | HexDigitToByte(classStr[3])); classBytes[2] = (byte)((byte)(HexDigitToByte(classStr[4]) << (byte)4) | HexDigitToByte(classStr[5])); classBytes[3] = (byte)((byte)(HexDigitToByte(classStr[6]) << (byte)4) | HexDigitToByte(classStr[7])); isSuccess = true; } RegCloseKey(hSubKey); } else { return false; } RegCloseKey(hKey); } return isSuccess; } 它对我来说有点难以调试,但最终我确定问题是在这一行发生的.之后执行似乎停止了. ret = RegQueryInfoKey(hSubKey,IntPtr.Zero); 我知道这不是权限问题,因为这个C#程序使用admin perms AND作为本地系统帐户运行.我需要的.Net API不提供的方法是RegQueryInfoKey.我的P / Invoke签名和使用的类型是: [StructLayout(LayoutKind.Sequential)] public struct SECURITY_ATTRIBUTES { public int nLength; public unsafe byte* lpSecurityDescriptor; public int bInheritHandle; } [Flags] public enum RegOption { NonVolatile = 0x0,Volatile = 0x1,CreateLink = 0x2,BackupRestore = 0x4,OpenLink = 0x8 } [Flags] 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 } public enum RegResult { CreatedNewKey = 0x00000001,OpenedExistingKey = 0x00000002 } [DllImport("advapi32.dll",CharSet = CharSet.Auto)] public static extern int RegOpenKeyEx( UIntPtr hKey,string subKey,int ulOptions,int samDesired,out UIntPtr hkResult); [DllImport("advapi32.dll",SetLastError = true)] public static extern int RegCloseKey( UIntPtr hKey); [DllImport("advapi32.dll",SetLastError = true)] static extern int RegCreateKeyEx( RegistryHive hKey,string lpSubKey,int Reserved,string lpClass,RegOption dwOptions,RegSAM samDesired,UIntPtr lpSecurityAttributes,out UIntPtr phkResult,out RegResult lpdwDisposition); [DllImport("advapi32.dll",EntryPoint = "RegQueryInfoKey",CallingConvention = CallingConvention.Winapi,SetLastError = true)] extern private static int RegQueryInfoKey( UIntPtr hkey,out StringBuilder lpClass,ref uint lpcbClass,IntPtr lpReserved,IntPtr lpcSubKeys,IntPtr lpcbMaxSubKeyLen,IntPtr lpcbMaxClassLen,IntPtr lpcValues,IntPtr lpcbMaxValueNameLen,IntPtr lpcbMaxValueLen,IntPtr lpcbSecurityDescriptor,IntPtr lpftLastWriteTime); 解决方法
lpClass参数声明不正确.按值传递StringBuilder.
[DllImport("advapi32.dll")] extern private static int RegQueryInfoKey( UIntPtr hkey,StringBuilder lpClass,IntPtr lpftLastWriteTime ); 您还需要分配StringBuilder实例以获得所需的容量.所以,像这样分配StringBuilder: StringBuilder classStr = new StringBuilder(255);//or whatever length you like 然后像这样设置classSize: classSize = classStr.Capacity+1; 我删除了DllImport的参数.大多数都不是必需的,并且SetLastError不正确. 您的代码可能存在其他问题,但是通过这些更改,至少对RegQueryInfoKey的调用将与您的C代码匹配. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |