Reputation: 8787
I have Windows registry key value in wstring
format. Now I want to pass it to this code (first argument - path to 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;
}
How can I do that?
Upvotes: 22
Views: 55221
Reputation: 8758
The safest way when interacting from stdlib classes with TCHAR
s is to use std::basic_string<TCHAR>
and surround raw strings with the TEXT()
macro (since TCHAR
can be narrow and wide depending on project settings).
std::basic_string<TCHAR> somePath(TEXT("....\\bin\\javaw.exe"));
Since you won't win style contests doing this ... another correct method is to use explicitly the narrow or wide version of a WinAPI function. E.g. in that particular case:
std::string
use CreateProcessA
(which uses LPCSTR
which is a typedef of char*
)std::u16string
or std::wstring
use CreateProcessW
(which uses LPCWSTR
which is a typedef of wchar_t*
, which is 16-bit in Windows)In C++17, you could do:
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)
Upvotes: 1
Reputation: 8787
Finally decided to use CreateProcessW as paulm mentioned with a little corrections - values need to be casted (otherwise I get error):
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;
}
Upvotes: 0
Reputation: 5892
Simply use the c_str
function of std::w/string
.
See here:
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;
}
Upvotes: 33
Reputation: 42133
LPCTSTR
is an old relic. It's a hybrid typedef that either defines char*
if you are using multi-byte strings or wchar_t*
if you are using Unicode. In Visual Studio, this can be changed in general project's settings under "Character Set".
If you are using Unicode, then:
std::wstring somePath(L"....\\bin\\javaw.exe");
LPCTSTR str = somePath.c_str(); // i.e. std::wstring to wchar_t*
If you are using multi-byte, then use this helper:
// 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;
}
i.e. std::wstring
to std::string
that will contain multi-byte string and then to char*
:
LPCTSTR str = ws2s(somePath).c_str();
Upvotes: 12