diff options
author | Joerg Bornemann <joerg.bornemann@nokia.com> | 2012-01-05 18:24:53 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-01-08 18:22:46 +0100 |
commit | 2588a5b24965d9afa0d6e368a9f42491d1cfb5f7 (patch) | |
tree | 5718ad2dec880e6e6834b810877600fcda55b750 | |
parent | ece75a8adfc30c91f25d45d37f98bf8cda90fdce (diff) |
QProcess/Win: direct forwarding of stdout and stderr
We are now directly passing the standard out/err handles to
CreateProcess instead of reading the output and writing it.
The downside is, that we cannot automatically forward the process
output of GUI applications anymore.
This behaviour is intended by the CreateProcess API.
Change-Id: Ic6e35c8c338dbea1a9f345567a37d938da1f34a2
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
Reviewed-by: Joerg Bornemann <joerg.bornemann@nokia.com>
-rw-r--r-- | dist/changes-5.0.0 | 4 | ||||
-rw-r--r-- | src/corelib/io/qprocess.cpp | 8 | ||||
-rw-r--r-- | src/corelib/io/qprocess_win.cpp | 40 |
3 files changed, 26 insertions, 26 deletions
diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index 8855aa3852..1d6a7d6c84 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -144,6 +144,10 @@ information about a particular change. - The QHttp, QHttpHeader, QHttpResponseHeader and QHttpRequestHeader classes have been removed, QNetworkAccessManager should be used instead. +- QProcess + + * On Windows, QProcess::ForwardedChannels will not forward the output of GUI + applications anymore, if they do not create a console. **************************************************************************** * General * diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 6f57f9f0e8..9f6fa4933e 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -617,6 +617,14 @@ void QProcessPrivate::Channel::clear() writes to its standard output and standard error will be written to the standard output and standard error of the main process. + \note Windows intentionally suppresses output from GUI-only + applications to inherited consoles. + This does \e not apply to output redirected to files or pipes. + To forward the output of GUI-only applications on the console + nonetheless, you must use SeparateChannels and do the forwarding + yourself by reading the output and writing it to the appropriate + output channels. + \sa setProcessChannelMode() */ diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index fd5f078ff0..8c6444d173 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -92,6 +92,15 @@ static void qt_create_pipe(Q_PIPE *pipe, bool in) CloseHandle(tmpHandle); } +static void duplicateStdWriteChannel(Q_PIPE *pipe, DWORD nStdHandle) +{ + pipe[0] = INVALID_Q_PIPE; + HANDLE hStdWriteChannel = GetStdHandle(nStdHandle); + HANDLE hCurrentProcess = GetCurrentProcess(); + DuplicateHandle(hCurrentProcess, hStdWriteChannel, hCurrentProcess, + &pipe[1], 0, TRUE, DUPLICATE_SAME_ACCESS); +} + /* Create the pipes to a QProcessPrivate::Channel. @@ -108,8 +117,11 @@ bool QProcessPrivate::createChannel(Channel &channel) if (channel.type == Channel::Normal) { // we're piping this channel to our own process - qt_create_pipe(channel.pipe, &channel == &stdinChannel); - + const bool isStdInChannel = (&channel == &stdinChannel); + if (isStdInChannel || processChannelMode != QProcess::ForwardedChannels) + qt_create_pipe(channel.pipe, isStdInChannel); + else + duplicateStdWriteChannel(channel.pipe, (&channel == &stdoutChannel) ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE); return true; } else if (channel.type == Channel::Redirect) { // we're redirecting the channel to/from a file @@ -465,18 +477,6 @@ qint64 QProcessPrivate::bytesAvailableFromStdout() const #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::bytesAvailableFromStdout() == %d", bytesAvail); #endif - if (processChannelMode == QProcess::ForwardedChannels && bytesAvail > 0) { - QByteArray buf(bytesAvail, 0); - DWORD bytesRead = 0; - if (ReadFile(stdoutChannel.pipe[0], buf.data(), buf.size(), &bytesRead, 0) && bytesRead > 0) { - HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); - if (hStdout) { - DWORD bytesWritten = 0; - WriteFile(hStdout, buf.data(), bytesRead, &bytesWritten, 0); - } - } - bytesAvail = 0; - } return bytesAvail; } @@ -490,18 +490,6 @@ qint64 QProcessPrivate::bytesAvailableFromStderr() const #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::bytesAvailableFromStderr() == %d", bytesAvail); #endif - if (processChannelMode == QProcess::ForwardedChannels && bytesAvail > 0) { - QByteArray buf(bytesAvail, 0); - DWORD bytesRead = 0; - if (ReadFile(stderrChannel.pipe[0], buf.data(), buf.size(), &bytesRead, 0) && bytesRead > 0) { - HANDLE hStderr = GetStdHandle(STD_ERROR_HANDLE); - if (hStderr) { - DWORD bytesWritten = 0; - WriteFile(hStderr, buf.data(), bytesRead, &bytesWritten, 0); - } - } - bytesAvail = 0; - } return bytesAvail; } |