【问题标题】:How to pass std::string value to RegSetValueEx() in C++如何在 C++ 中将 std::string 值传递给 RegSetValueEx()
【发布时间】:2017-01-03 08:16:51
【问题描述】:

我正在编写一个程序来通过 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;
        }

当我尝试用键名替换“XXXXXXXX”时,它给了我一个错误。如何在 RegSetValueEx() 中传递键名的值?

【问题讨论】:

  • 你得到什么错误信息?

标签: c++ windows winapi


【解决方案1】:

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

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

  • cbData 期望字符串的长度包含终止 NUL 字符,因此您需要将 size() 返回的长度加 1。
  • cbData 需要以 bytes 为单位的字符串大小,而不是字符数,因此对于宽字符串,您需要将 size() 返回的值乘以 @987654332 的长度@。
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) 字符串(您不应该这样做,因为您在这里直接与操作系统交互,而不是使用用户数据),您可以做同样的事情,但显式调用RegSetValueEx 的 ANSI 版本,具有 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 相同的任务。

【讨论】:

  • 确认!唯一需要字节大小的 API 之一。在那个方面完全犯了错误。谢谢@David 和 Bo。
  • 我已经完成了 c++ 程序,我希望它在其他 Windows 7 计算机上作为 .exe 程序运行。我将 .exe 从路径 C:\Users\Administrator\Documents\Visual Studio 2015\Projects\ConsoleApplication1\x64\Debug 复制到其他 Windows 7 计算机。但是当我尝试打开 .exe 时,它​​会给出错误“程序无法启动,因为您的计算机中缺少 MSVCP140D.dll”。我不想在其他 Windows 7 电脑上安装 MS Visual Studio,我该如何解决这个问题?
  • 您正在尝试使用调试版本。您需要将发布版本传输到另一台计算机。您可能还需要安装 VS 2015 Runtime。请参阅this answer,只需更改版本号即可。 @劳尔
  • 是的,我会选择静态链接方法,因为我的编码很简单。非常感谢您的建议。
  • 最后一个任务是如何让可执行文件在我双击时以管理员权限运行?如何在编码中嵌入管理员密码?因为这个可执行文件是为域中的普通用户设计的。并且通常可执行文件不允许用户运行。
猜你喜欢
  • 2011-08-28
  • 2015-09-26
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 2010-10-25
  • 2015-02-28
  • 2020-11-04
  • 1970-01-01
相关资源
最近更新 更多