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;
}
Beispiel #2
0
bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDir, qint64 *pid)
{
    QString args = qt_create_commandline(program, arguments);
    bool success = false;
    PROCESS_INFORMATION pinfo;

    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);
        CloseHandle(pinfo.hProcess);
        if (pid)
            *pid = pinfo.dwProcessId;
    }

    return success;
}
Beispiel #3
0
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

    if (success) {
        CloseHandle(pinfo.hThread);
        CloseHandle(pinfo.hProcess);
        if (pid)
            *pid = pinfo.dwProcessId;
    }

    return success;
}
bool AdminAuthorization::execute(const QString &program, const QStringList &arguments)
{
    // AdminAuthorization::execute uses UAC to ask for admin privileges. If the user is no
    // administrator yet and the computer's policies are set to not use UAC (which is the case
    // in some corporate networks), the call to execute() will simply succeed and not at all
    // launch the child process. To avoid this, we detect this situation here and return early.
    if (!hasAdminRights())
    {
        QLatin1String key("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
                          "Policies\\System");
        QSettings registry(key, QSettings::NativeFormat);
        const QVariant enableLUA = registry.value(QLatin1String("EnableLUA"));

        if ((enableLUA.type() == QVariant::Int) && (enableLUA.toInt() == 0))
        {
            return false;
        }
    }

    const QString file = QDir::toNativeSeparators(program);
    const QString args = qt_create_commandline(QString(), arguments);

    SHELLEXECUTEINFOW shellExecuteInfo = { 0 };
    shellExecuteInfo.nShow = SW_HIDE;
    shellExecuteInfo.lpVerb = L"runas";
    shellExecuteInfo.lpFile = (wchar_t *)file.utf16();
    shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
    shellExecuteInfo.lpParameters = (wchar_t *)args.utf16();
    shellExecuteInfo.fMask = SEE_MASK_NOASYNC;

    qDebug() << QString::fromLatin1("Starting elevated process %1 with arguments: %2.").arg(file, args);

    if (ShellExecuteExW(&shellExecuteInfo))
    {
        qDebug() << "Finished starting elevated process.";
        return true;
    }
    else
    {
        qWarning() << QString::fromLatin1("Error while starting elevated process: %1, "
            "Error: %2").arg(program, windowsErrorString(GetLastError()));
    }

    return false;
}
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->hasEventDispatcher()) {
        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();
}
Beispiel #6
0
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);

    if (!createChannel(stdinChannel) ||
        !createChannel(stdoutChannel) ||
        !createChannel(stderrChannel))
        return;

    QString args = qt_create_commandline(program, arguments);
    QByteArray envlist;
    if (environment.d.constData())
        envlist = qt_create_environment(environment.d.constData()->hash);
    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

    // Forwarded channels must not set the CREATE_NO_WINDOW flag because this
    // will render the stdout/stderr handles we're passing useless.
    DWORD dwCreationFlags = (processChannelMode == QProcess::ForwardedChannels ? 0 : CREATE_NO_WINDOW);
    dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
    STARTUPINFOW startupInfo = { sizeof( STARTUPINFO ), 0, 0, 0,
                                 (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
                                 (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
                                 0, 0, 0,
                                 STARTF_USESTDHANDLES,
                                 0, 0, 0,
                                 stdinChannel.pipe[0], stdoutChannel.pipe[1], stderrChannel.pipe[1]
    };
    success = CreateProcess(0, (wchar_t*)args.utf16(),
                            0, 0, TRUE, dwCreationFlags,
                            environment.isEmpty() ? 0 : envlist.data(),
                            workingDirectory.isEmpty() ? 0 : (wchar_t*)QDir::toNativeSeparators(workingDirectory).utf16(),
                            &startupInfo, pid);
    if (!success) {
        // Capture the error string before we do CloseHandle below
        q->setErrorString(QProcess::tr("Process failed to start: %1").arg(qt_error_string()));
    }

    if (stdinChannel.pipe[0] != INVALID_Q_PIPE) {
        CloseHandle(stdinChannel.pipe[0]);
        stdinChannel.pipe[0] = INVALID_Q_PIPE;
    }
    if (stdoutChannel.pipe[1] != INVALID_Q_PIPE) {
        CloseHandle(stdoutChannel.pipe[1]);
        stdoutChannel.pipe[1] = INVALID_Q_PIPE;
    }
    if (stderrChannel.pipe[1] != INVALID_Q_PIPE) {
        CloseHandle(stderrChannel.pipe[1]);
        stderrChannel.pipe[1] = INVALID_Q_PIPE;
    }

    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);
        notifier = new QTimer(q);
        QObject::connect(notifier, SIGNAL(timeout()), q, SLOT(_q_notified()));
        notifier->start(NOTIFYTIMEOUT);
    }

    _q_startupNotification();
}
QString QInstaller::createCommandline(const QString &program, const QStringList &arguments)
{
    return qt_create_commandline(program, arguments);
}