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

我经历了MSDN文档,以及在Google上搜索了数小时,不幸的是,我被卡住了。

#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);
}

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

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

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

因此,第二个参数在附加时应显示为:
SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\NVIDIA Drivers

这是RegGetValue上的MSDN引用:
http://msdn.microsoft.com/en-us/library/ms724868%28v=vs.85%29.aspx

我也尝试过类似的方法:
wcscat(_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"), achKey)

它会编译,但随后运行时会崩溃。

最佳答案

我可以看到原始代码存在两个主要问题:

  • 混合使用Unicode / ACSII字符串:从您的注释看来,您正在使用Unicode字符串编译项目,但您使用的是char value[255]。使用wchar_tTCHAR代替charRegGetValue()函数将根据项目Unicode设置自动“转发”到RegGetValueW()RegGetValueA()函数。如果您想强制使用特定的字符集,则可以直接使用这些函数,但是通常最好直接使用RegGetValue()函数。
  • 缓冲区溢出:您正在使用255个元素的char缓冲区,但将缓冲区的大小传递为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");
    

    编辑:LPCWSTR注释

    Windows中的LPCWSTR是指向恒定宽字符串的简单指针,或更直接地是const wchar_t *,它与Unicode项目中的TCHAR *相同。请注意,如果您将项目更改为MultiByte字符集,则RegGetValue()(以及许多其他Windows函数)的函数声明将改为使用LPCSTR,而TCHAR将仅是char

    使用std::string / wstring的好处是它们直接与LPCWSTRLPCSTR兼容。因此,您对RegGetValue()的调用可以直接使用std::wstring变量,例如:
    std::wstring BaseKey(_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"));
    std::wstring Value(_T("DisplayName"));
    RegGetValue(HKEY_LOCAL_MACHINE, BaseKey, Value, ...).
    

    08-06 14:47