Jump to content
iXX

How to determine if computer is locked/unlocked?

Recommended Posts

iXX

Is here any command or script for finding out, if the workstation is currently locked or unlocked?

Share this post


Link to post
Share on other sites
Xenobiologist

Global Const $DESKTOP_ENUMERATE = 0x40
Global Const $SPI_GETSCREENSAVERRUNNING = 114
Global Const $DESKTOP_SWITCHDESKTOP = 0x100
HotKeySet("{ESC}", "_Terminate")
AdlibRegister("IsDeskTopLocked", 500)
While 1
Sleep(10)
WEnd
Func IsDeskTopLocked()
Local $p_lngHwnd, $p_lngRtn, $p_lngErr, $p_lngScreenSaver, $p_blnIsScreenSaver
;~    ' ------------------------------------------
;~    ' First check for screen saver one of 2 ways,
;~    '  based of OS
;~    ' ------------------------------------------
If @OSTYPE = "WIN32_WINDOWS" Then
;~     ' ---------------------------------------
;~     ' Pre W2K -- Note, will only be TRUE if
;~     '     the "Password Protected" box is
;~     '     checked.
;~     ' ---------------------------------------
  $p_lngHwnd = DllCall("user32.dll", "int", "OpenDesktopA", "str", "screen-saver", "int", 0, "int", False, "int", $DESKTOP_ENUMERATE)
  If $p_lngHwnd[0] <> 0 Then
   $p_blnIsScreenSaver = True
  Else
   $p_blnIsScreenSaver = False
  EndIf
Else
;~     ' ---------------------------------------
;~     ' W2K+ -- Will determine if screen saver
;~     '     is running whether or not the
;~     '     "Password Protected" box is checked
;~     ' ---------------------------------------
  $p_lngRtn = DllCall("user32.dll", "int", "SystemParametersInfoA", "int", $SPI_GETSCREENSAVERRUNNING, "int", 0, "int", $p_lngScreenSaver, "int", 0)
  If $p_lngRtn[0] = 0 Then
   ConsoleWrite("+>Error detecting screen saver" & @LF)
  Else
   $p_blnIsScreenSaver = $p_lngScreenSaver
  EndIf
EndIf
;~    ' ------------------------------------------
;~    ' If screen saver is *not* running, then
;~    '  check for locked workstation
;~    ' ------------------------------------------
If $p_blnIsScreenSaver Then
  If @OSTYPE = "WIN32_WINDOWS" Then
   ConsoleWrite("Screen saver is running..., Handle #" & $p_lngHwnd[0] & @LF)
   $p_lngHwnd = DllCall("user32.dll", "int", "CloseDesktop", "int", $p_lngHwnd[0])
  Else
   ConsoleWrite("Screen saver is running on W2K+" & @LF)
  EndIf
Else
  $p_lngHwnd = DllCall("user32.dll", "int", "OpenDesktopA", "str", "Default", "int", 0, "int", False, "int", $DESKTOP_SWITCHDESKTOP)
  If $p_lngHwnd[0] = 0 Then
   ConsoleWrite("Error with OpenDesktop" & @LF)
  Else
   $p_lngRtn = DllCall("user32.dll", "int", "SwitchDesktop", "int", $p_lngHwnd[0])
   $p_lngErr = _GetLastErrorMessage()
   If $p_lngRtn[0] = 0 Then
    If $p_lngErr = 0 Then
     ConsoleWrite("! Desktop is locked" & @LF)
    Else
     ConsoleWrite("Error with SwitchDesktop" & @LF)
    EndIf
   Else
    ConsoleWrite("Not locked!" & @LF)
   EndIf
   $p_lngHwnd = DllCall("user32.dll", "int", "CloseDesktop", "int", $p_lngHwnd[0])
  EndIf
EndIf
EndFunc   ;==>IsDeskTopLocked
Func _Terminate()
Exit
EndFunc   ;==>_Terminate
;===============================================
;    _GetLastErrorMessage($DisplayMsgBox="")
;    Format the last windows error as a string and return it
;    if $DisplayMsgBox <> "" Then it will display a message box w/ the error
;    Return     Window's error as a string
;===============================================
Func _GetLastErrorMessage($DisplayMsgBox = "")
Local $ret, $s
Local $p = DllStructCreate("char[4096]")
Local Const $FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
If @error Then Return ""
$ret = DllCall("Kernel32.dll", "int", "GetLastError")
$ret = DllCall("kernel32.dll", "int", "FormatMessage", _
   "int", $FORMAT_MESSAGE_FROM_SYSTEM, _
   "ptr", 0, _
   "int", $ret[0], _
   "int", 0, _
   "ptr", DllStructGetPtr($p), _
   "int", 4096, _
   "ptr", 0)
$s = DllStructGetData($p, 1)
If $DisplayMsgBox <> "" Then MsgBox(0, "_GetLastErrorMessage", $DisplayMsgBox & @CRLF & $s)
Return $s
EndFunc   ;==>_GetLastErrorMessage

While 1
Sleep(1000)
If _isWorksatationLocked() Then ConsoleWrite(@HOUR & ":" & @MIN & ":" & @SEC & " - " & "workstation locked" & @CRLF)
WEnd
Func _isWorksatationLocked()
If StringInStr(WinGetText(""), "Program Manager") <> 0 And WinGetTitle("") = "" Then Return 1
Return 0
EndFunc   ;==>_isWorksatationLocked

Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Share this post


Link to post
Share on other sites
iXX

ThanX, this works! :oops:

Share this post


Link to post
Share on other sites
LoWang

First example does not seem to work via psexec on WinXP SP3. Error with OpenDesktop always...tested on multiple machines.

Aha so I guess it just cannot work via psexec...otherwise it works and says "not locked". But then I don't really understand how you intended that it should be used :-]

Unfortunatelly neither example works for me :oops: I have tried the first one to run from a script running as system service and again Error with OpenDesktop. The second one does not work either. Any ideas?

Edited by LoWang

Share this post


Link to post
Share on other sites
LoWang

So I seem to have found a solution:

;compile as desktoplocked.exe
$res=0
$h=DllCall("User32.dll","int","OpenInputDesktop","int",0,"int",0,"int",0x0001)
if $h[0]=0 then $res=1
DllCall("user32.dll", "int", "CloseDesktop", "int", $h[0])
exit($res)  ;1=computer locked, 0=unlocked

but this needs to have access to desktop so either you can run it via psexec -i or schedule an interactive task via AT command or if you use a system service which does something on a computer and also periodically checks if computer is locked you can use something like this in it:

Func desktoplocked()
if not fileexists("c:windowspsexec.exe") then downloadutils()
$r=regread("HKEY_CURRENT_USERSoftwareSysinternalspsexec","EulaAccepted")
if not $r then regwrite("HKEY_CURRENT_USERSoftwareSysinternalspsexec","EulaAccepted","reg_dword",1)
$res=Runwait("c:windowspsexec.exe -i 0 c:windowsdesktoplocked.exe")  ;user seems to be always logged in session 0 so I am using this number
return $res
endfunc
Edited by LoWang

Share this post


Link to post
Share on other sites
MKANET

I'm still an autoit novice. I'm curious why there are two separate scripts listed (NOT the psexec modified ones, just the original two listed scripts). At first I thought that the first script was a UDF. But, that doesnt seem to be the case since the second script doesnt have an include for it.

I also tried combining both script snipets into one larger script and executing it; but, unfortunately there's no output from the script at all.

What am I doing wrong? Thanks in advance to help me get started!

Edit: I even tried making the first script as a UDF file called "locked.au3"; and, "#include "locked.au3" it from the second script. But, that doesn't work either.

Edited by MKANET

Share this post


Link to post
Share on other sites
MKANET

^Bump^ Maybe, there's a better way to detect if a workstation is locked? I dont use screensavers, so it's not as simple as detecting if the screensaver is running.

Edited by MKANET

Share this post


Link to post
Share on other sites
MKANET

Could someone please take a quick look at this? Im really struggling trying to figure out what I'm missing.

The other people in this thread were able to use the script(s). I'm just not sure how to use them. I'm guessing it's something very basic that I'm missing.

Share this post


Link to post
Share on other sites
guinness

Please stop bumping and showing little effort.

#include <APIConstants.au3>
#include <WinAPIEx.au3>

While 1
    If _IsLocked() Then
        ConsoleWrite('Workstation Is Locked.' & @CRLF)
    Else
        ConsoleWrite('Workstation Not Locked.' & @CRLF)
    EndIf
    Sleep(500)
WEnd

Func _IsLocked()
    Local $fIsLocked = False
    Local Const $hDesktop = _WinAPI_OpenDesktop('Default', $DESKTOP_SWITCHDESKTOP)
    If @error = 0 Then
        $fIsLocked = Not _WinAPI_SwitchDesktop($hDesktop)
        _WinAPI_CloseDesktop($hDesktop)
    EndIf
    Return $fIsLocked
EndFunc   ;==>_IsLocked
  • Like 1

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Share this post


Link to post
Share on other sites
MKANET

The problem I'm having all along is the script just hangs. It doesn't write to the console regardless if the desktop is locked or not. This happens with the script in the OP as well as the one from guinness. I was hoping someone might know why this is happening. I obviously wouldn't ask if I hadn't already tried everything I could think of to figure it out.

I dont have issues with running other autoit scripts. Both scripts below dont write any text to the console. They just produce the autoit system tray icon show shown below; and, the process stays in memory indefinitely until I kill it. I've tried it without compiling; running the au3 scripts by themselves. I've tried compiling them to exe's (both 64bit EXE and 32bit EXE). They all do the same thing.

I'm using Windows 7 64bit.

IsDesktopLocked.au3

#include <APIConstants.au3>
#include <WinAPIEx.au3>

While 1
Sleep(1000)
If _isWorksatationLocked() Then ConsoleWrite(@HOUR & ":" & @MIN & ":" & @SEC & " - " & "workstation locked" & @CRLF)
WEnd
Func _isWorksatationLocked()
If StringInStr(WinGetText(""), "Program Manager") <> 0 And WinGetTitle("") = "" Then Return 1
Return 0
EndFunc ;==>_isWorksatationLocked

IsDesktopLocked-2.au3

#include <APIConstants.au3>
#include <WinAPIEx.au3>

While 1
If _IsLocked() Then
ConsoleWrite('Workstation Is Locked.' & @CRLF)
Else
ConsoleWrite('Workstation Not Locked.' & @CRLF)
EndIf
Sleep(500)
WEnd

Func _IsLocked()
Local $fIsLocked = False
Local Const $hDesktop = _WinAPI_OpenDesktop('Default', $DESKTOP_SWITCHDESKTOP)
If @error = 0 Then
$fIsLocked = Not _WinAPI_SwitchDesktop($hDesktop)
_WinAPI_CloseDesktop($hDesktop)
EndIf
Return $fIsLocked
EndFunc ;==>_IsLocked

Posted Image

Edited by MKANET

Share this post


Link to post
Share on other sites
guinness

Well it works for me and I'm using the latest version of AutoIt.


UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Share this post


Link to post
Share on other sites
SlowCoder74

I know this thread is a little old, but I'm concurring that guinness' example works for me, under Windows 7 64bit, running Autoit 3.3.12.0, as user GUI (no psexec).

Share this post


Link to post
Share on other sites
BlueRabbit

I also needed to check whether my PC is unlocked or locked, but neither Xenobiologist' nor guinness' script worked for me. However, I found a pretty simple workaround: If the system is locked, no window will ever get active. So what I basically do is opening a arbitrary window, call WinActivate on that window and then check, if WinActive. If the window is not active, the system is locked. If if is active, the system is unlocked.

Here is my usecase, which works for me:

switchToHdmiAudio()

Func switchToHdmiAudio()
   If $activeDisplay = 1 Then
      ShellExecute("mmsys.cpl")
      waitUntilLoggedIn()
      WinWaitActive("Sound")
      Send("{DOWN}{DOWN}{DOWN}{DOWN}{TAB}{TAB}{ENTER}")
      Sleep(100)
      WinClose("Sound")
   EndIf
EndFunc

Func waitUntilLoggedIn()
   $DUR = 120
   For $i = 0 to $DUR Step +1
      WinActivate("Sound")
      If WinActive("Sound") Then ExitLoop
      Sleep(1000)
      If $i = $DUR Then
         Msgbox(16, $programName, "Aborted: Desktop locked!")
         Exit
      EndIf
   Next
EndFunc

 

Edited by BlueRabbit

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×