3

我想创建一个关闭当前CMD 控制台窗口的 doskey 命令,而不影响任何其他打开的 CMD 控制台窗口。

即使在该窗口中(手动或通过批处理文件)运行了 cmd.exe,它也必须工作。通常我只会使用该exit命令,但如果 cmd.exe 的其他实例已在该窗口中运行,这不会关闭该窗口。

因此,我决定创建一个“关闭”命令,该命令将始终关闭当前窗口,无论其中运行了什么。我选择了窗口检测的 PID 方法(以避免出现标题相同的窗口问题),然后taskkill与 /F 和 /T 开关一起使用来终止进程。它工作得很好,但它与使用标准的“退出”命令有同样的问题。

我运行tasklist并意识到,只要在其中运行 cmd.exe,当前CMD 窗口的 PID 就会发生变化(即使没有打开新窗口,您也可以看到列出的 cmd.exe 的多个实例),因此使用 cmd.exe PID 是不是一个可用的方法。但是,每个窗口都有自己的conhost.exe进程与之关联(不管 cmd 实例的数量),因此终止 comhost 进程似乎是实现我想要的最佳方法。

我手动尝试了它,它完全按照我的意愿工作。

  1. 打开一个 cmd 控制台窗口,然后在该窗口中运行 cmd.exe 几次。
  2. 打开第二个 cmd 控制台窗口,在第二个窗口中运行 cmd.exe 几次。
  3. 使用 tasklist 查找要关闭的窗口的conhost进程的 PID。
  4. 手动运行:taskkill /PID <主机进程的PID > /F 杀死选定的主机。

以上立即关闭指定的控制台窗口(及其所有相关的 cmd.exe 实例),而单独保留另一个控制台窗口。

因此,我只需要在批处理文件中复制上述过程,这样我就可以使用我的 doskey 命令来调用它,而不是我现有的 cmd PID 检查代码。

这是我用于当前 cmd PID 检测的代码(我在网上找到的)。我不明白(我是代码新手),但它工作得很好。

然后我根据当前窗口的退出 cmd.exe PID 寻找方法来确定 conhost PID,但除了这个之外我找不到任何东西,它不起作用(并且这也导致了与现有命令无关的各种其他问题在我的批处理文件中)。

也许有一种更简单的方法可以实现我的目标,但是如果杀死 conhost 是要走的路,那么在我看来,下面代码的修改版本(使其找到当前的 conhost PID 而不是当前的 cmd PID)将是答案,因为在批处理文件中可靠地工作的代码行很少。

set T=%TEMP%\sthUnique.tmp
wmic process where (Name="WMIC.exe" AND CommandLine LIKE "%%%TIME%%%") get ParentProcessId /value | find "ParentProcessId" >%T%
set /P A=<%T%
set PID=%A:~16%
4

0 回答 0