【问题标题】:Python - Windows Shutdown EventsPython - Windows 关机事件
【发布时间】:2009-09-11 14:21:59
【问题描述】:

使用win32api.setConsoleCtrlHandler() 时,我能够从 Windows 接收关闭/注销/等事件,并彻底关闭我的应用程序。

但是,这只适用于在 python.exe 下运行应用程序(即,它有一个控制台窗口),而不是在 pythonw.exe 下(没有控制台窗口)。

当您没有控制台和窗口来接收这些事件时,Windows 中是否有等效的方式来接收这些事件?或者,是否有一种编程方式来隐藏控制台窗口?

明确一点 - 我的目标是能够成功接收 Windows 关闭/注销/等事件,而不会显示任何类型的控制台窗口。

编辑: 我一直在玩,而且我已经走得更远了。我为此写了一段测试代码。当我执行taskkill /im pythonw.exe 时 - 它会收到消息。

但是,当我在 Windows 上关闭、重新启动或注销时,我没有收到任何消息。

这就是全部内容:

""" Testing Windows shutdown events """

import win32con
import win32api
import win32gui
import sys
import time

def log_info(msg):
    """ Prints """
    print msg
    f = open("c:\\test.log", "a")
    f.write(msg + "\n")
    f.close()

def wndproc(hwnd, msg, wparam, lparam):
    log_info("wndproc: %s" % msg)

if __name__ == "__main__":
    log_info("*** STARTING ***")
    hinst = win32api.GetModuleHandle(None)
    wndclass = win32gui.WNDCLASS()
    wndclass.hInstance = hinst
    wndclass.lpszClassName = "testWindowClass"
    messageMap = { win32con.WM_QUERYENDSESSION : wndproc,
                   win32con.WM_ENDSESSION : wndproc,
                   win32con.WM_QUIT : wndproc,
                   win32con.WM_DESTROY : wndproc,
                   win32con.WM_CLOSE : wndproc }
    
    wndclass.lpfnWndProc = messageMap
    
    try:
        myWindowClass = win32gui.RegisterClass(wndclass)
        hwnd = win32gui.CreateWindowEx(win32con.WS_EX_LEFT,
                                     myWindowClass, 
                                     "testMsgWindow", 
                                     0, 
                                     0, 
                                     0, 
                                     win32con.CW_USEDEFAULT, 
                                     win32con.CW_USEDEFAULT, 
                                     win32con.HWND_MESSAGE, 
                                     0, 
                                     hinst, 
                                     None)
    except Exception, e:
        log_info("Exception: %s" % str(e))
    

    if hwnd is None:
        log_info("hwnd is none!")
    else:
        log_info("hwnd: %s" % hwnd)
    
    while True:
        win32gui.PumpWaitingMessages()
        time.sleep(1)

我觉得我离这里很近,但我肯定错过了一些东西!

【问题讨论】:

    标签: python windows


    【解决方案1】:

    这里的问题是 HWND_MESSAGE 窗口类型实际上并没有接收广播消息 - 例如 WM_QUERYENDSESSIONWM_ENDSESSION

    所以我没有为CreateWindowEx()的“父窗口”参数指定win32con.HWND_MESSAGE,而是指定了0

    基本上,这会创建一个实际的窗口,但我从不显示它,所以它实际上是一回事。现在,我可以成功接收到这些广播消息并正常关闭应用了。

    【讨论】:

    • 如何执行...
    • 在 Windows 10 上,这仅适用于 python.exe,不适用于 pythonw.exe
    • 这对我不起作用。我有 python 3.10。
    【解决方案2】:

    如果您没有控制台,那么设置控制台处理程序当然是行不通的。您可以通过创建另一个窗口(不必可见)来在 GUI(非控制台)程序上接收系统事件,确保您有一个正常的“消息泵”在其上提供服务,并处理 WM_QUERYENDSESSION - 那是该消息告诉您的窗口有关关闭和注销事件(并且您的窗口可以通过为此消息返回 0 来尝试推回结束会话)。 (“Windows 服务”不同于普通的应用程序——如果你写的是这个,请看一个例​​子here)。

    【讨论】:

    • 我尝试了上面的代码,但我从未在注销/关机时触发系统事件。你能帮帮我吗……?
    猜你喜欢
    • 2020-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    相关资源
    最近更新 更多