繁体   English   中英

在Windows Python中陷阱和处理Taskkill

[英]Trapping and handling taskkill in Windows Python

我正在将pywin32-218用于Windows(Windows XP SP3)上的Python 2.6.6。

在我的Python应用程序中,我有第二个线程(除了主线程),它产生了一个子进程来运行另一个Windows可执行文件。

我的问题是,当主进程(python.exe)被杀死(例如,使用taskkill)时,我想终止子进程(calc.exe)并执行一些清除操作。

我尝试了各种方法(atexit,signal和win32api.handleConsoleCtrl),但似乎没有一个方法能够捕获taskkill信号。

我的代码如下(test.py):

import sys
import os
import signal
import win32api
import atexit
import time
import threading
import subprocess

class SecondThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.secondProcess = None
    def run(self):
        secondCommand = ['C:\WINDOWS\system32\calc.exe']
        self.secondProcess = subprocess.Popen(secondCommand)
        print 'calc.exe running'
        self.secondProcess.wait()
        print 'calc.exe stopped'
        # do cleanup here
    def stop(self):
        if self.secondProcess and self.secondProcess.returncode == None:
            self.secondProcess.kill()

secondThread = SecondThread()

def main():
    secondThread.start()

def cleanup():
    print 'cleaning up'
    secondThread.stop()
    print 'cleaned up'

atexit.register(cleanup)

def handleSignal(signalNum, frame):
    print 'handleSignal'
    cleanup()
    sys.exit(0)

for signalNum in (signal.SIGINT, signal.SIGILL, signal.SIGABRT, signal.SIGFPE, signal.SIGSEGV, signal.SIGTERM):
    signal.signal(signalNum, handleSignal)

def handleConsoleCtrl(signalNum):
    print ('handleConsoleCtrl')
    cleanup()

win32api.SetConsoleCtrlHandler(handleConsoleCtrl, True)

main()

该应用程序使用启动

python.exe test.py

然后,控制台显示“ calc.exe正在运行”,然后运行Calculator应用程序,并使用Process Explorer,我可以看到calc.exe是python.exe的子进程。

然后我使用杀死了主要过程

taskkill /pid XXXX /f

(其中XXXX是python.exe的PID)

此后发生的情况是命令提示符返回而没有进一步的输出(即,没有打印“ cleaning up”,“ handleSignal”或“ handleConsoleCtrl”),Calculator应用程序继续运行,并且在Process Explorer中,不再运行python.exe运行中,但calc.exe已重新设置其父级。

Taskkill(通常)发送WM_CLOSE 如果你的应用仅仅是控制台,没有窗户,而你可以得到CTRL_CLOSE_EVENT通过由设置处理器SetConsoleCtrlHandler (发生,如果你的控制终端窗口被关闭),你不能接受裸WM_CLOSE消息。

如果您必须坚持使用taskkill(而不是使用其他程序发送Ctrl-C ),则一种解决方案是设置上述处理程序,并确保您的应用程序具有自己的终端窗口(例如,通过使用start.exe "" <yourprog>调用它)。 有关替代方法的详细信息,请参见https://stackoverflow.com/a/23197789/4513656

暂无
暂无

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

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