如果在没有ref的情况下调用,则RegSetValueEx返回998(ERROR_NOACCESS)

时间:2015-05-04 14:35:41

标签: c# pointers winapi visual-studio-2013 registry

我正在尝试使用c#将DWORD写入注册表。 因注册表重定向而使用p / invoke。

我已经搜索过这个问题,最终可以让它工作但我不明白。

[DllImport("advapi32.dll", SetLastError = true)]
        static extern uint RegSetValueEx(
             IntPtr hKey,
             [MarshalAs(UnmanagedType.LPStr)]
     string lpValueName,
             int Reserved,
             RegistryValueKind dwType,
             ref IntPtr lpData,
             int cbData);

 int checkreturn = RegOpenKeyEx(HKeyLocalMachine, @"SOFTWARE\Test", 0, (int) RegistrySecurity.KEY_WOW64_64KEY | (int) RegistrySecurity.KEY_SET_VALUE, ref keyHandle);

            const int dataStored = 0;
            IntPtr p = new IntPtr(dataStored);
            int size = Marshal.SizeOf(dataStored);
            uint checkreturn2 = RegSetValueEx(keyHandle, "valueName", 0, RegistryValueKind.DWord, ref p, size);

如果我将outref放在lpData参数上,如果我不这样做会返回错误998(ERROR_NOACCESS),这是有效的,为什么会这样?如果我将IntPtr更改为int并传递实际值,也会发生同样的事情,但这次我在代码上获得了第一个异常AccessViolation。

winapi声明它是*lpData,我假设它是通过IntPtr的。

  _In_       const BYTE    *lpData,  

1 个答案:

答案 0 :(得分:1)

api需要一个指向数据的指针加上数据的大小。您无法传递charboolref。您需要传递指向数据的指针。如果您传递其他内容,API会将其解释为指向数据的指针,随机结果将会发生。

使用P / Invoke,将[DllImport("advapi32.dll", SetLastError = true)] static extern uint RegSetValueEx( IntPtr hKey, [MarshalAs(UnmanagedType.LPStr)] string lpValueName, int Reserved, RegistryValueKind dwType, ref uint lpData, int cbData); 转换为指向该内容的指针。

现在,你可以

cbData

然后在sizeof(uint)传递ref这个会起作用,因为P / Invoke的ref[MarshalAs(UnmanagedType.LPStr)]

唯一的,我建议删除

function customJavaScript() {
    jQuery(document).ready(function() {
        checkLogin();
    });
}
function checkLogin() { 
    if(com_sirsi_ent_login.isLoggedIn!==false) { 
        window.location.assign("/client/employee/search/results?te=ILS&dt=list"); 
    } 
}

因为没有它,P / Invoke将使用该方法的Unicode版本,这更为正确。