RegGetValue 问题

发布于 2024-11-15 00:35:29 字数 1168 浏览 0 评论 0原文

我正在尝试用 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);
}

现在,我需要能够将 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)

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

I'm trying to write(what I thought would be) a simple script in C++ to search through the registry(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall specifically) and return the value of the DisplayName value.

I have gone through the MSDN docs, and hours of searching on google, unfortunately I'm stuck.

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

Now, I need to be able to append achKey to the 2nd parameter of RegGetValue, so that it grabs the correct values when looping through each subkey.

I've tried a million different things, unfortunately my experience in C++ is pretty limited and my google skills apparently need some work as well.

Edit:
achKey is the name of the key:
Ex: NVIDIA Drivers

So when appended, the 2nd param should read:

SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\NVIDIA Drivers

Here's the MSDN reference on RegGetValue:
http://msdn.microsoft.com/en-us/library/ms724868%28v=vs.85%29.aspx

I have also tried something like:

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

It will compile, but then when run, it crashes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

转角预定愛 2024-11-22 00:35:29

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

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

编辑: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, ...).

There are two main issues with your original code that I can see:

  1. Mixing Unicode/ACSII Strings : From your comments it appears you are compiling the project with Unicode strings but you are using a char value[255]. Use a wchar_t or TCHAR instead of char. the RegGetValue() function will be automatically 'forwarded' to the RegGetValueW() or RegGetValueA() functions depending on the project Unicode settings. If you wish to force a particular character set you can use those functions directly but it is generally better to just use the RegGetValue() function directly.
  2. Buffer Overflow: You are use a 255 element char buffer but passing the buffer's size as 8192. If the registry key is more than 255 bytes (not characters) then you'll overflow that buffer and bad things will happen. Make sure you pass the exact buffer size or smaller. Also be aware of the differences between bytes and characters with Unicode strings. Some functions may expect or return a buffer size in bytes and some in characters.

The following code is an example of using wide-strings in the manner you desire:

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

Edit: LPCWSTR Notes

A LPCWSTR in Windows is simple a pointer to a constant wide string, or more directly a const wchar_t * which is the same thing as a TCHAR * in a Unicode project. Note that if you changed your project to a MultiByte character set then the function declaration of RegGetValue() (and a host of other Windows functions) would change to using a LPCSTR instead and a TCHAR would simply be a char.

The nice thing about using std::string/wstring is that they are directly compatible with a LPCWSTR and a LPCSTR. Thus your call to RegGetValue() can use the std::wstring variables directly like:

std::wstring BaseKey(_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"));
std::wstring Value(_T("DisplayName"));
RegGetValue(HKEY_LOCAL_MACHINE, BaseKey, Value, ...).
折戟 2024-11-22 00:35:29

我也尝试过类似的方法:

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

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

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

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

I have also tried something like:

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

It will compile, but then when run, it
crashes.

That's because you are trying to concatenate something onto a literal string, so the best that will happen is you will trample over random areas of your application. I'm a little surprised it compiles without errors or warnings, as the literal string would be const...?

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

高跟鞋的旋律 2024-11-22 00:35:29

您在这里看到的是非常基本的字符串操作。例如:

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(), /* ... */);

What you're looking at here is pretty basic string manipulation. Something like:

std::string path("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
std::string achKey = get_key();

RegGetValueEx(HKEY_LOCAL_MACHINE, (path+achKey).c_str(), /* ... */);

If you're using wide strings, you want to use wstring (and wide character literals) instead:

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(), /* ... */);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文