diff --git a/src/plugins/projectexplorer/winguiprocess.cpp b/src/plugins/projectexplorer/winguiprocess.cpp index 961a352dbe6eb066ffdcdfa7a9f71fb0a9abb020..71ea57a749f8ef3cb3873034260f7e224492fe9b 100644 --- a/src/plugins/projectexplorer/winguiprocess.cpp +++ b/src/plugins/projectexplorer/winguiprocess.cpp @@ -101,72 +101,81 @@ void WinGuiProcess::run() ZeroMemory(m_pid, sizeof(PROCESS_INFORMATION)); m_exitCode = 0; + bool started = false; HANDLE bufferReadyEvent = NULL; HANDLE dataReadyEvent = NULL; HANDLE sharedFile = NULL; - LPVOID sharedMem = NULL; - - bool dbgInterface = setupDebugInterface(bufferReadyEvent, dataReadyEvent, sharedFile, sharedMem); - - QString cmdLine = createWinCommandline(m_program, m_args); - bool success = CreateProcessW(0, (WCHAR*)cmdLine.utf16(), - 0, 0, TRUE, CREATE_UNICODE_ENVIRONMENT, - environment().isEmpty() ? 0 - : createWinEnvironment(fixWinEnvironment(environment())).data(), - workingDirectory().isEmpty() ? 0 - : (WCHAR*)QDir::convertSeparators(workingDirectory()).utf16(), - &si, m_pid); - - if (!success) { - emit processError(tr("The process could not be started!")); - delete m_pid; - m_pid = 0; - return; - } + LPVOID sharedMem = 0; - if (!dbgInterface) { - emit receivedDebugOutput(tr("Cannot retrieve debugging output!")); - WaitForSingleObject(m_pid->hProcess, INFINITE); - } else { - LPSTR message; - LPDWORD processId; - HANDLE toWaitFor[2]; - - message = reinterpret_cast<LPSTR>(sharedMem) + sizeof(DWORD); - processId = reinterpret_cast<LPDWORD>(sharedMem); - - SetEvent(bufferReadyEvent); - - toWaitFor[0] = dataReadyEvent; - toWaitFor[1] = m_pid->hProcess; - - for (bool stop = false; !stop;) { - DWORD ret = WaitForMultipleObjects(2, toWaitFor, FALSE, INFINITE); - - switch (ret) { - case WAIT_OBJECT_0 + 0: - if (*processId == m_pid->dwProcessId) - emit receivedDebugOutput(QString::fromLocal8Bit(message)); - SetEvent(bufferReadyEvent); - break; - case WAIT_OBJECT_0 + 1: - stop = true; - break; - } + do { + + const bool dbgInterface = setupDebugInterface(bufferReadyEvent, dataReadyEvent, sharedFile, sharedMem); + + const QString cmdLine = createWinCommandline(m_program, m_args); + started = CreateProcessW(0, (WCHAR*)cmdLine.utf16(), + 0, 0, TRUE, CREATE_UNICODE_ENVIRONMENT, + environment().isEmpty() ? 0 + : createWinEnvironment(fixWinEnvironment(environment())).data(), + workingDirectory().isEmpty() ? 0 + : (WCHAR*)QDir::convertSeparators(workingDirectory()).utf16(), + &si, m_pid); + + if (!started) { + emit processError(tr("The process could not be started!")); + break; } - } - GetExitCodeProcess(m_pid->hProcess, &m_exitCode); - emit processFinished(static_cast<int>(m_exitCode)); + if (!dbgInterface) { + emit receivedDebugOutput(tr("Cannot retrieve debugging output!")); + WaitForSingleObject(m_pid->hProcess, INFINITE); + } else { + LPSTR message; + LPDWORD processId; + HANDLE toWaitFor[2]; + + message = reinterpret_cast<LPSTR>(sharedMem) + sizeof(DWORD); + processId = reinterpret_cast<LPDWORD>(sharedMem); + + SetEvent(bufferReadyEvent); + + toWaitFor[0] = dataReadyEvent; + toWaitFor[1] = m_pid->hProcess; + + for (bool stop = false; !stop;) { + DWORD ret = WaitForMultipleObjects(2, toWaitFor, FALSE, INFINITE); + + switch (ret) { + case WAIT_OBJECT_0 + 0: + if (*processId == m_pid->dwProcessId) + emit receivedDebugOutput(QString::fromLocal8Bit(message)); + SetEvent(bufferReadyEvent); + break; + case WAIT_OBJECT_0 + 1: + stop = true; + break; + } + } + } + } while (false); - UnmapViewOfFile(sharedMem); - CloseHandle(sharedFile); - CloseHandle(bufferReadyEvent); - CloseHandle(dataReadyEvent); - CloseHandle(m_pid->hProcess); - CloseHandle(m_pid->hThread); + if (started) { + GetExitCodeProcess(m_pid->hProcess, &m_exitCode); + emit processFinished(static_cast<int>(m_exitCode)); + } + if (sharedMem) + UnmapViewOfFile(sharedMem); + if (sharedFile != NULL) + CloseHandle(sharedFile); + if (bufferReadyEvent != NULL) + CloseHandle(bufferReadyEvent); + if (dataReadyEvent != NULL) + CloseHandle(dataReadyEvent); + if (m_pid->hProcess != NULL) + CloseHandle(m_pid->hProcess); + if (m_pid->hThread != NULL) + CloseHandle(m_pid->hThread); delete m_pid; m_pid = 0; } diff --git a/src/plugins/projectexplorer/winguiprocess.h b/src/plugins/projectexplorer/winguiprocess.h index 460651ff12caecd77a63df25eee23765ec1e44a5..c3ffee1e7724132a447b08363fb2d5291409ba08 100644 --- a/src/plugins/projectexplorer/winguiprocess.h +++ b/src/plugins/projectexplorer/winguiprocess.h @@ -42,6 +42,9 @@ using namespace Utils; namespace ProjectExplorer { namespace Internal { +/* Captures the debug output of a Windows GUI application (which + * would otherwise not be visible) using the debug interface and + * emits via a signal. */ class WinGuiProcess : public QThread, public AbstractProcess { Q_OBJECT