Detect when Windows screen lock/password is active

Get help with using AutoHotkey and its commands and hotkeys
momo2000
Posts: 32
Joined: 25 Jan 2015, 12:00

Detect when Windows screen lock/password is active

04 Jun 2015, 12:21

Can AHK detect when the windows screen has been locked AND unlocked? Password screen lock, I’m talking about. Is there some kind of function? I've searched but don't see anything.

USE CASE: This computer is in a public place, so I need for a tour guide to be able to use the keyboard to unlock the computer, but then after the screen is unlocked, I want to detect that and disable the keyboard. Then the public can only use the mouse to interact. Then when done, the tour guide will hit Windowskey+L and lock the screen again, but I need to detect that so I can make the the keyboard is active again, so that the tour guide can enter the password again (at a later time).
momo2000
Posts: 32
Joined: 25 Jan 2015, 12:00

Re: Detect when Windows screen lock/password is active

04 Jun 2015, 13:50

Well in re-reading my description, I realize there is an error. When the public is done and the tour guide would hit Windowskey+L to lock the computer. . . . they wouldn't be able to if ALL keyboard interaction was blocked, my mistake. SO, there would have to be some way (keyboard keystroke, or mouse click sequence) to simulate a Windowskey+L (or if those keys worked) so the screen lock would work. Thanks.
User avatar
Nextron
Posts: 1363
Joined: 01 Oct 2013, 08:23
Location: Netherlands OS: Win7 x64 AHK: Unicode x32

Re: Detect when Windows screen lock/password is active

04 Jun 2015, 17:14

This locks the workstation: DllCall("LockWorkStation"). You could make it a separate script you can execute by double clicking the mouse, but then you could just as easily create a shortcut to rundll32.exe user32.dll,LockWorkStation to lock the workstation. But you could also make it a mouse button combination, like: XButton2 & XButton1::DllCall("LockWorkStation").

To check is the workstation is locked I use this function, but again you could just use the DllCall:

Code: Select all

WorkstationIsLocked(){
	Return !DllCall("User32\OpenInputDesktop","int",0*0,"int",0*0,"int",0x0001L*1)
}
The downside is you need to repeatedly check if the state changed, so this is better, which is automatically called upon session change:

Code: Select all

WM_WTSSESSION_CHANGE(wParam, lParam, Msg, hWnd){
	static init:=(DllCall( "Wtsapi32.dll\WTSRegisterSessionNotification", UInt, A_ScriptHwnd, UInt, 1) && OnMessage(0x02B1, "WM_WTSSESSION_CHANGE"))
	
	If (wParam=0x6 || wParam=0x7){ ;Logoff or lock
		Run, powercfg -change -monitor-timeout-ac 1,,Hide ;Set monitor standby timeout to 1 minute
		SendMessage,0x112,0xF170,2,,Program Manager ;Monitor Standby
	}Else If (wParam=0x5 || wParam=0x8){ ;Logon or unlock
		Run, powercfg -change -monitor-timeout-ac 20,,Hide ;Set monitor standby timeout to 20 minutes
	}

		
			/*
			wParam::::::
			WTS_CONSOLE_CONNECT := 0x1 ; A session was connected to the console terminal.
			WTS_CONSOLE_DISCONNECT := 0x2 ; A session was disconnected from the console terminal.
			WTS_REMOTE_CONNECT := 0x3 ; A session was connected to the remote terminal.
			WTS_REMOTE_DISCONNECT := 0x4 ; A session was disconnected from the remote terminal.
			WTS_SESSION_LOGON := 0x5 ; A user has logged on to the session.
			WTS_SESSION_LOGOFF := 0x6 ; A user has logged off the session.
			WTS_SESSION_LOCK := 0x7 ; A session has been locked.
			WTS_SESSION_UNLOCK := 0x8 ; A session has been unlocked.
			WTS_SESSION_REMOTE_CONTROL := 0x9 ; A session has changed its remote controlled status. To determine the status, call GetSystemMetrics and check the SM_REMOTECONTROL metric.
			*/
}
I use it to put my monitors in standby and temporarily change to standby timeout to its minimum in the event a disturbance to the mouse wakes them up. You can easily add BlockInputs to those. Do remember the login screen is a special secure desktop with which interaction it not so straight forward. I doubt that blocking the input in the user session also blocks input for the login screen.
sierratango

Re: Detect when Windows screen lock/password is active

28 Nov 2015, 18:58

Does

Code: Select all

DllCall("User32\OpenInputDesktop","int",0*0,"int",0*0,"int",0x0001L*1)
still work for anybody on Windows 10? It doesn't for me. Wondering if anybody knows the updated code to get it to work again.
sierratango

Re: Detect when Windows screen lock/password is active

03 Jan 2016, 01:13

Well after coming back to this and testing it some more with Windows 10 I have concluded that the code does still work but not as well as previous Windows versions. The problem is that the code doesn't apply to the lock screen "curtain shade", only the actual lock screen where you enter your password.
sierratango

Re: Detect when Windows screen lock/password is active

03 Jan 2016, 17:26

This works reliably for me now:

Code: Select all

Sleep, 5000
CoordMode, Pixel, Screen
PixelGetColor, TaskbarColor, 3599, 1049

While (TaskbarColor != 0x151515) {
	Sleep, 3000
	PixelGetColor, TaskbarColor, 3599, 1049
}
Soundbeep,,1000
Msgbox, Unlocked
momo2000
Posts: 32
Joined: 25 Jan 2015, 12:00

Re: Detect when Windows screen lock/password is active

12 Mar 2016, 13:42

sierratango: thanks! appreciate you updating the thread with the W10 working solution.
HIACliff

Re: Detect when Windows screen lock/password is active

17 Mar 2017, 10:27

Nextron's second bit of code was more elegant to begin with, and continues to work on Windows 10.

The workaround of checking the taskbar color doesn't always work, depending on your monitor configuration and Windows theme.
kahbatron

Re: Detect when Windows screen lock/password is active

17 Mar 2017, 17:18

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.

SessionIsLocked()
{
	static WTS_CURRENT_SERVER_HANDLE := 0, WTSSessionInfoEx := 25, WTS_SESSIONSTATE_LOCK := 0x00000000, WTS_SESSIONSTATE_UNLOCK := 0x00000001 ;, WTS_SESSIONSTATE_UNKNOWN := 0xFFFFFFFF
	ret := False

	if (DllCall("ProcessIdToSessionId", "UInt", DllCall("GetCurrentProcessId", "UInt"), "UInt*", sessionId)
	 && DllCall("wtsapi32\WTSQuerySessionInformation", "Ptr", WTS_CURRENT_SERVER_HANDLE, "UInt", sessionId, "UInt", WTSSessionInfoEx, "Ptr*", sesInfo, "Ptr*", BytesReturned)) {
		SessionFlags := NumGet(sesInfo+0, 16, "Int")
		; "Windows Server 2008 R2 and Windows 7: Due to a code defect, the usage of the WTS_SESSIONSTATE_LOCK and WTS_SESSIONSTATE_UNLOCK flags is reversed."
		ret := A_OSVersion != "WIN_7" ? SessionFlags == WTS_SESSIONSTATE_LOCK : SessionFlags == WTS_SESSIONSTATE_UNLOCK
		DllCall("wtsapi32\WTSFreeMemory", "Ptr", sesInfo)
	}

	return ret
}

MsgBox % SessionIsLocked()
User avatar
Don
Posts: 2
Joined: 31 Aug 2014, 14:42

Re: Detect when Windows screen lock/password is active

28 Mar 2018, 17:17

On Win10, I found the same as sierratango with the 'WorkstationIsLocked' function.

The SessionIsLocked function from kahbatron worked the way I expected! thank you! :)
User avatar
danielocdh
Posts: 3
Joined: 01 Jul 2018, 18:42

Re: Detect when Windows screen lock/password is active

01 Jul 2018, 18:48

None of the solutions worked for me on windows 10 1703, maybe it has something to do with me only having remote access via remote desktop connection, disconnecting from the remote desktop connection does lock windows but maybe there is something different done

Return to “Ask For Help”

Who is online

Users browsing this forum: Bing [Bot], Odlanir and 215 guests