2009-09-11 72 views
7

win32api.setConsoleCtrlHandler()を使用すると、Windowsからシャットダウン/ログオフ/ etcイベントを受け取り、アプリケーションを正常にシャットダウンできます。Python - Windowsのシャットダウンイベント

ただし、これはpython.exe(コンソールウィンドウがある)ではなく、pythonw.exe(コンソールウィンドウなし)ではなく、アプリケーションを実行しているときのみ機能します。

これらのイベントを受信するWindowsと同等の方法は、コンソールがなく、受信するウィンドウがない場合ですか?または、コンソールウィンドウを非表示にするプログラム的な方法はありますか?

私の目標は、コンソールウィンドウを表示することなく、Windowsのシャットダウン/ログオフ/ etcイベントを正常に受信できるようにすることです。

編集: 私は周りを遊んでいましたが、かなり進んでいます。私はこれのためのテストコードを書いた。 「taskkill/im pythonw.exe」を実行すると、メッセージが表示されます。

ただし、Windowsでシャットダウン、再起動、またはログオフすると、メッセージは表示されません。

はここで全部です:

""" Testing Windows shutdown events """ 

import win32con 
import win32api 
import win32gui 
import sys 
import time 
#import os 

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) 

私はここにかなり近いんだような気がしますが、私は間違いなく何かが足りないんです!

答えて

7

ここでの問題は、HWND_MESSAGEウィンドウタイプがWM_QUERYENDSESSIONやWM_ENDSESSIONのようなブロードキャストメッセージを実際に受信しないことです。

したがって、CreateWindowEx()の "parent window"パラメータにwin32con.HWND_MESSAGEを指定する代わりに、私は "0"を指定しました。

これは基本的に実際のウィンドウを作成しますが、私はそれを表示しませんので、事実上同じです。今、私は正常にそれらのブロードキャストメッセージを受信し、適切にアプリケーションをシャットダウンすることができます。

+0

これを実行する方法...私は提供されたscriptを実行しようとしましたが、それは蟻のシステムLogogg、シャットダウンイベントを返さないか、またはタスクマネージャからタスクをkillしても – Rao

4

コンソールがない場合は、もちろんコンソールハンドラを設定することはできません。別のウィンドウ(表示する必要はありません)を作成し、通常の「メッセージポンプ」をサービスしていることを確認し、WM_QUERYENDSESSIONを処理することで、GUI(非コンソール)プログラムでシステムイベントを受け取ることができますウィンドウにシャットダウンとログオフのイベントを伝えます(ウィンドウはこのメッセージの0を返すことでエンドセッションに対してプッシュバックできます)。 (「Windowsサービス」は通常のアプリとは異なります - あなたが書いている場合はhereの例を参照してください)。

+0

私は上記のコードを試しましたが、ログオフ/シャットダウン時にシステムイベントを起動することはありません。ここで私を助けることができます....? – Rao

関連する問題