Python - События завершения работы Windows - PullRequest
8 голосов
/ 11 сентября 2009

При использовании win32api.setConsoleCtrlHandler () я могу получать события завершения работы / выхода из системы и т. Д. Из Windows и корректно завершать работу моего приложения.

Однако это работает только при запуске приложения под python.exe (т. Е. У него есть окно консоли), но не под pythonw.exe (без окна консоли).

Есть ли в Windows эквивалентный способ получения этих событий, когда у вас нет консоли и нет окна для их получения? Или есть программный способ скрыть окно консоли?

Чтобы было ясно - моя цель - иметь возможность успешно получать события завершения работы Windows / выхода из системы / и т. Д., Без какого-либо отображения окна консоли.

EDIT: Я играл вокруг, и я получил немного дальше. Я написал кусок тестового кода для этого. Когда я делаю "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)

Я чувствую, что здесь довольно близко, но я определенно что-то упускаю!

Ответы [ 2 ]

9 голосов
/ 16 сентября 2009

Проблема заключалась в том, что тип окна HWND_MESSAGE на самом деле не принимает широковещательные сообщения - такие как WM_QUERYENDSESSION и WM_ENDSESSION.

Таким образом, вместо указания win32con.HWND_MESSAGE для параметра «родительское окно» CreateWindowEx (), я просто указал «0».

По сути, это создает реальное окно, но я никогда его не показываю, так что это фактически одно и то же. Теперь я могу успешно получать эти широковещательные сообщения и корректно завершать работу приложения.

4 голосов
/ 11 сентября 2009

Если у вас нет консоли, настройка обработчика консоли, конечно, может не сработать. Вы можете получать системные события в программе с графическим интерфейсом (не консольной), сделав другое окно (не должно быть видимым), убедившись, что у вас есть обычный «обработчик сообщений», и обрабатывает WM_QUERYENDSESSION - сообщение, сообщающее вашему окну о событиях завершения работы и выхода из системы (и ваше окно может попытаться отодвинуться от конца сеанса, вернув 0 для этого сообщения). («Службы Windows» отличаются от обычных приложений - если это то, что вы пишете, см. Пример здесь ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...