Как преобразовать std:: wstring в LPCTSTR на C++?
у меня есть значение раздела реестра Windows в . Теперь я хочу передать его в этот код (первый аргумент-путь к javaw.EXE-файл):
std::wstring somePath(L"....binjavaw.exe");
if (!CreateProcess("C:Program FilesJavajre7binjavaw.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 failedn");
return 0;
}
Как я могу это сделать?
4 ответов
просто использовать c_str
функции std::w/string
.
смотрите здесь:
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*
если вы используете многобайтовые строки или wchar_t*
если вы используете Unicode. В 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
to std::string
который будет содержать многобайтовую строку, а затем char*
:
LPCTSTR str = ws2s(somePath).c_str();
наконец решил использовать CreateProcessW, как упоминал паульм с небольшими исправлениями-значения должны быть отлиты (иначе я получаю ошибку):
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
s использовать std::basic_string<TCHAR>
и окружить необработанные строки с TEXT()
макро (с TCHAR
может быть узким и широким, в зависимости от настроек проекта).
std::basic_string<TCHAR> somePath(TEXT("....\bin\javaw.exe"));
так как вы не выиграете конкурсы стиля, делая это ... другой правильный метод-явно использовать узкую или широкую версию функции WinAPI. Е. Г. в этом конкретном случае:
- С
std::string
использоватьCreateProcessA
(который используетLPCSTR
который является typedefchar*
) - С
std::u16string
илиstd::wstring
использоватьCreateProcessW
(который используетLPCWSTR
который является typedefwchar_t*
, который является 16-битным в Windows)
в 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)