目前我正在使用
RegQueryValueEx()
检索可能以 REG_SZ
或 REG_DWORD
格式写入的注册表值。
BYTE byteArray[MAX];
DWORD dataSize = sizeof(byteArray);
DWORD type = 0;
RegQueryValueEx(
hKey,
subKey,
nullptr,
&type,
reinterpret_cast<BYTE*>(&byteArray),
&dataSize));
当我获取
REG_SZ
值的数据(例如:“42314”)时,我得到以下响应:
byteArray 0x004fe6a8 "4" unsigned char[100]
[0] 52 '4' unsigned char
[1] 0 '\0' unsigned char
[2] 50 '2' unsigned char
[3] 0 '\0' unsigned char
[4] 51 '3' unsigned char
[5] 0 '\0' unsigned char
[6] 49 '1' unsigned char
[7] 0 '\0' unsigned char
[8] 52 '4' unsigned char
[9] 0 '\0' unsigned char
[10]0 '\0' unsigned char
有什么办法可以让每个字符后面都没有空字节吗?我认为这是因为每个角色都被称为
RegEnumValue()
,但我不确定。
您的问题与
RegEnumValue()
无关。
您的应用程序正在调用基于
TCHAR
的 RegQueryValueEx()
,它实际上是一个预处理器宏,映射到 RegQueryValueExA()
(ANSI) 或 RegQueryValueExW()
(Unicode),具体取决于 UNICODE
是否在编译时定义 -时间。
RegQueryValueExW()
以 UTF-16LE 格式将字符串数据返回为 Unicode 文本,这正是您在缓冲区中看到的内容,因此显然您的应用程序正在针对 Unicode 进行编译。您所看到的是完全正常的行为。
因此,您需要按照给定的格式处理字符串数据,例如:
BYTE byteArray[MAX];
DWORD dataSize = sizeof(byteArray);
DWORD type = 0;
if (RegQueryValueEx( // <-- calling the TCHAR version!
hKey,
subKey,
nullptr,
&type,
reinterpret_cast<BYTE*>(&byteArray),
&dataSize) == 0)
{
switch (type)
{
case REG_DWORD:
{
LPDWORD value = reinterpret_cast<LPDWORD>(&byteArray);
// use *value as needed ...
break;
}
case REG_SZ:
case REG_MULTI_SZ:
case REG_EXPAND_SZ:
{
// note the T in LPTSTR! That means 'TCHAR' is used...
LPTSTR text = reinterpret_cast<LPTSTR>(&byteArray);
// use text as needed, up to (dataSize/sizeof(TCHAR)) number
// of TCHARs. This is because RegQueryValueEx() does not
// guarantee the output data has a null terminator. If you
// want that, use RegGetValue() instead...
break;
}
}
}
或者:
BYTE byteArray[MAX];
DWORD dataSize = sizeof(byteArray);
DWORD type = 0;
if (RegQueryValueExW( // <-- calling the UNICODE version!
hKey,
subKey,
nullptr,
&type,
reinterpret_cast<BYTE*>(&byteArray),
&dataSize) == 0)
{
switch (type)
{
case REG_DWORD:
{
LPDWORD value = reinterpret_cast<LPDWORD>(&byteArray);
// use *value as needed ...
break;
}
case REG_SZ:
case REG_MULTI_SZ:
case REG_EXPAND_SZ:
{
// note the W in LPWSTR! That means 'WCHAR' is used...
LPWSTR text = reinterpret_cast<LPWSTR>(&byteArray);
// use text as needed, up to (dataSize/sizeof(WCHAR)) number
// of WCHARs. This is because RegQueryValueExW() does not
// guarantee the output data has a null terminator. If you
// want that, use RegGetValueW() instead...
break;
}
}
}
如果您想要其他格式的文本,您必须:
将其读取为 Unicode 后将其转换,例如使用
WideCharToMultiByte()
或等效的。直接使用
RegQueryValueExA()
(或 RegGetValueA()
),根据文档,这将返回用户当前语言环境中的 ANSI 文本字符串数据:
如果数据具有
、REG_SZ
或REG_MULTI_SZ
类型,并且使用此函数的 ANSI 版本(通过显式调用REG_EXPAND_SZ
或在包含RegQueryValueExA
文件之前不定义UNICODE
) ),该函数将存储的 Unicode 字符串转换为 ANSI 字符串,然后将其复制到Windows.h
指向的缓冲区。lpData
BYTE byteArray[MAX];
DWORD dataSize = sizeof(byteArray);
DWORD type = 0;
if (RegQueryValueExA( // <-- calling the ANSI version
hKey,
subKey,
nullptr,
&type,
reinterpret_cast<BYTE*>(&byteArray),
&dataSize) == 0)
{
switch (type)
{
case REG_DWORD:
{
LPDWORD value = reinterpret_cast<LPDWORD>(&byteArray);
// use *value as needed ...
break;
}
case REG_SZ:
case REG_MULTI_SZ:
case REG_EXPAND_SZ:
{
// note the lack of T in LPSTR! That means 'char' is used...
LPSTR text = reinterpret_cast<LPSTR>(&byteArray);
// use text as needed, up to dataSize number of chars. This
// is because RegQueryValueExA() does not guarantee the
// output data has a null terminator. If you want that,
// use RegGetValueA() instead...
break;
}
}
}
无论哪种方式,请注意,您将面临丢失您决定转换的目标字符集中不存在的任何非 ASCII 字符的风险。因此,最好坚持使用 Unicode,并将缓冲区数据处理为
WCHAR
数据(定义 TCHAR
时 UNICODE
映射到什么)。
Example showing opening/creating key, setting value, and finally querying it.
#include "stdafx.h"
#include <atlbase.h>
void MessageIDs_RegistryAdd() {
LONG nError = 0;
HKEY ROOT_KEY = HKEY_CURRENT_USER;
HKEY hOpenKey = 0;
char *strKey = "Software\\AKey\\AnotherKey";
// Open Key
nError = RegOpenKeyEx( ROOT_KEY, strKey, NULL, KEY_ALL_ACCESS, &hOpenKey );
if (nError == ERROR_FILE_NOT_FOUND) {
// Create Key
nError = RegCreateKeyEx( ROOT_KEY, strKey, NULL, NULL, REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS, NULL, &hOpenKey, NULL);
}
if ( nError != ERROR_SUCCESS ) {
OutputDebugString(" Error opening/creating key\r\n");
return;
}
// Set Key Value
DWORD dwValue = 42;
nError = RegSetValueEx( hOpenKey, NULL, 0, REG_DWORD, (const BYTE*)&dwValue, sizeof(dwValue) );
if ( nError != ERROR_SUCCESS ) {
OutputDebugString(" Error setting key value\r\n");
return;
}
// Read Key
const int MAX = 4096;
DWORD type = REG_DWORD;
DWORD dataSize = sizeof(DWORD);
DWORD theVal = 0;
nError = RegQueryValueEx( hOpenKey, NULL, nullptr, &type, reinterpret_cast<BYTE*>(&theVal), &dataSize );
if ( nError != ERROR_SUCCESS ) {
OutputDebugString(" Error reading key value\r\n");
return;
}
// Close key
nError = RegCloseKey( hOpenKey );
if ( nError != ERROR_SUCCESS ) {
OutputDebugString(" Error closing key.");
return;
}
return;
}
// Darryl Bassett