Use Unicode of CreateProcess, issue #261

This commit is contained in:
kervala 2016-02-20 18:54:32 +01:00
parent e9f8202701
commit 64af254ece

View file

@ -725,50 +725,54 @@ bool abortProgram(uint32 pid)
#endif #endif
} }
bool launchProgram(const std::string &programName, const std::string &arguments, bool log)
{
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
STARTUPINFOA si;
PROCESS_INFORMATION pi;
static bool createProcess(const std::string &programName, const std::string &arguments, bool log, PROCESS_INFORMATION &pi)
{
STARTUPINFOW si;
memset(&si, 0, sizeof(si)); memset(&si, 0, sizeof(si));
memset(&pi, 0, sizeof(pi)); memset(&pi, 0, sizeof(pi));
si.cb = sizeof(si); si.cb = sizeof(si);
// Enable nlassert/nlstop to display the error reason & callstack // Enable nlassert/nlstop to display the error reason & callstack
const TCHAR *SE_TRANSLATOR_IN_MAIN_MODULE = _T("NEL_SE_TRANS"); const char *SE_TRANSLATOR_IN_MAIN_MODULE = "NEL_SE_TRANS";
TCHAR envBuf [2];
if ( GetEnvironmentVariable( SE_TRANSLATOR_IN_MAIN_MODULE, envBuf, 2 ) != 0) char envBuf[2];
if (GetEnvironmentVariableA(SE_TRANSLATOR_IN_MAIN_MODULE, envBuf, 2) != 0)
{ {
SetEnvironmentVariable( SE_TRANSLATOR_IN_MAIN_MODULE, NULL ); SetEnvironmentVariableA(SE_TRANSLATOR_IN_MAIN_MODULE, NULL);
} }
const char *sProgramName = programName.c_str(); wchar_t *sProgramName = NULL;
std::string args; std::string args;
// a .bat file must have first parameter to NULL and use 2nd parameter to pass filename // a .bat file must have first parameter to NULL and use 2nd parameter to pass filename
if (CFile::getExtension(programName) == "bat") if (CFile::getExtension(programName) == "bat")
{ {
sProgramName = NULL;
args = "\"" + programName + "\" " + arguments; args = "\"" + programName + "\" " + arguments;
} }
else else
{ {
ucstring ucProgramName;
ucProgramName.fromUtf8(programName);
sProgramName = new wchar_t[MAX_PATH];
wcscpy(sProgramName, (wchar_t*)ucProgramName.c_str());
args = arguments; args = arguments;
} }
BOOL res = CreateProcessA(sProgramName, (char*)args.c_str(), NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW, NULL, NULL, &si, &pi); BOOL res = CreateProcessW(sProgramName, utf8ToWide(args), NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
if (res) if (sProgramName)
{ {
//nldebug("LAUNCH: Successful launch '%s' with arg '%s'", programName.c_str(), arguments.c_str()); delete [] sProgramName;
CloseHandle( pi.hProcess ); sProgramName = NULL;
CloseHandle( pi.hThread );
return true;
} }
else
if (!res)
{ {
if (log) if (log)
{ {
@ -778,8 +782,26 @@ bool launchProgram(const std::string &programName, const std::string &arguments,
CloseHandle( pi.hProcess ); CloseHandle( pi.hProcess );
CloseHandle( pi.hThread ); CloseHandle( pi.hThread );
return false;
} }
return true;
}
#endif
bool launchProgram(const std::string &programName, const std::string &arguments, bool log)
{
#ifdef NL_OS_WINDOWS
PROCESS_INFORMATION pi;
if (!createProcess(programName, arguments, log, pi)) return false;
//nldebug("LAUNCH: Successful launch '%s' with arg '%s'", programName.c_str(), arguments.c_str());
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
return true;
#else #else
#ifdef NL_OS_MAC #ifdef NL_OS_MAC
@ -884,76 +906,28 @@ bool launchProgram(const std::string &programName, const std::string &arguments,
sint launchProgramAndWaitForResult(const std::string &programName, const std::string &arguments, bool log) sint launchProgramAndWaitForResult(const std::string &programName, const std::string &arguments, bool log)
{ {
sint res = 0;
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
STARTUPINFOA si;
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(si)); if (!createProcess(programName, arguments, log, pi)) return -1;
memset(&pi, 0, sizeof(pi));
si.cb = sizeof(si);
// Enable nlassert/nlstop to display the error reason & callstack
const TCHAR *SE_TRANSLATOR_IN_MAIN_MODULE = _T("NEL_SE_TRANS");
TCHAR envBuf [2];
if ( GetEnvironmentVariable( SE_TRANSLATOR_IN_MAIN_MODULE, envBuf, 2 ) != 0)
{
SetEnvironmentVariable( SE_TRANSLATOR_IN_MAIN_MODULE, NULL );
}
const char *sProgramName = programName.c_str();
std::string args;
// a .bat file must have first parameter to NULL and use 2nd parameter to pass filename
if (CFile::getExtension(programName) == "bat")
{
sProgramName = NULL;
args = "\"" + programName + "\" " + arguments;
}
else
{
args = arguments;
}
BOOL ok = CreateProcessA(sProgramName, (char*)args.c_str(), NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE | CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
if (ok)
{
// Successfully created the process. Wait for it to finish. // Successfully created the process. Wait for it to finish.
WaitForSingleObject(pi.hProcess, INFINITE); WaitForSingleObject(pi.hProcess, INFINITE);
// Get the exit code. // Get the exit code.
DWORD exitCode = 0; DWORD exitCode = 0;
ok = GetExitCodeProcess(pi.hProcess, &exitCode); BOOL ok = GetExitCodeProcess(pi.hProcess, &exitCode);
//nldebug("LAUNCH: Successful launch '%s' with arg '%s'", programName.c_str(), arguments.c_str()); //nldebug("LAUNCH: Successful launch '%s' with arg '%s'", programName.c_str(), arguments.c_str());
CloseHandle(pi.hProcess); CloseHandle(pi.hProcess);
CloseHandle(pi.hThread); CloseHandle(pi.hThread);
if (ok) if (ok) return (sint)exitCode;
{
res = (sint)exitCode;
}
else
{
if (log) if (log)
nlwarning("LAUNCH: Failed launched '%s' with arg '%s'", programName.c_str(), arguments.c_str()); nlwarning("LAUNCH: Failed launched '%s' with arg '%s'", programName.c_str(), arguments.c_str());
}
}
else
{
if (log)
{
sint lastError = getLastError();
nlwarning("LAUNCH: Failed launched '%s' with arg '%s' err %d: '%s'", programName.c_str(), arguments.c_str(), lastError, formatErrorMessage(lastError).c_str());
}
CloseHandle(pi.hProcess); return -1;
CloseHandle(pi.hThread);
}
#else #else
// program name is the only required string // program name is the only required string
std::string command = programName; std::string command = programName;
@ -962,13 +936,13 @@ sint launchProgramAndWaitForResult(const std::string &programName, const std::st
if (!arguments.empty()) command += " " + arguments; if (!arguments.empty()) command += " " + arguments;
// execute the command // execute the command
res = system(command.c_str()); sint res = system(command.c_str());
if (res && log) if (res && log)
nlwarning ("LAUNCH: Failed launched '%s' with arg '%s' return code %d", programName.c_str(), arguments.c_str(), res); nlwarning ("LAUNCH: Failed launched '%s' with arg '%s' return code %d", programName.c_str(), arguments.c_str(), res);
#endif
return res; return res;
#endif
} }
std::string getCommandOutput(const std::string &command) std::string getCommandOutput(const std::string &command)