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;
}
どうやってやるの?
単に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
は古い遺物です。マルチバイト文字列を使用している場合はchar*
、Unicodeを使用している場合はwchar_t*
を定義するハイブリッドtypedefです。 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();
Paulmが言及したように、少し修正して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
を使用(_char*
_のtypedefであるLPCSTR
を使用)std::u16string
_または_std::wstring
_でCreateProcessW
を使用します(Windowsでは16ビットである_wchar_t*
_のtypedefであるLPCWSTR
を使用します)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)
_