如何使用QProcess启动并稍后在控制台窗口中终止cmd.exe

时间:2014-03-27 14:51:40

标签: c++ qt qprocess

我需要通过QProcess运行一个可见的cmd.exe窗口,并最终终止它。 shell的控制台窗口必须位于前台,并且必须对用户可见。

如果我使用QProcess::start()启动它,则控制台窗口永远不会出现。如果我使用类方法QProcess::startDetached()启动它,我不能使用实例方法terminate()来终止它。

2 个答案:

答案 0 :(得分:4)

在Windows上,QProcess有两种操作模式:

  1. 使用实例方法时的正常模式,如start()。在此模式下,QProcess本身是正在运行的应用程序的控制台,如果它请求一个。这个控制台是一个逻辑对象(就像Unix上的伪tty),没有可见的外观。

  2. 使用类方法 startDetached时的分离模式。如果正在运行的进程请求控制台,Windows会为其提供控制台窗口。

  3. 因此,利用Windows提供的控制台窗口的唯一选择是分离的开始。

    如果您希望在cmd.exe执行命令后让某人留在打开的控制台窗口,则以下情况适用:

    • 传递给执行的每个命令都需要以/k开头。

    • /k和命令是单独的参数

    要在应用程序退出时终止进程,可以使用以下类的实例,使其成为应用程序实例的子代:

    #include <windows.h>
    ...
    class ProcessKiller : public QObject {
      qint64 m_pid;
    public:
      ProcessKiller(qint64 pid, QObject * parent = 0) : 
        QObject(parent), m_pid(pid) {}
      ~ProcessKiller() {
        HANDLE hApp = OpenProcess(PROCESS_QUERY_INFORMATION
                                  | PROCESS_TERMINATE, FALSE, m_pid);
        if (hApp == NULL) return;
        TerminateProcess(hApp, NULL);
        CloseHandle(hApp);
      }
    }
    

    因此,在Windows提供的控制台窗口中以两个cmd.exe命令开始运行echo,并在应用程序退出时将其杀死,将是:

    qint64 pid;
    QProcess::startDetached("cmd.exe", QStringList()
      << "/k" << "echo foo"
      << "/k" << "echo bar",
      QDir::currentPath(), &pid);
    new ProcessKiller(pid, qApp);
    

答案 1 :(得分:0)

以下代码将解决我的问题:

qint64 pID;
QProcess *myProcess = new QProcess(this);
QStringList arguments;
arguments << "/k cd /d " << "c:\path to be opened";
myProcess->startDetached("cmd.exe", arguments, "", &pID);

...
...

QString pidString;
pidString.setNum(pID);
QString killProcessUsingPid = "taskkill /PID ";
killProcessUsingPid.append(pidString);

system(killProcessUsingPid.toStdString().c_str());