RegGetValue 问题

Jos*_*osh 2 c++ registry winapi

我正在尝试用 C++ 编写(我认为是)一个简单的脚本来搜索注册表(特别是 SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall)并返回 DisplayName 值的值。

我已经浏览了 MSDN 文档,并在谷歌上搜索了数小时,不幸的是我被卡住了。

#define BUFFER 8192
char value[255];
DWORD BufferSize = BUFFER;

if(RegGetValue(HKEY_LOCAL_MACHINE,
    _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"),
    _T("DisplayName"),
    RRF_RT_ANY,
    NULL,
    (PVOID)&value,
    &BufferSize)
    )
{
    _tprintf(TEXT("(%d) %s - %s\n"), i+1, achKey, value);
}
Run Code Online (Sandbox Code Playgroud)

现在,我需要能够将 achKey 附加到 RegGetValue 的第二个参数,以便在循环遍历每个子项时获取正确的值。

我已经尝试了一百万种不同的东西,不幸的是我在 C++ 方面的经验非常有限,而且我的谷歌技能显然也需要一些工作。

编辑:achKey 是密钥的名称:例如:NVIDIA 驱动程序

因此,附加时,第二个参数应为:

SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\NVIDIA Drivers
Run Code Online (Sandbox Code Playgroud)

这是关于 RegGetValue 的 MSDN 参考:http : //msdn.microsoft.com/en-us/library/ms724868%28v=vs.85%29.aspx

我也尝试过类似的事情:

wcscat(_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"), achKey)
Run Code Online (Sandbox Code Playgroud)

它会编译,但是当运行时,它崩溃了。

ues*_*esp 5

我可以看到您的原始代码有两个主要问题:

  1. 混合 Unicode/ACSII 字符串:从您的评论看来,您正在使用 Unicode 字符串编译项目,但您使用的是char value[255]. 使用wchar_tTCHAR代替char。该RegGetValue()函数将根据项目 Unicode 设置自动“转发”到RegGetValueW()RegGetValueA()函数。如果您希望强制使用特定字符集,您可以直接使用这些函数,但通常最好RegGetValue()直接使用该函数。
  2. 缓冲区溢出:您使用了 255 个字符的缓冲区,但将缓冲区的大小作为 8192 传递。如果注册表项超过 255 个字节(不是字符),那么您将溢出该缓冲区,并且会发生不好的事情。确保传递确切的缓冲区大小或更小。还要注意字节和字符与 Unicode 字符串之间的差异。某些函数可能期望或返回以字节为单位的缓冲区大小,而某些以字符为单位。

以下代码是以您希望的方式使用宽字符串的示例:

#include <iostream>
#include <string>

    ...
std::wstring BaseKey(_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"));
std::wstring achKey(_T("DisplayName"));
std::wstring NewKey;

NewKey = BaseKey + achKey;
wcout << NewKey << _T("\n");
NewKey = BaseKey + _T("AnotherName");
wcout << NewKey << _T("\n");
Run Code Online (Sandbox Code Playgroud)

编辑:LPCWSTR 注释

LPCWSTRWindows 中的A是一个简单的指向常量宽字符串的指针,或者更直接的 aconst wchar_t *TCHAR *Unicode 项目中的 a相同。请注意,如果您将项目更改为 MultiByte 字符集,那么RegGetValue()(以及许多其他 Windows 函数)的函数声明将更改为使用 aLPCSTR代替,而 aTCHAR将只是一个char.

使用 std::string/wstring 的好处是它们直接与 aLPCWSTR和 a兼容LPCSTR。因此,您的调用RegGetValue()可以直接使用 std::wstring 变量,例如:

std::wstring BaseKey(_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"));
std::wstring Value(_T("DisplayName"));
RegGetValue(HKEY_LOCAL_MACHINE, BaseKey, Value, ...).
Run Code Online (Sandbox Code Playgroud)