6

How can I check whether a Windows OS workstation is locked? (e.g. Win+L or choosing the lock option after Ctrl+Alt+Del.)

I want something like ctypes.windll.user32.isWorkstationLocked().

mrry
  • 123,190
  • 25
  • 396
  • 396
Ivan Baksheev
  • 61
  • 1
  • 4

8 Answers8

10

This code worked today for me on four different Windows 7 and 10 machines, try something similar:

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')

Edit: Also, this one works today:

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.")
macok
  • 101
  • 1
  • 4
4

You can get the window on top, when the session is locked, the function return 0.

import ctypes
user32 = ctypes.windll.User32

def isLocked():
    return user32.GetForegroundWindow() == 0
TheDelta
  • 128
  • 11
  • 3
    This is false for me in Windows 10 Pro. When locked, the hwnd process ID is a changing number with the title "Windows Default Lock Screen". It's only hwnd == 0 when I press Enter to put the password in. I used a few lines from this example to fetch the title and compare it to either 0, "", or the title above. http://pixomania.net/programming/python-getting-the-title-of-windows-getting-their-processes-and-their-commandlines-using-ctypes-and-win32/ – James Koss Oct 13 '18 at 13:34
  • @JamesKoss try the solution below this one, it worked for me. – Danielle Dec 19 '18 at 03:49
4

A hacky I discovered to get around to see if Windows 10 is locked is to look at the running processes using psutil. You then search to see if LogonUI.exe is running. This process only runs if there when a user has a locked session.

Note: If you use switch users this process will show as running and this workaround will not work. Windows actually spawns multiple LogonUI.exe processes, one per logged on locked user. It is only useful where only one person is logged on at a time.

import psutil

for proc in psutil.process_iter():
    if(proc.name() == "LogonUI.exe"):
        print ("Locked")
3

Something like this should do the trick:

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)
TacomenX
  • 31
  • 1
  • 3
  • 1
    @IvanBaksheev, are you using Python 3? This should be written to use `OpenDesktopW` and the explicit unicode literal `u"Default"`. – Eryk Sun Dec 30 '15 at 22:31
  • Note that the "Default" desktop may not be the active application desktop, so switching to it is a side effect. I don't know how to get the current application desktop. `OpenInputDesktop` tries to open the active desktop, but that could be "Winlogon" if the workstation is locked (requires SYSTEM). It's not telling us what the WindowStation's active *application* desktop is. winlogon.exe tracks this, but I don't know an API to query it. – Eryk Sun Dec 30 '15 at 22:32
1

From the LockWorkStation() documentation:

There is no function you can call to determine whether the workstation is locked.

Not a Python limitation, but the system itself.

cdonts
  • 8,768
  • 2
  • 41
  • 69
1

What works for me on Windows 10 Pro is getting the foreground window:

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)

This returns Windows Default Lock Screen as window title and C:\Windows\SystemApp\Microsoft.LockApp_<randomcharacters>\LockApp.exe as filename when locked.

However, as James Koss mentioned, GetForeGroundWindow will return 0 if the user is typing their password. There are also other (non-locked) situations where the current ForegroundWindow is 0, so this cannot be relied upon.

Stardidi
  • 198
  • 1
  • 10
1

Hi Check these 4 lines..

returns the application name which is on the screen.. if window is locked returns the string - Windows Default Lock Screen.

from win32gui import GetWindowText, GetForegroundWindow
import time
time.sleep(5)
# lock the system or open the application for a check
print(GetWindowText(GetForegroundWindow()))
Hietsh Kumar
  • 989
  • 7
  • 15
0

Based on @Stardidi answer, this worked for me (Windows 10 Pro):

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"