¿Cómo convertir std:: wstring a LPCTSTR en C++?
type-conversion (4)
Tengo el valor de clave de registro de Windows en formato wstring
. Ahora quiero pasarlo a este código (primer argumento - ruta a 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ómo puedo hacer eso?
Finalmente, decidí usar CreateProcessW como paulm mencionado con algunas correcciones. Los valores deben ser emitidos (de lo contrario me sale un 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;
}
La forma más segura al interactuar desde clases stdlib con TCHAR
s es usar std::basic_string<TCHAR>
y rodear cadenas sin std::basic_string<TCHAR>
con la macro TEXT()
(ya que TCHAR
puede ser estrecha y amplia dependiendo de la configuración del proyecto).
std::basic_string<TCHAR> somePath(TEXT("....//bin//javaw.exe"));
Ya que no ganarás concursos de estilo haciendo esto ... otro método correcto es usar explícitamente la versión angosta o amplia de una función WinAPI. Por ejemplo, en ese caso particular:
- con
std::string
useCreateProcessA
(que usaLPCSTR
que es un typedef dechar*
) - con
std::u16string
ostd::wstring
useCreateProcessW
(que usaLPCWSTR
que es un typedef dewchar_t*
, que es de 16 bits en Windows)
En C ++ 17, podrías hacer:
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)
Simplemente use la función c_str
de std::w/string
.
Mira aquí:
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
es una antigua reliquia. Es un typedef híbrido que define char*
si está usando cadenas de múltiples bytes o wchar_t*
si está usando Unicode. En Visual Studio, esto se puede cambiar en la configuración general del proyecto en "Conjunto de caracteres".
Si está utilizando Unicode, entonces:
std::wstring somePath(L"....//bin//javaw.exe");
LPCTSTR str = somePath.c_str(); // i.e. std::wstring to wchar_t*
Si está utilizando un byte múltiple, use este ayudante:
// 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;
}
es decir, std::wstring
to std::string
que contendrá una cadena de múltiples bytes y luego a char*
:
LPCTSTR str = ws2s(somePath).c_str();