如何在C++中将std::string值传递给RegSetValueEx()

How to pass std::string value to RegSetValueEx() in C++

本文关键字:RegSetValueEx 值传 string C++ 中将 std      更新时间:2023-10-16

我正在编写一个用C++编辑windows注册表项的程序,但当我试图将字符串值传递给库函数RegSetValueEx()时,有一个以TEXT()开头的文件,其中只能是硬编码值。

我的部分代码:

string region;
string excelserver_type;
string keyname = region + excelserver_type;
if (RegSetValueEx(key64, TEXT("XXXXXXXXX"), 0, REG_SZ, (LPBYTE)TEXT("XXXXXXXXXX"), 100) != ERROR_SUCCESS)
{
RegCloseKey(key);
cout << "Unable to set registry value in HKEY_LOCAL_MACHINE\Software" << endl;
}

当我试图用keyname替换"XXXXXXXX"时,它会给我一个错误。如何在RegSetValueEx()中传递keyname的值?

您需要使用std::wstring类型。这将为您提供一个基于wchar_t类型的宽(Unicode)字符串,这就是Windows在内部存储字符串的方式。

然后,您可以简单地使用c_str()成员函数来检索指向C样式字符串的指针,并将其直接传递给RegSetValueEx函数。size()成员函数为您提供字符串的长度,您可以将其作为cbData参数传递,但有两个注意事项:

  • cbData期望字符串的长度包括终止NUL字符,因此需要在size()返回的长度上加1
  • cbData要求字符串的大小以字节为单位,而不是字符数,因此对于宽字符串,您需要将size()返回的值乘以wchar_t的长度
bool SetStringValue(HKEY                hRegistryKey,
const std::wstring& valueName,
const std::wstring& data)
{
assert(hRegistryKey != nullptr);
return (RegSetValueExW(hRegistryKey,
valueName.c_str(),
0,
REG_SZ,
(LPBYTE)(data.c_str()),
(data.size() + 1) * sizeof(wchar_t)) == ERROR_SUCCESS);
}

如果你绝对必须使用窄(ANSI)字符串(你不应该这样做,因为你在这里直接与操作系统接口,而不是处理用户数据),你可以做同样的事情,但明确地调用ANSI版本的RegSetValueEx,它有一个A后缀。在这里,您仍然需要在长度上加1,但字节大小等于字符数,因此不需要缩放。

bool SetStringValue_ANSI(HKEY                hRegistryKey,
const std::string& valueName,
const std::string& data)
{
assert(hRegistryKey != nullptr);
return (RegSetValueExA(hRegistryKey,
valueName.c_str(),
0,
REG_SZ,
(LPBYTE)(data.c_str()),
data.size() + 1) == ERROR_SUCCESS);
}

在内部,RegSetValueExA将字符串转换为Unicode,然后执行与RegSetValueExW相同的任务。