- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试移植以下 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,0,NULL,REG_OPTION_NON_VOLATILE,KEY_QUERY_VALUE,NULL,&hKey,&dwDisposition);
if(ret!=ERROR_SUCCESS)
return FALSE;
else if(dwDisposition!=REG_OPENED_EXISTING_KEY) {
RegCloseKey(hKey);
return FALSE;
}
else {
if(RegOpenKeyEx(hKey,valueName,0,KEY_READ,&hSubKey)==ERROR_SUCCESS) {
classSize = 8+1;
ret = RegQueryInfoKey(hSubKey,(LPTSTR)classStr,&classSize,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,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, keyName, 0, 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, valueName, 0, (int)RegSAM.Read, out hSubKey);
if (res == 0)
{
classSize = 8 + 1;
ret = RegQueryInfoKey(hSubKey, out classStr, ref classSize, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 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, out classStr, ref classSize, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
我知道这不是权限问题,因为此 C# 程序以管理员权限和本地系统帐户运行。 .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,
ref uint lpcbClass,
IntPtr lpReserved,
IntPtr lpcSubKeys,
IntPtr lpcbMaxSubKeyLen,
IntPtr lpcbMaxClassLen,
IntPtr lpcValues,
IntPtr lpcbMaxValueNameLen,
IntPtr lpcbMaxValueLen,
IntPtr lpcbSecurityDescriptor,
IntPtr lpftLastWriteTime
);
您还需要分配 StringBuilder
实例以具有所需的容量。因此,像这样分配 StringBuilder
:
StringBuilder classStr = new StringBuilder(255);//or whatever length you like
然后像这样设置classSize
:
classSize = classStr.Capacity+1;
我删除了 DllImport
的参数。大多数都不是必需的,SetLastError
不正确。
您的代码可能存在其他问题,但通过这些更改,至少对 RegQueryInfoKey
的调用将与您的 C++ 代码匹配。
关于C# P/Invoke Win32 函数 RegQueryInfoKey,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16928795/
我有以下代码: Public Delegate Sub SetStatusBarTextDelegate(ByVal StatusText As String) Private Sub SetStat
在调用 Invoke-RestMethod 时使用 Powershell,例如: Invoke-RestMethod -Method Get -Uri "https://google.com/api/
我正在尝试将 Winform 应用程序转换为控制台应用程序。 Winform 应用程序有一个委托(delegate)处理程序。如何在 console 应用程序中编写相同的功能? this.Invoke
在 WPF 中,Dispatcher.Invoke 和直接在控件实例上调用的 Invoke 有什么区别。据我了解,调度程序负责处理线程的消息,Control.Invoke 是否会继续调用 Dispat
我正在研究性能监控系统,它可以将其例程注入(inject)现有程序集。为此,我试图了解 dalvik 代码的工作原理。 下面是我要完成的工作的示例。输入类可能如下所示: class MyClass{
我正在使用 powershell 命令来执行脚本和 cmdlet。因此,在执行 cmdlet 时,我使用了 powershell.invoke,而在执行脚本时,我使用了 pipeline.invoke
有人能解释一下 Invoke-Expression $test 之间的区别吗?和 Invoke-Expression -Command $test ? 变量测试是: $test = "notepad
我有四个类,即 MapperOne、ReducerOne、MapperTwo、ReducerTwo。我想要其中的一个链。 MapperOne-->ReducerOne-->输出文件生成,输入到Mapp
我正在阅读 Java ForkJoin 框架。不直接在 ForkJoinTask 的实现上调用 invoke()(例如 RecursiveTask),而是实例化 ForkJoinPool 有什么额外的
我在调用 Invoke-SqlCmd 时遇到问题,因为它包含第二个 Invoke-SqlCmd 调用: function Get-Foo { $query=` @" WITH data AS (
有人知道如何解决这个问题吗?我创建了一个客户端来使用网络服务。客户端代码为: package cliente; import java.util.List; import handler.Header
我希望使用 P/Invoke 来允许我的 C# 程序集与 native C 库互操作;这需要是跨平台的(即 Mono),因此不能使用混合模式程序集。我想知道使用不安全的 P/invoke 调用并在不安
一般来说,我对使用 Invoke-RestMethod/Invoke-WebRequest 比较陌生 - 我认为这是以下问题的重要背景。 我正在调用如下电话: $Headers = @{ "A
在 Jenkins 的一个自由风格项目(不是说 Maven2/3 项目)中,我有两个可能的构建步骤: 调用 Maven 3 调用顶级 Maven 目标 在不同的安装中,我有不同的组合(有些两者都有,有
这是完整的错误: e: C:\Users\HP\AndroidStudioProjects\MoneyManager\app\src\main\java\com\cruxrepublic\moneym
我正在编写 jQuery 插件并将它们与 AJAX 集成。我正在减少脂肪并专注于基础知识: (function($) { function MyPlugin(el, options) {
有人可以建议我如何处理这条消息吗? CA1060 Move P/Invokes to NativeMethods class Because it is a P/Invoke method, 'UCo
在java中我们可以“用类名调用一个静态方法”也可以“用一个对象调用一个静态方法”java中“用类名调用静态方法”和“用对象调用静态方法”有什么区别? 最佳答案 没有区别,但建议以静态方式调用 sta
尝试从对话框中的 EditText 获取 Edit Text 的值,但一次又一次地出现此错误 Attempt to invoke virtual method 'android.text.Editab
我正在开发一款扑翼应用程序。在出现此错误之前,读取和写入FireStore数据库没有任何问题,但随后突然出现错误(如下所示),并阻止我读取或写入数据库。我一直在寻找答案,但不幸的是,我找不到任何可以解
我是一名优秀的程序员,十分优秀!