[英]In Python 3, how can I tell if Windows is locked?
如何檢查 Windows 操作系統工作站是否被鎖定? (例如 Win+L 或在 Ctrl+Alt+Del 之后選擇鎖定選項。)
我想要像ctypes.windll.user32.isWorkstationLocked()
這樣的東西。
這段代碼今天在四台不同的 Windows 7 和 10 機器上對我有用,嘗試類似的東西:
import ctypes
import time
user32 = ctypes.windll.User32
time.sleep(5)
#
#print(user32.GetForegroundWindow())
#
if (user32.GetForegroundWindow() % 10 == 0): print('Locked')
# 10553666 - return code for unlocked workstation1
# 0 - return code for locked workstation1
#
# 132782 - return code for unlocked workstation2
# 67370 - return code for locked workstation2
#
# 3216806 - return code for unlocked workstation3
# 1901390 - return code for locked workstation3
#
# 197944 - return code for unlocked workstation4
# 0 - return code for locked workstation4
#
else: print('Unlocked')
編輯:另外,這個今天有效:
import subprocess
import time
time.sleep(5)
process_name='LogonUI.exe'
callall='TASKLIST'
outputall=subprocess.check_output(callall)
outputstringall=str(outputall)
if process_name in outputstringall:
print("Locked.")
else:
print("Unlocked.")
您可以在頂部獲取窗口,當會話被鎖定時,該函數返回 0。
import ctypes
user32 = ctypes.windll.User32
def isLocked():
return user32.GetForegroundWindow() == 0
我發現要查看 Windows 10 是否被鎖定的一個技巧是使用 psutil 查看正在運行的進程。 然后搜索以查看 LogonUI.exe 是否正在運行。 此過程僅在用戶鎖定會話時運行。
注意:如果您使用切換用戶,此過程將顯示為正在運行,並且此解決方法將不起作用。 Windows 實際上會生成多個 LogonUI.exe 進程,每個登錄的鎖定用戶一個。 它僅在一次只有一個人登錄的情況下有用。
import psutil
for proc in psutil.process_iter():
if(proc.name() == "LogonUI.exe"):
print ("Locked")
像這樣的事情應該可以解決問題:
import time
import ctypes
user32 = ctypes.windll.User32
OpenDesktop = user32.OpenDesktopA
SwitchDesktop = user32.SwitchDesktop
DESKTOP_SWITCHDESKTOP = 0x0100
while 1:
hDesktop = OpenDesktop ("default", 0, False, DESKTOP_SWITCHDESKTOP)
result = SwitchDesktop (hDesktop)
if result:
print "Unlocked"
time.sleep (1.0)
else:
print time.asctime (), "still locked"
time.sleep (2)
在 Windows 10 Pro 上對我有用的是獲取前景窗口:
whnd = win32gui.GetForegroundWindow()
(_, pid) = win32process.GetWindowThreadProcessId(whnd)
handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, False, pid)
filename = win32process.GetModuleFileNameEx(handle, 0)
window_text = win32gui.GetWindowText(whnd)
這將返回Windows Default Lock Screen
作為窗口標題和C:\\Windows\\SystemApp\\Microsoft.LockApp_<randomcharacters>\\LockApp.exe
作為鎖定時的文件名。
但是,正如 James Koss 所提到的,如果用戶輸入密碼,GetForeGroundWindow 將返回 0。 還有其他(非鎖定)情況,當前 ForegroundWindow 為 0,因此不能依賴。
嗨檢查這4行..
返回屏幕上的應用程序名稱。如果窗口被鎖定,則返回字符串 - Windows 默認鎖定屏幕。
from win32gui import GetWindowText, GetForegroundWindow
import time
time.sleep(5)
# lock the system or open the application for a check
print(GetWindowText(GetForegroundWindow()))
基於@Stardidi 的回答,這對我有用(Windows 10 專業版):
import time
import win32gui
import win32api
import win32con
import win32process
while True:
time.sleep(1)
_, pid = win32process.GetWindowThreadProcessId(win32gui.GetForegroundWindow())
try:
handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, False, pid)
filename = win32process.GetModuleFileNameEx(handle, 0)
except Exception as _e:
filename = "LockApp.exe"
del _e
current_status = "locked" if "LockApp" in filename else "unlocked"
這里沒有簡單的答案,但您可以通過 Session 跟蹤來做到這一點。
沒有function可以打電話判斷工作站是否被鎖。 要在用戶登錄時接收通知,請使用WTSRegisterSessionNotification function 來接收WM_WTSSESSION_CHANGE消息。 您可以使用 session 通知來跟蹤桌面 state 以便您知道是否可以與用戶交互。
首先將 session 通知注冊到程序的 window。
def register(handle: HWND) -> bool:
"""
@param handle: handle for your message window.
When registered, Windows Messages related to session event changes will be
sent to the message window.
@returns: True is session tracking is successfully registered.
Blocks until Windows accepts session tracking registration.
Every call to this function must be paired with a call to unregister.
https://docs.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-wtsregistersessionnotification
"""
# OpenEvent handle must be closed with CloseHandle.
eventObjectHandle: HANDLE = ctypes.windll.kernel32.OpenEventW(
# Blocks until WTS session tracking can be registered.
# Windows needs time for the WTS session tracking service to initialize.
# must ensure that the WTS session tracking service is ready before trying to register
SYNCHRONIZE, # DWORD dwDesiredAccess
False, # BOOL bInheritHandle - sub-processes do not need to inherit this handle
# According to the docs, when the Global\TermSrvReadyEvent global event is set,
# all dependent services have started and WTSRegisterSessionNotification can be successfully called.
# https://docs.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-wtsregistersessionnotification#remarks
"Global\\TermSrvReadyEvent" # LPCWSTR lpName - The name of the event object.
)
if not eventObjectHandle:
error = ctypes.WinError()
log.error("Unexpected error waiting to register session tracking.")
return False
registrationSuccess = ctypes.windll.wtsapi32.WTSRegisterSessionNotification(handle, NOTIFY_FOR_THIS_SESSION)
ctypes.windll.kernel32.CloseHandle(eventObjectHandle)
if registrationSuccess:
log.debug("Registered session tracking")
else:
error = ctypes.WinError()
if error.errno == RPC_S_INVALID_BINDING:
log.error(
"WTS registration failed. "
"Waited successfully on TermSrvReadyEvent to ensure that WTS is ready to allow registration. "
"Cause of failure unknown. "
)
else:
log.error("Unexpected error registering session tracking.")
return registrationSuccess
def unregister(handle: HWND) -> None:
"""
This function must be called once for every call to register.
If unregistration fails, session tracking may not work properly until the session can be unregistered in a new instance.
https://docs.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-wtsunregistersessionnotification
"""
if ctypes.windll.wtsapi32.WTSUnRegisterSessionNotification(handle):
log.debug("Unregistered session tracking")
else:
error = ctypes.WinError()
log.error("Unexpected error unregistering session tracking.")
In your Window Message handler for the window, when you receive WM_WTSSESSION_CHANGE
, handle WTS_SESSION_UNLOCK
and WTS_SESSION_LOCK
events to track the state of Windows being locked.
此處類似的答案可能會提供有關處理 windows 消息的更多上下文。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.