Windows 查找当前CMD窗口的conhost.exe进程的PID
我想创建一个doskey命令,关闭当前的CMD控制台窗口,而不影响任何其他打开的CMD控制台窗口 即使在该窗口内已运行cmd.exe(手动或批处理文件),它也必须工作。通常我只会使用Windows 查找当前CMD窗口的conhost.exe进程的PID,windows,batch-file,cmd,pid,Windows,Batch File,Cmd,Pid,我想创建一个doskey命令,关闭当前的CMD控制台窗口,而不影响任何其他打开的CMD控制台窗口 即使在该窗口内已运行cmd.exe(手动或批处理文件),它也必须工作。通常我只会使用exit命令,但如果cmd.exe的其他实例已在该窗口中运行,则不会关闭该窗口 因此,我决定创建一个“close”命令,该命令将始终关闭当前窗口,而不管其中运行了什么。我选择了窗口检测的PID方法(以避免窗口标题相同的问题),然后使用带有/F和/T开关的taskkill终止进程。它工作正常,但与使用标准的“退出”命令
exit
命令,但如果cmd.exe的其他实例已在该窗口中运行,则不会关闭该窗口
因此,我决定创建一个“close”命令,该命令将始终关闭当前窗口,而不管其中运行了什么。我选择了窗口检测的PID方法(以避免窗口标题相同的问题),然后使用带有/F和/T开关的taskkill
终止进程。它工作正常,但与使用标准的“退出”命令有相同的问题
我运行了tasklist
,意识到只要在其中运行CMD.exe,当前CMD窗口的PID就会改变(即使没有打开新窗口,您也可以看到列出的CMD.exe的多个实例),因此使用CMD.exe PID是不可用的方法。但是,每个窗口都有自己的conhost.exe进程与之关联(无论cmd实例的数量如何),因此终止comhost进程似乎是实现我想要的目标的最佳方式
我手动尝试了一下,效果完全符合我的要求
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%
set T=%TEMP%\sthUnique.tmp
wmic进程,其中(Name=“wmic.exe”和类似“%%%TIME%%%”的命令行)获取ParentProcessId/value |查找“ParentProcessId”>%T%
set/P A=它只是一个控制台窗口,而不是CMD控制台窗口。CMD与创建或托管控制台窗口或控制台I/O缓冲区无关。它只是一个实现交互式shell的常规控制台应用程序。在Windows 7+中,每个控制台窗口都托管在一个conhost.exe实例中。但是控制台主机实际上将窗口的拥有进程和线程ID(即从GetWindowThreadProcessId
)伪造为分配进程的进程和线程ID,或者如果第一个进程退出,则伪造为其附加进程列表中的下一个进程。这种攻击是在Windows NT早期添加的,当时控制台托管在会话服务器csrss.exe的一个线程上,因为这种攻击允许识别与进程相关联的控制台窗口并发送WM_CLOSE
消息。taskkill.exe将WM_CLOSE
发送到应用程序的窗口,但仅适用于非强制终止。假设您试图杀死被冒充为所有者的控制台的lead进程,如果您省略/F
和/T
选项,它应该按照您想要的方式工作。这将关闭控制台窗口,连接到控制台的所有应用程序将收到一个CTRL\u close\u事件的信号,并在会话服务器csrss.exe强制终止之前有5秒钟的时间优雅地退出。