簡體   English   中英

在 Python 3 中,如何判斷 Windows 是否被鎖定?

[英]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()))

LockWorkStation()文檔

沒有可以調用的函數來確定工作站是否被鎖定。

不是 Python 限制,而是系統本身。

基於@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 跟蹤來做到這一點。

LockWorkStation() 文檔

沒有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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM