split qprocess_win.cpp into Windows and WinCE parts
Change-Id: I7f2cf2c42dd24ca162238e6dc6408ac39dfcd790 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>bb10
parent
156d160c56
commit
d0bb97c327
|
|
@ -72,7 +72,6 @@ SOURCES += \
|
|||
|
||||
win32 {
|
||||
SOURCES += io/qsettings_win.cpp
|
||||
SOURCES += io/qprocess_win.cpp
|
||||
SOURCES += io/qfsfileengine_win.cpp
|
||||
|
||||
SOURCES += io/qfilesystemwatcher_win.cpp
|
||||
|
|
@ -84,6 +83,12 @@ win32 {
|
|||
SOURCES += io/qfilesystemengine_win.cpp
|
||||
SOURCES += io/qfilesystemiterator_win.cpp
|
||||
SOURCES += io/qstandardpaths_win.cpp
|
||||
|
||||
wince* {
|
||||
SOURCES += io/qprocess_wince.cpp
|
||||
} else {
|
||||
SOURCES += io/qprocess_win.cpp
|
||||
}
|
||||
} else:unix|integrity {
|
||||
SOURCES += \
|
||||
io/qfsfileengine_unix.cpp \
|
||||
|
|
|
|||
|
|
@ -72,7 +72,6 @@ static void qt_create_pipe(Q_PIPE *pipe, bool in)
|
|||
// read handles to avoid non-closable handles (this is done by the
|
||||
// DuplicateHandle() call).
|
||||
|
||||
#if !defined(Q_OS_WINCE)
|
||||
SECURITY_ATTRIBUTES secAtt = { sizeof( SECURITY_ATTRIBUTES ), NULL, TRUE };
|
||||
|
||||
HANDLE tmpHandle;
|
||||
|
|
@ -91,10 +90,6 @@ static void qt_create_pipe(Q_PIPE *pipe, bool in)
|
|||
}
|
||||
|
||||
CloseHandle(tmpHandle);
|
||||
#else
|
||||
Q_UNUSED(pipe);
|
||||
Q_UNUSED(in);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -277,7 +272,6 @@ static QString qt_create_commandline(const QString &program, const QStringList &
|
|||
QProcessEnvironment QProcessEnvironment::systemEnvironment()
|
||||
{
|
||||
QProcessEnvironment env;
|
||||
#if !defined(Q_OS_WINCE)
|
||||
// Calls to setenv() affect the low-level environment as well.
|
||||
// This is not the case the other way round.
|
||||
if (wchar_t *envStrings = GetEnvironmentStringsW()) {
|
||||
|
|
@ -293,11 +287,9 @@ QProcessEnvironment QProcessEnvironment::systemEnvironment()
|
|||
}
|
||||
FreeEnvironmentStringsW(envStrings);
|
||||
}
|
||||
#endif
|
||||
return env;
|
||||
}
|
||||
|
||||
#if !defined(Q_OS_WINCE)
|
||||
static QByteArray qt_create_environment(const QProcessEnvironmentPrivate::Hash &environment)
|
||||
{
|
||||
QByteArray envlist;
|
||||
|
|
@ -357,7 +349,6 @@ static QByteArray qt_create_environment(const QProcessEnvironmentPrivate::Hash &
|
|||
}
|
||||
return envlist;
|
||||
}
|
||||
#endif
|
||||
|
||||
void QProcessPrivate::startProcess()
|
||||
{
|
||||
|
|
@ -381,14 +372,10 @@ void QProcessPrivate::startProcess()
|
|||
!createChannel(stderrChannel))
|
||||
return;
|
||||
|
||||
#if defined(Q_OS_WINCE)
|
||||
QString args = qt_create_commandline(QString(), arguments);
|
||||
#else
|
||||
QString args = qt_create_commandline(program, arguments);
|
||||
QByteArray envlist;
|
||||
if (environment.d.constData())
|
||||
envlist = qt_create_environment(environment.d.constData()->hash);
|
||||
#endif
|
||||
if (!nativeArguments.isEmpty()) {
|
||||
if (!args.isEmpty())
|
||||
args += QLatin1Char(' ');
|
||||
|
|
@ -402,15 +389,6 @@ void QProcessPrivate::startProcess()
|
|||
qDebug(" pass environment : %s", environment.isEmpty() ? "no" : "yes");
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WINCE)
|
||||
QString fullPathProgram = program;
|
||||
if (!QDir::isAbsolutePath(fullPathProgram))
|
||||
fullPathProgram = QFileInfo(fullPathProgram).absoluteFilePath();
|
||||
fullPathProgram.replace(QLatin1Char('/'), QLatin1Char('\\'));
|
||||
success = CreateProcess((wchar_t*)fullPathProgram.utf16(),
|
||||
(wchar_t*)args.utf16(),
|
||||
0, 0, false, 0, 0, 0, 0, pid);
|
||||
#else
|
||||
DWORD dwCreationFlags = CREATE_NO_WINDOW;
|
||||
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
|
||||
STARTUPINFOW startupInfo = { sizeof( STARTUPINFO ), 0, 0, 0,
|
||||
|
|
@ -443,7 +421,6 @@ void QProcessPrivate::startProcess()
|
|||
CloseHandle(stderrChannel.pipe[1]);
|
||||
stderrChannel.pipe[1] = INVALID_Q_PIPE;
|
||||
}
|
||||
#endif // Q_OS_WINCE
|
||||
|
||||
if (!success) {
|
||||
cleanup();
|
||||
|
|
@ -484,7 +461,6 @@ qint64 QProcessPrivate::bytesAvailableFromStdout() const
|
|||
return 0;
|
||||
|
||||
DWORD bytesAvail = 0;
|
||||
#if !defined(Q_OS_WINCE)
|
||||
PeekNamedPipe(stdoutChannel.pipe[0], 0, 0, 0, &bytesAvail, 0);
|
||||
#if defined QPROCESS_DEBUG
|
||||
qDebug("QProcessPrivate::bytesAvailableFromStdout() == %d", bytesAvail);
|
||||
|
|
@ -501,7 +477,6 @@ qint64 QProcessPrivate::bytesAvailableFromStdout() const
|
|||
}
|
||||
bytesAvail = 0;
|
||||
}
|
||||
#endif
|
||||
return bytesAvail;
|
||||
}
|
||||
|
||||
|
|
@ -511,7 +486,6 @@ qint64 QProcessPrivate::bytesAvailableFromStderr() const
|
|||
return 0;
|
||||
|
||||
DWORD bytesAvail = 0;
|
||||
#if !defined(Q_OS_WINCE)
|
||||
PeekNamedPipe(stderrChannel.pipe[0], 0, 0, 0, &bytesAvail, 0);
|
||||
#if defined QPROCESS_DEBUG
|
||||
qDebug("QProcessPrivate::bytesAvailableFromStderr() == %d", bytesAvail);
|
||||
|
|
@ -528,7 +502,6 @@ qint64 QProcessPrivate::bytesAvailableFromStderr() const
|
|||
}
|
||||
bytesAvail = 0;
|
||||
}
|
||||
#endif
|
||||
return bytesAvail;
|
||||
}
|
||||
|
||||
|
|
@ -596,13 +569,6 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
|
|||
{
|
||||
Q_Q(QProcess);
|
||||
|
||||
#if defined(Q_OS_WINCE)
|
||||
processError = QProcess::ReadError;
|
||||
q->setErrorString(QProcess::tr("Error reading from process"));
|
||||
emit q->error(processError);
|
||||
return false;
|
||||
#endif
|
||||
|
||||
QIncrementalSleepTimer timer(msecs);
|
||||
|
||||
forever {
|
||||
|
|
@ -646,13 +612,6 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
|
|||
{
|
||||
Q_Q(QProcess);
|
||||
|
||||
#if defined(Q_OS_WINCE)
|
||||
processError = QProcess::ReadError;
|
||||
q->setErrorString(QProcess::tr("Error reading from process"));
|
||||
emit q->error(processError);
|
||||
return false;
|
||||
#endif
|
||||
|
||||
QIncrementalSleepTimer timer(msecs);
|
||||
|
||||
forever {
|
||||
|
|
@ -786,13 +745,6 @@ qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen)
|
|||
{
|
||||
Q_Q(QProcess);
|
||||
|
||||
#if defined(Q_OS_WINCE)
|
||||
processError = QProcess::WriteError;
|
||||
q->setErrorString(QProcess::tr("Error writing to process"));
|
||||
emit q->error(processError);
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
if (!pipeWriter) {
|
||||
pipeWriter = new QWindowsPipeWriter(stdinChannel.pipe[1], q);
|
||||
pipeWriter->start();
|
||||
|
|
@ -832,36 +784,19 @@ void QProcessPrivate::_q_notified()
|
|||
|
||||
bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDir, qint64 *pid)
|
||||
{
|
||||
#if defined(Q_OS_WINCE)
|
||||
Q_UNUSED(workingDir);
|
||||
QString args = qt_create_commandline(QString(), arguments);
|
||||
#else
|
||||
QString args = qt_create_commandline(program, arguments);
|
||||
#endif
|
||||
|
||||
bool success = false;
|
||||
|
||||
PROCESS_INFORMATION pinfo;
|
||||
|
||||
#if defined(Q_OS_WINCE)
|
||||
QString fullPathProgram = program;
|
||||
if (!QDir::isAbsolutePath(fullPathProgram))
|
||||
fullPathProgram.prepend(QDir::currentPath().append(QLatin1Char('/')));
|
||||
fullPathProgram.replace(QLatin1Char('/'), QLatin1Char('\\'));
|
||||
success = CreateProcess((wchar_t*)fullPathProgram.utf16(),
|
||||
(wchar_t*)args.utf16(),
|
||||
0, 0, false, CREATE_NEW_CONSOLE, 0, 0, 0, &pinfo);
|
||||
#else
|
||||
STARTUPINFOW startupInfo = { sizeof( STARTUPINFO ), 0, 0, 0,
|
||||
(ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
|
||||
(ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
success = CreateProcess(0, (wchar_t*)args.utf16(),
|
||||
0, 0, FALSE, CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE, 0,
|
||||
workingDir.isEmpty() ? 0 : (wchar_t*)workingDir.utf16(),
|
||||
&startupInfo, &pinfo);
|
||||
#endif // Q_OS_WINCE
|
||||
STARTUPINFOW startupInfo = { sizeof( STARTUPINFO ), 0, 0, 0,
|
||||
(ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
|
||||
(ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
success = CreateProcess(0, (wchar_t*)args.utf16(),
|
||||
0, 0, FALSE, CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE, 0,
|
||||
workingDir.isEmpty() ? 0 : (wchar_t*)workingDir.utf16(),
|
||||
&startupInfo, &pinfo);
|
||||
|
||||
if (success) {
|
||||
CloseHandle(pinfo.hThread);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,330 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qprocess.h"
|
||||
#include "qprocess_p.h"
|
||||
|
||||
#include <qdir.h>
|
||||
#include <qfileinfo.h>
|
||||
#include <qregexp.h>
|
||||
#include <qtimer.h>
|
||||
#include <qwineventnotifier.h>
|
||||
#include <qdebug.h>
|
||||
|
||||
#ifndef QT_NO_PROCESS
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
//#define QPROCESS_DEBUG
|
||||
|
||||
void QProcessPrivate::destroyPipe(Q_PIPE pipe[2])
|
||||
{
|
||||
Q_UNUSED(pipe);
|
||||
}
|
||||
|
||||
static QString qt_create_commandline(const QString &program, const QStringList &arguments)
|
||||
{
|
||||
QString args;
|
||||
if (!program.isEmpty()) {
|
||||
QString programName = program;
|
||||
if (!programName.startsWith(QLatin1Char('\"')) && !programName.endsWith(QLatin1Char('\"')) && programName.contains(QLatin1Char(' ')))
|
||||
programName = QLatin1Char('\"') + programName + QLatin1Char('\"');
|
||||
programName.replace(QLatin1Char('/'), QLatin1Char('\\'));
|
||||
|
||||
// add the prgram as the first arg ... it works better
|
||||
args = programName + QLatin1Char(' ');
|
||||
}
|
||||
|
||||
for (int i=0; i<arguments.size(); ++i) {
|
||||
QString tmp = arguments.at(i);
|
||||
// Quotes are escaped and their preceding backslashes are doubled.
|
||||
tmp.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\\1\\1\\\""));
|
||||
if (tmp.isEmpty() || tmp.contains(QLatin1Char(' ')) || tmp.contains(QLatin1Char('\t'))) {
|
||||
// The argument must not end with a \ since this would be interpreted
|
||||
// as escaping the quote -- rather put the \ behind the quote: e.g.
|
||||
// rather use "foo"\ than "foo\"
|
||||
int i = tmp.length();
|
||||
while (i > 0 && tmp.at(i - 1) == QLatin1Char('\\'))
|
||||
--i;
|
||||
tmp.insert(i, QLatin1Char('"'));
|
||||
tmp.prepend(QLatin1Char('"'));
|
||||
}
|
||||
args += QLatin1Char(' ') + tmp;
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
QProcessEnvironment QProcessEnvironment::systemEnvironment()
|
||||
{
|
||||
QProcessEnvironment env;
|
||||
return env;
|
||||
}
|
||||
|
||||
void QProcessPrivate::startProcess()
|
||||
{
|
||||
Q_Q(QProcess);
|
||||
|
||||
bool success = false;
|
||||
|
||||
if (pid) {
|
||||
CloseHandle(pid->hThread);
|
||||
CloseHandle(pid->hProcess);
|
||||
delete pid;
|
||||
pid = 0;
|
||||
}
|
||||
pid = new PROCESS_INFORMATION;
|
||||
memset(pid, 0, sizeof(PROCESS_INFORMATION));
|
||||
|
||||
q->setProcessState(QProcess::Starting);
|
||||
|
||||
QString args = qt_create_commandline(QString(), arguments);
|
||||
if (!nativeArguments.isEmpty()) {
|
||||
if (!args.isEmpty())
|
||||
args += QLatin1Char(' ');
|
||||
args += nativeArguments;
|
||||
}
|
||||
|
||||
#if defined QPROCESS_DEBUG
|
||||
qDebug("Creating process");
|
||||
qDebug(" program : [%s]", program.toLatin1().constData());
|
||||
qDebug(" args : %s", args.toLatin1().constData());
|
||||
qDebug(" pass environment : %s", environment.isEmpty() ? "no" : "yes");
|
||||
#endif
|
||||
|
||||
QString fullPathProgram = program;
|
||||
if (!QDir::isAbsolutePath(fullPathProgram))
|
||||
fullPathProgram = QFileInfo(fullPathProgram).absoluteFilePath();
|
||||
fullPathProgram.replace(QLatin1Char('/'), QLatin1Char('\\'));
|
||||
success = CreateProcess((wchar_t*)fullPathProgram.utf16(),
|
||||
(wchar_t*)args.utf16(),
|
||||
0, 0, false, 0, 0, 0, 0, pid);
|
||||
|
||||
if (!success) {
|
||||
cleanup();
|
||||
processError = QProcess::FailedToStart;
|
||||
emit q->error(processError);
|
||||
q->setProcessState(QProcess::NotRunning);
|
||||
return;
|
||||
}
|
||||
|
||||
q->setProcessState(QProcess::Running);
|
||||
// User can call kill()/terminate() from the stateChanged() slot
|
||||
// so check before proceeding
|
||||
if (!pid)
|
||||
return;
|
||||
|
||||
if (threadData->eventDispatcher) {
|
||||
processFinishedNotifier = new QWinEventNotifier(pid->hProcess, q);
|
||||
QObject::connect(processFinishedNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_processDied()));
|
||||
processFinishedNotifier->setEnabled(true);
|
||||
}
|
||||
|
||||
// give the process a chance to start ...
|
||||
Sleep(SLEEPMIN * 2);
|
||||
_q_startupNotification();
|
||||
}
|
||||
|
||||
bool QProcessPrivate::processStarted()
|
||||
{
|
||||
return processState == QProcess::Running;
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::bytesAvailableFromStdout() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::bytesAvailableFromStderr() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static BOOL QT_WIN_CALLBACK qt_terminateApp(HWND hwnd, LPARAM procId)
|
||||
{
|
||||
DWORD currentProcId = 0;
|
||||
GetWindowThreadProcessId(hwnd, ¤tProcId);
|
||||
if (currentProcId == (DWORD)procId)
|
||||
PostMessage(hwnd, WM_CLOSE, 0, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void QProcessPrivate::terminateProcess()
|
||||
{
|
||||
if (pid) {
|
||||
EnumWindows(qt_terminateApp, (LPARAM)pid->dwProcessId);
|
||||
PostThreadMessage(pid->dwThreadId, WM_CLOSE, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void QProcessPrivate::killProcess()
|
||||
{
|
||||
if (pid)
|
||||
TerminateProcess(pid->hProcess, 0xf291);
|
||||
}
|
||||
|
||||
bool QProcessPrivate::waitForStarted(int)
|
||||
{
|
||||
Q_Q(QProcess);
|
||||
|
||||
if (processStarted())
|
||||
return true;
|
||||
|
||||
if (processError == QProcess::FailedToStart)
|
||||
return false;
|
||||
|
||||
processError = QProcess::Timedout;
|
||||
q->setErrorString(QProcess::tr("Process operation timed out"));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QProcessPrivate::waitForReadyRead(int msecs)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QProcessPrivate::waitForBytesWritten(int msecs)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QProcessPrivate::waitForFinished(int msecs)
|
||||
{
|
||||
Q_Q(QProcess);
|
||||
#if defined QPROCESS_DEBUG
|
||||
qDebug("QProcessPrivate::waitForFinished(%d)", msecs);
|
||||
#endif
|
||||
|
||||
QIncrementalSleepTimer timer(msecs);
|
||||
|
||||
forever {
|
||||
if (!pid)
|
||||
return true;
|
||||
|
||||
if (WaitForSingleObject(pid->hProcess, timer.nextSleepTime()) == WAIT_OBJECT_0) {
|
||||
_q_processDied();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (timer.hasTimedOut())
|
||||
break;
|
||||
}
|
||||
processError = QProcess::Timedout;
|
||||
q->setErrorString(QProcess::tr("Process operation timed out"));
|
||||
return false;
|
||||
}
|
||||
|
||||
void QProcessPrivate::findExitCode()
|
||||
{
|
||||
DWORD theExitCode;
|
||||
if (GetExitCodeProcess(pid->hProcess, &theExitCode)) {
|
||||
exitCode = theExitCode;
|
||||
//### for now we assume a crash if exit code is less than -1 or the magic number
|
||||
crashed = (exitCode == 0xf291 || (int)exitCode < 0);
|
||||
}
|
||||
}
|
||||
|
||||
void QProcessPrivate::flushPipeWriter()
|
||||
{
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::pipeWriterBytesToWrite() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
Q_UNUSED(maxlen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool QProcessPrivate::waitForWrite(int msecs)
|
||||
{
|
||||
Q_UNUSED(msecs);
|
||||
return false;
|
||||
}
|
||||
|
||||
void QProcessPrivate::_q_notified()
|
||||
{
|
||||
}
|
||||
|
||||
bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDir, qint64 *pid)
|
||||
{
|
||||
Q_UNUSED(workingDir);
|
||||
QString args = qt_create_commandline(QString(), arguments);
|
||||
|
||||
bool success = false;
|
||||
|
||||
PROCESS_INFORMATION pinfo;
|
||||
|
||||
QString fullPathProgram = program;
|
||||
if (!QDir::isAbsolutePath(fullPathProgram))
|
||||
fullPathProgram.prepend(QDir::currentPath().append(QLatin1Char('/')));
|
||||
fullPathProgram.replace(QLatin1Char('/'), QLatin1Char('\\'));
|
||||
success = CreateProcess((wchar_t*)fullPathProgram.utf16(),
|
||||
(wchar_t*)args.utf16(),
|
||||
0, 0, false, CREATE_NEW_CONSOLE, 0, 0, 0, &pinfo);
|
||||
|
||||
if (success) {
|
||||
CloseHandle(pinfo.hThread);
|
||||
CloseHandle(pinfo.hProcess);
|
||||
if (pid)
|
||||
*pid = pinfo.dwProcessId;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_PROCESS
|
||||
Loading…
Reference in New Issue