16

我正在尝试使用 C++ 在 Windows 注册表中创建一个新的注册表项。这是我到目前为止的代码:

HKEY hKey;
    LPCTSTR sk = TEXT("SOFTWARE\\OtherTestSoftware");

    LONG openRes = RegCreateKeyEx(
            HKEY_LOCAL_MACHINE,
            sk,
            0,
            NULL,
            REG_OPTION_BACKUP_RESTORE,
            KEY_ALL_ACCESS,
            NULL,
            &hKey,
            NULL);

    if (openRes==ERROR_SUCCESS) {
        printf("Success creating key.");
    } else {
        printf("Error creating key.");
    }

    LPCTSTR value = TEXT("OtherTestSoftwareKey");
    LPCTSTR data = "OtherTestData\0";

    LONG setRes = RegSetValueEx (hKey, value, 0, REG_SZ, (LPBYTE)data, strlen(data)+1);

    if (setRes == ERROR_SUCCESS) {
        printf("Success writing to Registry.");
    } else {
        printf("Error writing to Registry.");
    }

    //RegDeleteKey(hKey, sk);

    LONG closeOut = RegCloseKey(hKey);

    if (closeOut == ERROR_SUCCESS) {
        printf("Success closing key.");
    } else {
        printf("Error closing key.");
    }

我能够使用非常相似的代码片段成功打开现有密钥(基本上用 RegOpenKeyEx 替换 RegCreateKeyEx)。我想我传递给 RegCreateKeyEx 的一个或多个参数会导致麻烦。老实说,由于我捕获的所有错误代码都显示成功,因此我不确定在哪里可能会出现问题。作为参考,这里是 RegCreateKeyEx 的函数签名:

/*
 * LONG WINAPI RegCreateKeyEx(
      __in        HKEY hKey,
      __in        LPCTSTR lpSubKey,
      __reserved  DWORD Reserved,
      __in_opt    LPTSTR lpClass,
      __in        DWORD dwOptions,
      __in        REGSAM samDesired,
      __in_opt    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
      __out       PHKEY phkResult,
      __out_opt   LPDWORD lpdwDisposition
    );
 */

任何想法都会很棒!

谢谢,布赖恩

4

4 回答 4

15

多年来,我一直在编译自己的个人函数库。其中一部分完全处理注册表访问,请参阅Registry.Cpp文件中的 CreateRegistryKey 函数。

如果你有兴趣,你可以在这里获取整个图书馆

于 2009-02-03T20:58:10.197 回答
3

如前所述,您REG_OPTION_BACKUP_RESTORE在对 的调用中指定了选项RegCreateKeyEx,这意味着您正在打开密钥以执行备份或恢复。通常,您会REG_OPTION_NON_VOLATILE改用。

你运行的是什么操作系统?在 Windows 2000/XP 中,HKEY_LOCAL_MACHINE非管理员用户无法写入注册表配置单元,因此RegCreateKeyEx将失败并出现拒绝访问错误(错误 5)。这也适用于 Vista,如果您的应用程序requestedExecutionLevel在其清单中有一个条目。如果您正在运行 Vista,并且您的应用程序没有指定 a requestedExecutionLevel(或者如果它根本没有清单),则访问HKEY_LOCAL_MACHINE将被虚拟化,因此RegCreateKeyEx应该会成功。有关详细信息,请参阅MSDN中的 Windows Vista 中的注册表虚拟化。

UNICODE您发布的代码还有一些问题,只有在您使用定义编译项目时才会变得明显。这一行:

LPCTSTR data = "OtherTestData\0";

应该

LPCTSTR data = TEXT("OtherTestData\0");

这行:

LONG setRes = RegSetValueEx(hKey, value, 0, REG_SZ,
    (LPBYTE)data, _tcslen(data)+1);

应该:

LONG setRes = RegSetValueEx(hKey, value, 0, REG_SZ,
    (LPBYTE)data, (_tcslen(data)+1) * sizeof(TCHAR));

因为cbData参数 inRegSetValueEx是以字节为单位的数据长度,而不是字符。

我希望这有帮助!

于 2009-02-03T20:56:22.073 回答
2

第一个线索是你使用REG_OPTION_BACKUP_RESTORE. 您可能不想使用该标志,因为我认为它需要您需要事先启用的特殊“备份”权限。普通应用程序不想这样做。

于 2009-02-03T19:54:24.320 回答
0

可能这就是您无法使用代码创建新密钥的原因。

这些链接可能会有所帮助。

http://www.codeguru.com/forum/archive/index.php/t-378884.html
http://www.codeguru.com/forum/archive/index.php/t-275250.html

作为旁注,请始终尝试 GetLastError() 以获取错误消息。

我没有测试过它们中的任何一个。

于 2011-05-30T12:03:03.667 回答