def detect_win32_session_events(self, app_hwnd): """ Use pywin32 to receive session notification events. """ log.debug("detect_win32_session_events(%s)" % app_hwnd) try: import win32ts, win32con, win32api, win32gui #@UnresolvedImport WM_TRAYICON = win32con.WM_USER + 20 NIN_BALLOONSHOW = win32con.WM_USER + 2 NIN_BALLOONHIDE = win32con.WM_USER + 3 NIN_BALLOONTIMEOUT = win32con.WM_USER + 4 NIN_BALLOONUSERCLICK = win32con.WM_USER + 5 #register our interest in those events: #http://timgolden.me.uk/python/win32_how_do_i/track-session-events.html#isenslogon #http://stackoverflow.com/questions/365058/detect-windows-logout-in-python #http://msdn.microsoft.com/en-us/library/aa383841.aspx #http://msdn.microsoft.com/en-us/library/aa383828.aspx win32ts.WTSRegisterSessionNotification( app_hwnd, win32ts.NOTIFY_FOR_THIS_SESSION) #catch all events: http://wiki.wxpython.org/HookingTheWndProc def MyWndProc(hWnd, msg, wParam, lParam): #from the web!: WM_WTSSESSION_CHANGE is 0x02b1. if msg == 0x02b1: log.debug("Session state change!") elif msg == win32con.WM_DESTROY: # Restore the old WndProc log.debug("WM_DESTROY, restoring call handler") win32api.SetWindowLong(app_hwnd, win32con.GWL_WNDPROC, self.oldWndProc) elif msg == win32con.WM_COMMAND: log.debug("WM_COMMAND") elif msg == WM_TRAYICON: log.debug("WM_TRAYICON") if lParam == NIN_BALLOONSHOW: log.debug("NIN_BALLOONSHOW") if lParam == NIN_BALLOONHIDE: log.debug("NIN_BALLOONHIDE") self.balloon_click_callback = None elif lParam == NIN_BALLOONTIMEOUT: log.debug("NIN_BALLOONTIMEOUT") elif lParam == NIN_BALLOONUSERCLICK: log.info( "NIN_BALLOONUSERCLICK, balloon_click_callback=%s" % self.balloon_click_callback) if self.balloon_click_callback: self.balloon_click_callback() self.balloon_click_callback = None else: log.debug("unknown win32 message: %s / %s / %s", msg, wParam, lParam) # Pass all messages to the original WndProc try: return win32gui.CallWindowProc(self.old_win32_proc, hWnd, msg, wParam, lParam) except Exception, e: log.error("error delegating call: %s", e) self.old_win32_proc = win32gui.SetWindowLong( app_hwnd, win32con.GWL_WNDPROC, MyWndProc)
def message_receiver(self): # Hidden window that can listen for messages self._logger.debug('Starting the message receiver') event_window = None try: hinst = win32api.GetModuleHandle(None) wndclass = win32gui.WNDCLASS() wndclass.hInstance = hinst wndclass.lpszClassName = "ListenerWindowClass" wndclass.lpfnWndProc = self.msg_handler event_window = None event_window_class = win32gui.RegisterClass(wndclass) event_window = win32gui.CreateWindowEx(0, event_window_class, "ListenerWindow", 0, 0, 0, 0, 0, win32con.HWND_MESSAGE, None, None, None) win32ts.WTSRegisterSessionNotification( event_window, win32ts.NOTIFY_FOR_ALL_SESSIONS) while not self._stop_event.is_set(): win32gui.PumpWaitingMessages() self._stop_event.wait(5) except Exception as e: self._logger.error("Exception while making message handler: %s", e) finally: win32ts.WTSUnRegisterSessionNotification(event_window) self._logger.debug('Exiting the message receiver')
def __init__(self, *args, **kwargs): QWidget.__init__(self, *args, **kwargs) # self.show() win32ts.WTSRegisterSessionNotification(self.winId(), win32ts.NOTIFY_FOR_ALL_SESSIONS) self.addMsgHandler(WM_WTSSESSION_CHANGE, self.on_session) self.hookWndProc()
def detect_win32_session_events(self, app_hwnd): """ Use pywin32 to receive session notification events. """ if app_hwnd is None: if self.tray_widget is None: #probably closing down, don't warn return log.warn("detect_win32_session_events(%s) missing handle!", app_hwnd) return try: debug("detect_win32_session_events(%s)", app_hwnd) #register our interest in those events: #http://timgolden.me.uk/python/win32_how_do_i/track-session-events.html#isenslogon #http://stackoverflow.com/questions/365058/detect-windows-logout-in-python #http://msdn.microsoft.com/en-us/library/aa383841.aspx #http://msdn.microsoft.com/en-us/library/aa383828.aspx win32ts.WTSRegisterSessionNotification( app_hwnd, win32ts.NOTIFY_FOR_THIS_SESSION) #catch all events: http://wiki.wxpython.org/HookingTheWndProc self.old_win32_proc = win32gui.SetWindowLong( app_hwnd, win32con.GWL_WNDPROC, self.MyWndProc) except Exception, e: log.error("failed to hook session notifications: %s", e)
def __init__(self, als): self._als = als wc = win32gui.WNDCLASS() wc.hInstance = hInst = win32gui.GetModuleHandle(None) wc.lpszClassName = self.CLASS_NAME wc.lpfnWndProc = self.WndProc self.classAtom = win32gui.RegisterClass(wc) self.hWnd = win32gui.CreateWindow(self.classAtom, self.WND_NAME, 0, 0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, 0, 0, hInst, None) win32gui.UpdateWindow(self.hWnd) win32ts.WTSRegisterSessionNotification(self.hWnd, win32ts.NOTIFY_FOR_ALL_SESSIONS)
def start( self ): # This is a blocking method and must be called in a separate thread window_class = win32gui.WNDCLASS() window_class.hInstance = win32gui.GetModuleHandle(None) window_class.lpszClassName = self.class_name window_class.lpfnWndProc = self.message_handler self.window = win32gui.CreateWindow( win32gui.RegisterClass(window_class), self.window_name, 0, 0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, 0, 0, window_class.hInstance, None) win32gui.UpdateWindow(self.window) win32ts.WTSRegisterSessionNotification(self.window, win32ts.NOTIFY_FOR_THIS_SESSION) win32gui.PumpMessages()
def __init__(self): wc = gui.WNDCLASS() wc.hInstance = hInst = api.GetModuleHandle(None) wc.lpszClassName = self.className wc.lpfnWndProc = self.WndProc self.classAtom = gui.RegisterClass(wc) style = 0 self.hWnd = gui.CreateWindow(self.classAtom, self.wndName, style, 0, 0, con.CW_USEDEFAULT, con.CW_USEDEFAULT, 0, 0, hInst, None) gui.UpdateWindow(self.hWnd) # you can optionally use ts.NOTIFY_FOR_ALL_SESSIONS ts.WTSRegisterSessionNotification(self.hWnd, ts.NOTIFY_FOR_THIS_SESSION)
def __init__(self, callBack=None): self.callBack = callBack self.className = "WTSMonitor" self.wndName = "WTS Event Monitor" wc = win32gui.WNDCLASS() wc.hInstance = hInst = win32gui.GetModuleHandle(None) wc.lpszClassName = self.className wc.lpfnWndProc = self.WndProc self.classAtom = win32gui.RegisterClass(wc) style = 0 self.hWnd = win32gui.CreateWindow(self.classAtom, self.wndName, style, 0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, 0, 0, hInst, None) win32gui.UpdateWindow(self.hWnd) win32ts.WTSRegisterSessionNotification(self.hWnd, win32ts.NOTIFY_FOR_ALL_SESSIONS)
def __init__(self, root, all_sessions=False): wc = gui.WNDCLASS() wc.hInstance = hInst = api.GetModuleHandle(None) wc.lpszClassName = self.className wc.lpfnWndProc = self.WndProc self.classAtom = gui.RegisterClass(wc) self.root = root style = 0 self.hWnd = gui.CreateWindow(self.classAtom, self.wndName, style, 0, 0, con.CW_USEDEFAULT, con.CW_USEDEFAULT, 0, 0, hInst, None) gui.UpdateWindow(self.hWnd) if all_sessions: scope = ts.NOTIFY_FOR_ALL_SESSIONS else: scope = ts.NOTIFY_FOR_THIS_SESSION ts.WTSRegisterSessionNotification(self.hWnd, scope)
def _register_listener(self): w_class_struct = win32gui.WNDCLASS() # From: https://docs.microsoft.com/en-us/windows/desktop/api/libloaderapi/nf-libloaderapi-getmodulehandlea # If this parameter is NULL, GetModuleHandle returns a handle # to the file used to create the calling process (.exe file). self.h_instance = w_class_struct.hInstance = win32api.GetModuleHandle( None) w_class_struct.lpszClassName = self._window_class w_class_struct.lpfnWndProc = self._window_procedure atom = win32gui.RegisterClass(w_class_struct) style = 0 self.h_window = win32gui.CreateWindow(atom, self._title, style, 0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, 0, 0, self.h_instance, None) win32gui.UpdateWindow(self.h_window) # scope = win32ts.NOTIFY_FOR_THIS_SESSION scope = win32ts.NOTIFY_FOR_ALL_SESSIONS win32ts.WTSRegisterSessionNotification(self.h_window, scope)