【问题标题】:How to launch and later terminate cmd.exe in a console window with QProcess如何使用 QProcess 在控制台窗口中启动和稍后终止 cmd.exe
【发布时间】:2014-03-27 14:51:39
【问题描述】:

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

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

【问题讨论】:

  • 我尝试使用 QProcess start 和 startDetach stratDetach 的问题是,它分离了进程。我想在我的应用程序本身中处理它。
  • @AlexP 是的。我有一个命令行实用程序。当我运行它时,它会在一秒钟内运行并关闭。但我想至少通过 cmd.exe 向用户展示该工具

标签: c++ qt qprocess


【解决方案1】:

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

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

  2. 使用类方法时的分离模式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);
  }
}

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

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

【讨论】:

  • 至少我们能得到分离进程的进程ID吗?因为我需要在关闭 Qt 应用程序时终止该进程
  • 好的。我使用分离进程的原因是用户与 cmd.exe 进行通信如果我使用 start 而不是 startDetached,cmd.exe 只会弹出并立即关闭。有一个选项可以在 startDetached 方法中获取进程的 pid,但不确定如何使用该 pid 关闭 cmd.exe
  • 这是我用来启动 cmd.exe 的一段代码 [code] `qint64 pID; QProcess *myProcess = new QProcess(this); QStringList 参数; arguments startDetached("cmd.exe", arguments, "", &pID);'
  • 析构函数代码应该是这样
     ProcessKiller::~ProcessKiller() { HANDLE hApp = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_TERMINATE, FALSE, m_pid); if(hApp != NULL) { TerminateProcess(hApp, NULL);关闭句柄(hApp); hApp = NULL; } }
【解决方案2】:

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

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());

【讨论】:

  • 我认为应该是 path = "c:\path to be opening";参数 startDetached("cmd.exe", arguments, path, &pID);
猜你喜欢
  • 1970-01-01
  • 2011-07-05
  • 1970-01-01
  • 2017-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多