[英]How to convert std::wstring to LPCTSTR in C++?
我有wstring
格式的Windows注冊表項值。 現在我想將它傳遞給這個代碼(第一個參數 - javaw.exe的路徑):
std::wstring somePath(L"....\\bin\\javaw.exe");
if (!CreateProcess("C:\\Program Files\\Java\\jre7\\bin\\javaw.exe", <--- here should be LPCTSTR, but I have a somePath in wstring format..
cmdline, // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
0, // Set handle inheritance to FALSE.
CREATE_NO_WINDOW, // ON VISTA/WIN7, THIS CREATES NO WINDOW
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi)) // Pointer to PROCESS_INFORMATION structure.
{
printf("CreateProcess failed\n");
return 0;
}
我怎樣才能做到這一點?
只需使用std::w/string
的c_str
函數。
看這里:
http://www.cplusplus.com/reference/string/string/c_str/
std::wstring somePath(L"....\\bin\\javaw.exe");
if (!CreateProcess(somePath.c_str(),
cmdline, // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
0, // Set handle inheritance to FALSE.
CREATE_NO_WINDOW, // ON VISTA/WIN7, THIS CREATES NO WINDOW
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi)) // Pointer to PROCESS_INFORMATION structure.
{
printf("CreateProcess failed\n");
return 0;
}
LPCTSTR
是一個古老的遺物。 它是一個混合typedef,如果你使用多字節字符串,則定義char*
如果使用Unicode,則定義wchar_t*
。 在Visual Studio中,可以在“字符集”下的常規項目設置中更改此設置。
如果您使用的是Unicode,那么:
std::wstring somePath(L"....\\bin\\javaw.exe");
LPCTSTR str = somePath.c_str(); // i.e. std::wstring to wchar_t*
如果您使用多字節,請使用此幫助程序:
// wide char to multi byte:
std::string ws2s(const std::wstring& wstr)
{
int size_needed = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), int(wstr.length() + 1), 0, 0, 0, 0);
std::string strTo(size_needed, 0);
WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), int(wstr.length() + 1), &strTo[0], size_needed, 0, 0);
return strTo;
}
即std::wstring
到std::string
,它將包含多字節字符串,然后是char*
:
LPCTSTR str = ws2s(somePath).c_str();
最后決定使用CreateProcessW作為paulm提到一點修改 - 值需要進行轉換(否則我得到錯誤):
STARTUPINFOW si;
memset(&si, 0, sizeof (STARTUPINFOW));
si.cb = sizeof (STARTUPINFOW);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = FALSE;
PROCESS_INFORMATION pi;
memset(&pi, 0, sizeof (PROCESS_INFORMATION));
std::wstring cmdline(L" -jar install.jar");
if (!CreateProcessW((LPCWSTR)strKeyValue.c_str(),
(LPWSTR)cmdline.c_str(), // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
0, // Set handle inheritance to FALSE.
CREATE_NO_WINDOW, // ON VISTA/WIN7, THIS CREATES NO WINDOW
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi)) // Pointer to PROCESS_INFORMATION structure.
{
printf("CreateProcess failed\n");
return 0;
}
從stdlib類與TCHAR
交互時最安全的方法是使用std::basic_string<TCHAR>
並使用TEXT()
宏包圍原始字符串(因為TCHAR
可以根據項目設置來縮小和寬)。
std::basic_string<TCHAR> somePath(TEXT("....\\bin\\javaw.exe"));
因為你不會贏得這樣做的風格競賽......另一種正確的方法是明確使用WinAPI函數的窄版或寬版。 例如,在那種特殊情況下:
std::string
使用CreateProcessA
(使用LPCSTR
,它是char*
的typedef) std::u16string
或std::wstring
使用CreateProcessW
(使用LPCWSTR
,它是wchar_t*
的typedef,在Windows中為16位) 在C ++ 17中,你可以這樣做:
std::filesystem::path app = "my/path/myprogram.exe";
std::string commandcall = app.filename.string() + " -myAwesomeParams";
// define si, pi
CreateProcessA(
const_cast<LPCSTR>(app.string().c_str()),
const_cast<LPSTR>(commandcall.c_str()),
nullptr, nullptr, false, CREATE_DEFAULT_ERROR_MODE, nullptr, nullptr,
&si, &pi)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.