使用Python优雅地杀死Windows版Chrome [英] Gracefully kill Chrome for Windows with Python

查看:104
本文介绍了使用Python优雅地杀死Windows版Chrome的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试确定一种使用Python正常关闭Chrome(及其他进程)的方法.我已经尝试了几种方法,但是所有方法都会导致Chrome显示一条消息,指出"Chrome无法正确关闭".与还原按钮.当您从Windows中的任务管理器中关闭程序时,不会发生这种情况.我使用Falcon编写了一个程序,以提供API访问权限以关闭托管"程序.相应的代码无关紧要,但是下面是我尝试过的方法,这些方法确实可以正常运行Chrome,但效果并不理想.

I have been trying to determine a method to close Chrome (and other processes) gracefully utilizing Python. I have gone through a few methods but all result in Chrome displaying a message stating "Chrome didn't shut down correctly." with a Restore button. This doesn't happen when you shut down a program from task manager in Windows. I have written a program utilizing Falcon to provide API access to shut down 'managed' programs. The code for that isn't relevant, but here are the methods I have tried that do work to shut down Chrome that work well, but not gracefully.

def stop_app(app_exe):
    for process in psutil.process_iter():
        if process.name() == app_exe:
            process.terminate()

备用:

for process in psutil.process_iter():
    if process.name() == app_exe:
        children = process.children(recursive=True)
        children.append(process)
        for p in children:
            p.send_signal(signal.CTRL_BREAK_EVENT)

我也尝试过用kill()代替各种信号类型的terate()(Windows实际上仅支持三种,CTRL_BREAK_EVENT,CNTL_C_EVENT,SIGTERM).

I have also tried kill() in place of terminate(), various signal types (Windows really only supports three, CTRL_BREAK_EVENT, CNTL_C_EVENT, SIGTERM).

我也尝试过使用Win32库,但遇到了同样的问题.Win32也不是平台无关的,我发现Win32/wmi库在寻找运行Windows进程时会占用大量系统资源.psutil库允许与平台无关,并且在遍历Windows进程时不会出现相同的性能问题.这是代码.

I have also tried using the win32 library and I had the same issue. Win32 also isn't platform agnostic and I had found that win32/wmi libraries utilize a lot of system resources when looking for running windows processes. The psutil library allows for being platform agnostic AND doesn't have the same performance issue when iterating through the Windows processes. Here is the code for that.

c = wmi.WMI()
for process in c.Win32_Process():
    if process.Name == app_exe:
        process.Terminate()

外面有人尝试类似的方法并提出解决方案吗?

Anyone out there try something similar and come up with a solution?

根据CristiFati的建议快速解决.

Quick solution per CristiFati recommendations.:

def enumWindowsProc(hwnd, lParam):
    if (lParam is None) or ((lParam is not None) and 
          win32process.GetWindowThreadProcessId(hwnd)[1] == pid)):
        text = win32gui.GetWindowText(hwnd)
        if text:
            wStyle = win32api.GetWindowLong(hwnd, win32con.GWL_STYLE)
            if wStyle & win32con.WS_VISIBLE:
                win32api.SendMessage(hwnd, win32con.WM_CLOSE)


def stop_app(app_exe):
    for process in psutil.process_iter():
        if process.name() == app_exe:
            win32gui.EnumWindows(enumWindowsProc, process.pid)

推荐答案

显然, Chrome 在由于进程终止而关闭时不满意.它具有检测这种确切情况的机制.
它运行着许多流程,我认为这可以是一种通过仔细选择流程顺序来正常关闭流程的方式(我可能是错的,但是我记得一旦我做到了)被杀死( crashpad-handler utility renderer ,在 master 之前),但是现在我可以了做到这一点,我也不知道那实际上是多么优雅.

Apparently, Chrome is not happy when being closed by process termination. It has a mechanism of detecting this exact scenario.
It has a bunch of processes running, and I think it could be a way of gracefully closing it (I might be wrong, but I remember that once I managed to do it), by carefully selecting the order which the processes are killed (crashpad-handler, utility, renderers, before the master one), but now I can't do it, neither do I know how gracefully that actually is.

注意:我个人认为此行为非常有用,因为我打开了许多带有许多选项卡的 Chrome 窗口,每次需要重新启动笔记本电脑时,我都会从任务管理器中关闭 Chrome ,以便下次打开它时,它将恢复当前状态.

Note: I personally consider this behavior very useful, because I have many opened Chrome windows each with many tabs, and every time I need to restart my laptop, I close Chrome from Task Manager, so that next time I open it it will restore the current state.

回到我们的问题,一种方法是获取其窗口并将其发送给 [MS.Docs]:WM_CLOSE消息(另请检查

Back, to our problem, one way would be to get its window and sending it the [MS.Docs]: WM_CLOSE message (also check [MS.Docs]: Closing the Window). Note that it's Win specific!

win32api.SendMessage(0x005C0974, win32con.WM_CLOSE)  # 0x005C0974 was Chrome's (main) window handle in my test

  • 您需要做的就是将以上3种(略有变化)结合起来
  • 另一个适用于Windows的示例: [SO]:键盘事件未通过pywin32发送到窗口(@CristiFati的回答).

    Another example that works with windows: [SO]: Keyboard event not sent to window with pywin32 (@CristiFati's answer).

    这篇关于使用Python优雅地杀死Windows版Chrome的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆