将文件系统路径转换为 const BYTE* 的问题
Issue with converting a filesystem path to a const BYTE*
我想要实现的是使用注册表在 Windows 启动时执行我的程序。当我尝试放置文件位置时,编译器抱怨它无法从 filesystem::path
转换为 const 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;
EXCEPTION: No suitable conversion function from "std:filesystem::path" to "const BYTE *" exists
WinAPI 函数不接受 std::filesystem::path
类型的参数,因此您需要以某种方式将其转换为 const BYTE*
。
这是一个例子:
std::string fullpath = (fs::temp_directory_path() / filename).string();
RegSetValueEx(
newValue,
"myprogram",
0,
REG_SZ,
reinterpret_cast<LPCBYTE>(fullpath.c_str()), // returns a "const char*" then cast
fullpath.size() + 1 // + 1 for null terminator
);
根据 RegSetValueExA()
documentation,函数不接受 std::filesystem::path
对象。这就是错误消息所抱怨的内容。
LSTATUS RegSetValueExA(
HKEY hKey,
LPCSTR lpValueName,
DWORD Reserved,
DWORD dwType,
const BYTE *lpData, // <-- here
DWORD cbData
);
第 5 个参数采用 const BYTE*
指向 null-terminated C-style 字符串 的指针。第6个参数取字符串中的字符数,包括空终止符:
lpData
The data to be stored.
For string-based types, such as REG_SZ, the string must be null-terminated. With the REG_MULTI_SZ data type, the string must be terminated with two null characters.
Note lpData indicating a null value is valid, however, if this is the case, cbData must be set to '0'.
cbData
The size of the information pointed to by the lpData parameter, in bytes. If the data is of type REG_SZ, REG_EXPAND_SZ, or REG_MULTI_SZ, cbData must include the size of the terminating null character or characters.
std::filesystem::path
没有 隐式 到 const BYTE*
的转换,因此编译器错误。您需要先 显式 将 path
转换为 std::string
或 std::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;
我想要实现的是使用注册表在 Windows 启动时执行我的程序。当我尝试放置文件位置时,编译器抱怨它无法从 filesystem::path
转换为 const 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;
EXCEPTION: No suitable conversion function from "std:filesystem::path" to "const BYTE *" exists
WinAPI 函数不接受 std::filesystem::path
类型的参数,因此您需要以某种方式将其转换为 const BYTE*
。
这是一个例子:
std::string fullpath = (fs::temp_directory_path() / filename).string();
RegSetValueEx(
newValue,
"myprogram",
0,
REG_SZ,
reinterpret_cast<LPCBYTE>(fullpath.c_str()), // returns a "const char*" then cast
fullpath.size() + 1 // + 1 for null terminator
);
根据 RegSetValueExA()
documentation,函数不接受 std::filesystem::path
对象。这就是错误消息所抱怨的内容。
LSTATUS RegSetValueExA(
HKEY hKey,
LPCSTR lpValueName,
DWORD Reserved,
DWORD dwType,
const BYTE *lpData, // <-- here
DWORD cbData
);
第 5 个参数采用 const BYTE*
指向 null-terminated C-style 字符串 的指针。第6个参数取字符串中的字符数,包括空终止符:
lpData
The data to be stored.
For string-based types, such as REG_SZ, the string must be null-terminated. With the REG_MULTI_SZ data type, the string must be terminated with two null characters.
Note lpData indicating a null value is valid, however, if this is the case, cbData must be set to '0'.
cbData
The size of the information pointed to by the lpData parameter, in bytes. If the data is of type REG_SZ, REG_EXPAND_SZ, or REG_MULTI_SZ, cbData must include the size of the terminating null character or characters.
std::filesystem::path
没有 隐式 到 const BYTE*
的转换,因此编译器错误。您需要先 显式 将 path
转换为 std::string
或 std::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;