首页 > 解决方案 > 将文件系统路径转换为 ​​const BYTE* 的问题

问题描述

我想要实现的是使用注册表在 Windows 启动时执行我的程序。当我尝试放置文件位置时,编译器抱怨它无法filesystem::pathconst BYTE*. 我不知道如何解决这个问题,因为我是 C++ 的初学者。我提供了以下代码:

HKEY newValue;
RegOpenKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", &newValue);
RegSetValueEx(newValue, "myprogram", 0, REG_SZ, fs::temp_directory_path().append(filename), sizeof("tes3t")); // This line is the issue. fs::temp_directory_path().append(filename)
RegCloseKey(newValue);
return 0;

例外:不存在从“std:filesystem::path”到“const BYTE *”的合适转换函数

标签: c++winapifilesystemsc++17registry

解决方案


根据RegSetValueExA()文档,该函数不接受std::filesystem::path对象。这就是错误消息所抱怨的。

LSTATUS RegSetValueExA(
  HKEY       hKey,
  LPCSTR     lpValueName,
  DWORD      Reserved,
  DWORD      dwType,
  const BYTE *lpData, // <-- here
  DWORD      cbData
);

第 5 个参数采用const BYTE*指向以null 结尾的 C 样式字符串的指针。第 6 个参数取字符串中的字符数,包括空终止符:

lpData

要存储的数据。

对于基于字符串的类型,例如 REG_SZ,字符串必须以 null 结尾。对于 REG_MULTI_SZ 数据类型,字符串必须以两个空字符结束。

注意 表示空值的lpData是有效的,但是,如果是这种情况,则 cbData必须设置为“0”。

cbData

lpData参数指向的信息的大小,以字节为单位。如果数据的类型为 REG_SZ、REG_EXPAND_SZ 或 REG_MULTI_SZ,则 cbData必须包括终止空字符的大小

std::filesystem::path没有隐式转换为const BYTE*,因此编译器错误。您需要先显式转换path为 astd::stringstd::wstring第一个(更喜欢后者,因为注册表在内部将字符串存储为 Unicode),然后才能将该字符串值保存到注册表,例如:

// using std::string...

HKEY newValue;

// don't use RegOpenKey()! It is provided only for backwards compatibility with 16bit apps...
if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_SET_VALUE, &newValue) == 0)
{
    // this may lose data for non-ASCII characters!
    std::string s = fs::temp_directory_path().append(filename).string();

    // this will convert the ANSI string to Unicode for you...
    RegSetValueExA(newValue, "myprogram", 0, REG_SZ, reinterpret_cast<LPCBYTE>(s.c_str()), s.size()+1);

    RegCloseKey(newValue);
}

return 0;
// using std::wstring...

HKEY newValue;

// don't use RegOpenKey()! It is provided only for backwards compatibility with 16bit apps...
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_SET_VALUE, &newValue) == 0)
{
    // no data loss here!
    std::wstring s = fs::temp_directory_path().append(filename).wstring();

    // no ANSI->Unicode conversion is performed here...
    RegSetValueExW(newValue, L"myprogram", 0, REG_SZ, reinterpret_cast<LPCBYTE>(s.c_str()), (s.size()+1) * sizeof(WCHAR));

    RegCloseKey(newValue);
}

return 0;

推荐阅读