C++ 如何读取注册表的键值并使用 MessageBox() 将其打印到屏幕上
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10675705/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I read a key value of Registry and print it to the screen with the MessageBox()
提问by Luther
I'm new to C++ and to WinCe developing.
我是 C++ 和 WinCe 开发的新手。
I want to read a string from the registry and display with the MessageBox()
. I have tried the following.
我想从注册表中读取一个字符串并以MessageBox()
. 我尝试了以下方法。
HKEY key;
if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("System\CurrentControlSet\GPS Intermediate Driver\Drivers\SiRFStar3HW"), 0, KEY_READ, &key) != ERROR_SUCCESS)
{
MessageBox(NULL,L"Can't open the registry!",L"Error",MB_OK);
}
char value[5];
DWORD value_length=5;
DWORD type=REG_SZ;
RegQueryValueEx(key,(LPCTSTR)"Baud", NULL, &type, (LPBYTE)&value, &value_length);
wchar_t buffer[5];
_stprintf(buffer, _T("%i"), value);
::MessageBox(NULL,buffer,L"Value:",MB_OK);
::RegCloseKey(key);
So I know somethings wrong in here, but how can I solve?
所以我知道这里有问题,但我该如何解决?
回答by David Heffernan
Navigating the Win32 API can be a tricky business. The registry APIs are some of the more complicated. Here's a short program to demonstrate how to read a registry string.
导航 Win32 API 可能是一项棘手的工作。注册表 API 是一些更复杂的。这是一个演示如何读取注册表字符串的简短程序。
#include <Windows.h>
#include <iostream>
#include <string>
using namespace std;
wstring ReadRegValue(HKEY root, wstring key, wstring name)
{
HKEY hKey;
if (RegOpenKeyEx(root, key.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
throw "Could not open registry key";
DWORD type;
DWORD cbData;
if (RegQueryValueEx(hKey, name.c_str(), NULL, &type, NULL, &cbData) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
throw "Could not read registry value";
}
if (type != REG_SZ)
{
RegCloseKey(hKey);
throw "Incorrect registry value type";
}
wstring value(cbData/sizeof(wchar_t), L'//Create C++ Win32 Project in Visual Studio
//Project -> "project" Properties->Configuration Properties->C/C++->Advanced->Show Includes : YES(/ showIncludes)
//Project -> "project" Properties->Configuration Properties->General->Project Defaults->Use of MFC : Use MFC in a shared DLL
#include <iostream>
#include <afx.h>
using namespace std;
int ReadRegistryKeyAttributes(CString ConstantKeyPath)
{
//Here ConstantKeyPath is considered as Registry Key Path to Read
HKEY MyRegistryKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER, ConstantKeyPath, 0, KEY_READ, &MyRegistryKey) != ERROR_SUCCESS)
{
cout << "KeyOpen Failed" << endl;
return -1;
}
DWORD type = REG_DWORD;
DWORD cbData;
unsigned long size = 1024;
CString csVersionID;
csVersionID = _T("VersionID"); //Here VersionID is considered as Name of the Key
if (RegQueryValueEx(MyRegistryKey, csVersionID, NULL, &type, (LPBYTE)&cbData, &size) != ERROR_SUCCESS)
{
RegCloseKey(MyRegistryKey);
cout << "VersionID Key Attribute Reading Failed" << endl;
return -1; //Error
}
else
{
cout << "VersionID = " << cbData << endl; //Key value will be printed here.
}
return 1; //Success
}
int main()
{
int iResult;
CString KeyPath = _T("Software\RCD_Technologies\Rajib_Test");
iResult = ReadRegistryKeyAttributes(KeyPath);
if (iResult < 0)
{
cout << "ReadRegistryKeyAttributes operation Failed" << endl;
return -1;
}
cout << "<--- ReadRegistryKeyAttribute Operation Successfull -->" << endl;
getchar();
return 0;
}
');
if (RegQueryValueEx(hKey, name.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(&value[0]), &cbData) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
throw "Could not read registry value";
}
RegCloseKey(hKey);
size_t firstNull = value.find_first_of(L'int _tmain(int argc, _TCHAR* argv[])
{
HKEY key;
if(!RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
_T("System\CurrentControlSet\GPS Intermediate Driver\Drivers\SiRFStar3HW"),
0,
NULL,
&key))
{
MessageBox(NULL, _T("Failed to open key"), _T("Error"), 0);
return -1;
}
DWORD length;
// get the size - it's going to be 4 for a DWORD, but this shows how to deal with REG_SZ, etc
if(!RegQueryValueEx(
key,
_T("Baud"),
NULL,
NULL,
NULL,
&length))
{
MessageBox(NULL, _T("Failed to get buffer size"), _T("Error"), 0);
goto exit;
}
// allocate - again, if we know it's a DWORD, this could be simplified
BYTE *buffer = (BYTE*)LocalAlloc(LPTR, length);
// query
if(!RegQueryValueEx(
key,
_T("Baud"),
NULL, NULL,
buffer,
&length))
{
MessageBox(NULL, _T("Failed to get value data"), _T("Error"), 0);
goto exit;
}
// assuming "baud" is a DWORD, not a string
DWORD baud = *(DWORD*)buffer;
// build an output
TCHAR message[MAX_PATH];
_stprintf(message, _T("The baud value is %i"), baud);
MessageBox(NULL, message, _T("Success"), 0);
exit:
RegCloseKey(key);
return 0;
}
');
if (firstNull != string::npos)
value.resize(firstNull);
return value;
}
int wmain(int argc, wchar_t* argv[])
{
wcout << ReadRegValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\Microsoft\Windows\CurrentVersion", L"CommonFilesDir");
return 0;
}
Notes:
笔记:
- I don't have CE so this is a plain Win32 app, compiled for Unicode. I took that route because CE doesn't do ANSI characters.
- I've taken advantage of a number of C++ features. Most significantly
std::wstring
. This makes string handling a cinch. - I've used exceptions for error handling. You could replace that with some other mechanism, but it served my purpose of keeping the error handling issues in the background.
- Using exceptions makes closing the registry key slightly messy. A better solution would be to use an RAII class to wrap up the lifetime of the registry key. I've omitted that for simplicity, but in production code you would want to take that extra step.
- Usually,
RegQueryValueEx
returnsREG_SZ
data that is null-terminated. This code deals with that by truncating beyond the first null character. In case the value returned is not null-terminated, that truncation won't happen, but the value will still be fine. - I've just printed to my console, but it would be trivial for you to call
MessageBox
. Like this:MessageBox(0, value.c_str(), L"Caption", MB_OK)
- 我没有 CE,所以这是一个普通的 Win32 应用程序,为 Unicode 编译。我采取了这条路线,因为 CE 不处理 ANSI 字符。
- 我已经利用了许多 C++ 特性。最显着
std::wstring
。这使得字符串处理变得轻而易举。 - 我使用异常进行错误处理。您可以用其他一些机制替换它,但它符合我的目的,将错误处理问题保留在后台。
- 使用异常会使关闭注册表项变得有些混乱。更好的解决方案是使用 RAII 类来结束注册表项的生命周期。为简单起见,我省略了这一点,但在生产代码中,您可能需要采取额外的步骤。
- 通常,
RegQueryValueEx
返回REG_SZ
以空值结尾的数据。这段代码通过截断第一个空字符来处理这个问题。如果返回的值不是以 null 结尾的,则不会发生截断,但该值仍然可以。 - 我刚刚打印到我的控制台,但是你调用
MessageBox
. 像这样:MessageBox(0, value.c_str(), L"Caption", MB_OK)
回答by RajibTheKing
Here is a complete source code to read a key value of Registry and print it to the screen:
这是读取 Registry 的键值并将其打印到屏幕的完整源代码:
MessageBox(0,&buffer,"Value:",MB_OK);
Hope this example will be helpful who are seeking this problem.
希望这个例子对正在寻求这个问题的人有所帮助。
回答by ctacke
This is untested (my device doesn't have your key/value), but compiles for CE and gives you the gist of how you do what you're after: #include
这是未经测试的(我的设备没有您的键/值),但是针对 CE 进行编译,并为您提供了您所要做的事情的要点:#include
##代码##回答by muko
just use RegQueryValueEx and put it in buf
只需使用 RegQueryValueEx 并将其放入 buf
回答by Jo?o Marcelo Brito
When using a char array you will need to set not the buffer but the pointer to the buffer, like this:
使用 char 数组时,您需要设置的不是缓冲区而是指向缓冲区的指针,如下所示:
##代码##