我有一个PyQt5应用程序,我想检查Windows工作站是否处于锁定状态。
首先,我尝试使用代码段See if my workstation is locked。它在我的Windows 7 64位上根本不起作用。它认为工作站一直处于锁定状态。
我在问题How to detect Windows is locked?中注意到上述解决方案可能是一个黑客,我应该使用WTSRegisterSessionNotification
。我找到了以下代码段Terminal Services event monitor for Windows NT/XP/2003/...。它可以正常使用。
我已将代码简化为以下内容:
import win32con
import win32gui
import win32ts
WM_WTSSESSION_CHANGE = 0x2B1
class WTSMonitor():
className = "WTSMonitor"
wndName = "WTS Event Monitor"
def __init__(self):
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 start(self):
win32gui.PumpMessages()
def stop(self):
win32gui.PostQuitMessage(0)
def WndProc(self, hWnd, message, wParam, lParam):
if message == WM_WTSSESSION_CHANGE:
self.OnSession(wParam, lParam)
def OnSession(self, event, sessionID):
print(event)
if __name__ == '__main__':
m = WTSMonitor()
m.start()
现在我正在尝试将其与PyQt5骨架合并:
import sys
from PyQt5.QtWidgets import *
class Window(QWidget):
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Window()
sys.exit(app.exec_())
但是,我不知道该怎么做。我所做的每一次尝试都不起作用,事件似乎没有登记。知道如何使这项工作吗?
修改 这是我尝试过的合并之一。
import sys
from PyQt5.QtWidgets import *
import win32gui
import win32ts
WM_WTSSESSION_CHANGE = 0x2B1
class WTSMonitor(QWidget):
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
self.show()
win32ts.WTSRegisterSessionNotification(self.winId(), win32ts.NOTIFY_FOR_ALL_SESSIONS)
def start(self):
win32gui.PumpMessages()
def stop(self):
win32gui.PostQuitMessage(0)
def WndProc(self, hWnd, message, wParam, lParam):
if message == WM_WTSSESSION_CHANGE:
self.OnSession(wParam, lParam)
def OnSession(self, event, sessionID):
print(event)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = WTSMonitor()
win.start()
sys.exit(app.exec_())
答案 0 :(得分:0)
我已将WndProcHookMixin.py上发布的wxPython wiki的想法改编为PyQt。它按预期工作。
import sys
from PyQt5.QtWidgets import *
import win32api
import win32con
import win32gui
import win32ts
WM_WTSSESSION_CHANGE = 0x2B1
WTS_SESSION_LOCK = 0x7
WTS_SESSION_UNLOCK = 0x8
# http://wiki.wxpython.org/HookingTheWndProc
# http://wiki.wxpython.org/HookingTheWndProc?action=AttachFile&do=view&target=WndProcHookMixin.py
# http://wiki.wxpython.org/HookingTheWndProc?action=AttachFile&do=view&target=WndProcHookMixinCtypes.py
class WndProcHookMixin:
def __init__(self):
self.msgDict = {}
def hookWndProc(self):
self.oldWndProc = win32gui.SetWindowLong(self.winId(), win32con.GWL_WNDPROC, self.localWndProc)
def unhookWndProc(self):
win32api.SetWindowLong(self.winId(), win32con.GWL_WNDPROC, self.oldWndProc)
def addMsgHandler(self, messageNumber, handler):
self.msgDict[messageNumber] = handler
def localWndProc(self, hWnd, msg, wParam, lParam):
if msg in self.msgDict:
if self.msgDict[msg](wParam, lParam) == False:
return
if msg == win32con.WM_DESTROY:
self.unhookWndProc()
return win32gui.CallWindowProc(self.oldWndProc, hWnd, msg, wParam, lParam)
class Window(QWidget, WndProcHookMixin):
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 on_session(self, wParam, lParam):
event, session_id = wParam, lParam
if event == WTS_SESSION_LOCK:
print("Locked")
if event == WTS_SESSION_UNLOCK:
print("Unlocked")
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Window()
sys.exit(app.exec_())