在Windows Python中捕获和处理taskkill任务

3

我在Windows XP SP3上使用Python 2.6.6和pywin32-218。

我的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正在运行”,计算器应用程序运行,并且使用进程资源管理器,我可以看到calc.exe作为python.exe的子进程。然后我使用以下命令杀死主进程:
taskkill /pid XXXX /f

(其中XXXX是python.exe的PID)之后,命令提示符返回而没有进一步输出(即“cleaning up”,“handleSignal”或“handleConsoleCtrl”都没有打印),计算器应用程序继续运行,并且从Process Explorer中可以看出,python.exe不再运行,但calc.exe已经重新成为了父级进程。

创建另一个程序来跟踪您的主程序怎么样? - Hamoudaq
1个回答

1

Taskkill(通常)发送WM_CLOSE。如果您的应用程序仅为控制台且没有窗口,则可以通过由SetConsoleCtrlHandler设置的处理程序获取CTRL_CLOSE_EVENT(如果关闭控制终端窗口),但无法接收裸WM_CLOSE消息。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接