RegGetValue Question

RegGetValue Question

本文关键字:Question RegGetValue      更新时间:2023-10-16

我正在尝试编写(我认为会是什么(一个简单的脚本,以C++搜索注册表(软件\Microsoft\Windows\当前版本\卸载特别是(并返回显示名称值的值。

我已经浏览了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 - %sn"), i+1, achKey, value);
}

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

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

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

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

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)

它将编译,但在运行时,它会崩溃。

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

  1. 混合 Unicode/ACSII 字符串 :从您的评论来看,您似乎正在使用 Unicode 字符串编译项目,但您使用的是char value[255]。使用wchar_tTCHAR而不是charRegGetValue()函数将自动"转发"到RegGetValueW()RegGetValueA()函数,具体取决于项目 Unicode 设置。如果您希望强制使用特定的字符集,您可以直接使用这些函数,但通常最好直接使用 RegGetValue() 函数。
  2. 缓冲区
  3. 溢出:您使用 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");

编辑:LPCWSTR笔记

Windows 中的LPCWSTR只是指向常量宽字符串的指针,或者更直接地说是一个const wchar_t *,它与 Unicode 项目中的TCHAR *相同。请注意,如果将项目更改为多字节字符集,则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, ...).

我也尝试过类似的东西:

wcscat(_T("SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"), achKey)

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

这是因为您正在尝试将某些内容连接到文本字符串上,因此最好的情况是您将践踏应用程序的随机区域。我有点惊讶它编译时没有错误或警告,因为文字字符串将是 const...?

http://msdn.microsoft.com/en-us/library/h1x0y282%28v=vs.80%29.aspx

你在这里看到的是非常基本的字符串操作。像这样:

std::string path("SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\");
std::string achKey = get_key();
RegGetValueEx(HKEY_LOCAL_MACHINE, (path+achKey).c_str(), /* ... */);

如果使用宽字符串,则需要改用wstring(和宽字符文本(:

std::wstring path(L"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\");
std::wstring achKey = get_key(); // some function that gets the key you care about.
RegGetValueEx(HKEY_LOCAL_MACHINE, (path+achKey).c_str(), /* ... */);