in src/main/cpp/launcher/windows/src/ProcessUtils.c [111:217]
void executeCommand(LauncherProperties * props, WCHAR * command, WCHAR * dir, DWORD timeLimitMillis, HANDLE hWriteOutput, HANDLE hWriteError, DWORD priority) {
STARTUPINFOW si;
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
PROCESS_INFORMATION pi;
HANDLE newProcessInput;
HANDLE newProcessOutput;
HANDLE newProcessError;
HANDLE currentProcessStdout;
HANDLE currentProcessStdin;
HANDLE currentProcessStderr;
WCHAR * directory;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
sa.lpSecurityDescriptor = &sd;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
if (!CreatePipe(&newProcessInput, ¤tProcessStdin, &sa, 0)) {
writeErrorA(props, OUTPUT_LEVEL_NORMAL, 1, "Can`t create pipe for input. ", NULL , GetLastError());
props->status = ERROR_ON_EXECUTE_PROCESS;
return;
}
if (!CreatePipe(¤tProcessStdout, &newProcessOutput, &sa, 0)) {
writeErrorA(props, OUTPUT_LEVEL_NORMAL, 1, "Can`t create pipe for output. ", NULL , GetLastError());
CloseHandle(newProcessInput);
CloseHandle(currentProcessStdin);
props->status = ERROR_ON_EXECUTE_PROCESS;
return;
}
if (!CreatePipe(¤tProcessStderr, &newProcessError, &sa, 0)) {
writeErrorA(props, OUTPUT_LEVEL_NORMAL, 1, "Can`t create pipe for error. ", NULL , GetLastError());
CloseHandle(newProcessInput);
CloseHandle(currentProcessStdin);
CloseHandle(newProcessOutput);
CloseHandle(currentProcessStdout);
props->status = ERROR_ON_EXECUTE_PROCESS;
return;
}
GetStartupInfoW(&si);
si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
si.hStdOutput = newProcessOutput;
si.hStdError = newProcessError;
si.hStdInput = newProcessInput;
directory = (dir!=NULL) ? dir : getCurrentDirectory();
writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Create new process: ", 1);
writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " command : ", 0);
writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, command, 1);
writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " directory : ", 0);
writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, directory, 1);
props->exitCode = ERROR_OK;
if (CreateProcessW(NULL, command, NULL, NULL, TRUE,
CREATE_NEW_CONSOLE | CREATE_NO_WINDOW | CREATE_DEFAULT_ERROR_MODE | priority,
NULL, directory, &si, &pi)) {
// TODO
// Check whether volder virtualization can brake things and provide method to disable it if necessary
// I am not sure whether we need it off or on.
// http://www.netbeans.org/issues/show_bug.cgi?id=122186
DWORD timeOut = ((timeLimitMillis<=0) ? DEFAULT_PROCESS_TIMEOUT: timeLimitMillis);
props->status = ERROR_OK;
writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... process created", 1);
props->exitCode = readProcessStream(pi, currentProcessStdin, currentProcessStdout, currentProcessStderr, timeOut, newProcessInput, hWriteOutput, hWriteError);
if(props->exitCode==STILL_ACTIVE) {
//actually we have reached the timeout of the process and need to terminate it
writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... process is timeouted", 1);
GetExitCodeProcess(pi.hProcess, & (props->exitCode));
if(props->exitCode==STILL_ACTIVE) {
TerminateProcess(pi.hProcess, 0);
writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... terminate process", 1);
//Terminating process...It worked too much without any stdout/stdin/stderr
props->status = ERROR_PROCESS_TIMEOUT;//terminated by timeout
}
} else {
//application finished its work... succesfully or not - it doesn`t matter
writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... process finished his work", 1);
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
} else {
writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "... can`t create process.", NULL, GetLastError());
props->status = ERROR_ON_EXECUTE_PROCESS;
}
CloseHandle(newProcessInput);
CloseHandle(newProcessOutput);
CloseHandle(newProcessError);
CloseHandle(currentProcessStdin);
CloseHandle(currentProcessStdout);
CloseHandle(currentProcessStderr);
}