我需要通过 QProcess 运行一个可见的 cmd.exe 窗口,并最终终止它。shell 的控制台窗口必须在前台,并且必须对用户可见。
如果我使用 启动它QProcess::start(),控制台窗口永远不会出现。如果我使用类方法启动它QProcess::startDetached(),我不能使用实例方法terminate()来终止它。
在 Windows 上,QProcess有两种操作模式:
当您使用普通模式的实例方法一样start()。在这种模式下,如果它请求一个,它QProcess本身就是正在运行的应用程序的控制台。这个控制台是一个逻辑对象(就像 Unix 上的伪 tty)并且没有可见的外观。
使用类方法 时的分离模式startDetached。如果正在运行的进程请求控制台,Windows 会为其提供控制台窗口。
因此,利用 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);
}
}
Run Code Online (Sandbox Code Playgroud)
因此,要在 Windows 提供的控制台窗口中cmd.exe以两个echo命令开始运行,并在应用程序退出时将其终止,将是:
qint64 pid;
QProcess::startDetached("cmd.exe", QStringList()
<< "/k" << "echo foo"
<< "/k" << "echo bar",
QDir::currentPath(), &pid);
new ProcessKiller(pid, qApp);
Run Code Online (Sandbox Code Playgroud)