Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 查找当前CMD窗口的conhost.exe进程的PID_Windows_Batch File_Cmd_Pid - Fatal编程技术网

Windows 查找当前CMD窗口的conhost.exe进程的PID

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终止进程。它工作正常,但与使用标准的“退出”命令

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

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

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

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

我手动尝试了一下,效果完全符合我的要求

  • 打开一个cmd控制台窗口,然后在该窗口内运行cmd.exe几次
  • 打开第二个cmd控制台窗口,在第二个窗口中运行cmd.exe几次
  • 使用任务列表查找所选窗口的conhost进程的PID 我想关门
  • 手动运行:   taskkill/PID/F  杀掉 选定的conhost 上述操作会立即关闭指定的控制台窗口(及其所有相关的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%
    
    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秒钟的时间优雅地退出。