简体   繁体   English

Python子进程kill适用于“ notepad.exe”,但不适用于“ calc.exe”

[英]Python subprocess kill is working for “notepad.exe” but not working for “calc.exe”

OS: Windows 10 Python: 3.5.2 I am trying to open calc.exe do some actions and than close it. 操作系统:Windows 10 Python:3.5.2我试图打开calc.exe做一些动作,然后关闭它。 Here is my code sample 这是我的代码示例

import subprocess, os, time
p = subprocess.Popen('calc.exe')
#Some actions
time.sleep(2)
p.kill()

So this is not working for calc.exe, it just opens the calculator, but does not close it, But same code is working fine for "notepad.exe". 因此,这对于calc.exe不起作用,它只是打开计算器,但没有关闭它,但是对于“ notepad.exe”来说,相同的代码工作正常。

I am guessing that there is a bug in subprocess lib for process kill method. 我猜在子进程库中有一个用于进程终止方法的错误。 so the notepad.exe process name in task manager is notepad.exe, but the calc.exe process name is calculator.exe, so I am guessing it is trying to kill by name and do not find it. 因此,任务管理器中的notepad.exe进程名称为notepad.exe,但是calc.exe进程名称为Calculator.exe,因此,我猜测它正在尝试按名称杀死它并找不到它。

There's no bug in subprocess.kill . subprocess.kill没有错误。 If you're really worried about that, just check the source , which is linked from the docs . 如果您真的对此感到担心,请检查docs链接的源代码 The kill method just calls send_signal , which just calls os.kill unless the process is already done, and you can see the Windows implementation for that function . kill方法仅调用send_signal ,除非过程已完成,否则仅调用os.kill ,您可以看到该函数的Windows实现 In short: subprocess.Process.kill doesn't care what name the process has in the kernel's process table (or the Task Manager); 简而言之: subprocess.Process.kill并不关心该进程在内核的进程表(或任务管理器)中的名称; it remembers the PID (process ID) of the process it started, and kills it that way. 它会记住它启动的进程的PID(进程ID),并以此方式将其杀死。

The most likely problem is that, like many Windows apps, calc.exe has some special "single instance" code: when you launch it, if there's already a copy of calc.exe running in your session, it just tells that copy to come to the foreground (and open a window, if it doesn't have one), and then exits. 最可能的问题是,与许多Windows应用程序一样, calc.exe具有一些特殊的“单个实例”代码:启动它时,如果会话中已经运行了calc.exe的副本,它只是告诉该副本即将到来到前台(如果没有,则打开一个窗口),然后退出。 So, by the time you try to kill it 2 seconds later, the process has already exited. 因此,当您尝试在2秒后将其kill时,该过程已经退出。

And if the actual running process is calculator.exe , that means calc.exe is just a launcher for the real program, so it always tells calculator.exe to come to the foreground, launching it if necessary, and then exits. 如果实际运行过程calculator.exe ,这意味着calc.exe是只为真正的程序启动器,所以它总是告诉calculator.exe来到前台,如果有必要启动它,然后退出。

So, how can you kill the new calculator you started? 那么,如何杀死您启动的新计算器? Well, you can't, because you didn't start a new one. 好吧,你不能,因为你没有开始新的。 You can kill all calc.exe and/or calculator.exe processes (the easiest way to do this is with a third-party library like psutil —see the examples on filtering and then kill the process once you've found it), but that will kill any existing calculator process you had open before running your program, not just the new one you started. 你可以杀死所有 calc.exe和/或calculator.exe过程(做,这是一个第三方库像最简单的方式psutil -见的例子过滤 ,然后kill进程,一旦你已经找到了),但这将杀死您在运行程序之前打开的任何现有计算器进程,而不仅仅是启动的新计算器进程。 Since calc.exe makes it impossible to tell if you've started a new process or not, there's really no way around that. 由于calc.exe使得无法判断您是否已开始新进程,因此实际上没有解决办法。

This is one way to kill it, but it will close every open calculator. 这是杀死它的一种方法,但是它将关闭所有打开的计算器。

It calls a no window command prompt and gives the command to close the Calculator.exe process. 它会调用no window命令提示符,并给出命令以关闭Calculator.exe进程。

import subprocess, os, time
p = subprocess.Popen('calc.exe')
print(p)
#Some actions
time.sleep(2)
CREATE_NO_WINDOW = 0x08000000
subprocess.call('taskkill /F /IM Calculator.exe', creationflags=CREATE_NO_WINDOW)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM