Sign in to follow this  
Followers 0
Eleasar

Closing a Programm when Windows is locked

10 posts in this topic

Hi,

i did search for a way to close a specific program (just sending ALT+F4 or specific key combination) to a program when windows (Windows 7) is locked. I was not able to find an example on how to achieve this. If anyone got one that would be great! If it helps i always lock the computer with the windows-key+L.

Thanks in advance ;)

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Detecting if windows session is locked:

http://www.winvistatips.com/wmi-do-detect-windows-session-locked-t755964.html

Terminating a running process (or program)

See ProcessClose in the help file.

A little Google goes a long way.

----Edit----

This might also help

http://www.autoitscript.com/forum/index.php?showtopic=63317

Edited by willichan

Share this post


Link to post
Share on other sites

Ok thanks! After your link i found the correct words to search for and found the following very small construct that did the job:

While True
    Sleep(1000)
    If ProcessExists("logonui.exe") then
        MsgBox(0, "Details", "locked")
    EndIf
WEnd

Not sure if i should ask in a new thread but i got the following problem testing with Evernote (should finally work with trillian, evernote and maybe a few more programms). It closes notepad just fine but not evernote. Evernote is handling the close action differently (right click in taskbar > close or on the red X) - it will just hide itself - but not even this is working from autoit.

Only with (manual) key command CTRL+Q it will really close. Sending this command to Evernote is not working even in non-locked state.

And when Evernote is minimized the WinList will not find it either...

This is my program so far:

;#requireadmin
Opt("WinTitleMatchMode", 2)

While True
    Sleep(1000)
    If ProcessExists("logonui.exe") then
        ;CloseProgram("Notepad")
        Sleep(1000)
        CloseProgram("Evernote")
        ;MsgBox(0, "Details", "locked")
    EndIf
WEnd

Func CloseProgram($name)
    $var = WinList($name)
    For $i = 1 to $var[0][0]
      ; Only display visble windows that have a title
      If $var[$i][0] <> "" AND IsVisible($var[$i][1]) Then
        WinActivate($var[$i][1])
        Sleep(500)
        Send("!{F4}")
        Send("^Q")
        WinClose($var[$i][1])
        ;Send("^q")
        ;WinClose($var[$i][1])
        ;WinKill($var[$i][1])
        ;MsgBox(0, "Details", "Title=" & $var[$i][0] & @LF & "Handle=" & $var[$i][1])
        ;ProcessClose("evernote.exe")
      EndIf
    Next
EndFunc

Func IsVisible($handle)
  If BitAnd( WinGetState($handle), 2 ) Then 
    Return 1
  Else
    Return 0
  EndIf
EndFunc

Share this post


Link to post
Share on other sites

After some more testing and looking through the forum i found the task bar method to find an icon and click that, navigate once up and hit enter which effectively closes Evernote. But when windows is locked it seems that this is not working (would make sense):

#Include <GuiToolBar.au3>
AutoItSetOption("WinTitleMatchMode", 2)
#NoTrayIcon
Global $hSysTray_Handle, $iSystray_ButtonNumber
Global $sToolTipTitle = "Evernote" ; <<<<<<<<<<<<<<<< Enter some tooltip text for the icon you want here


While True
    Sleep(100)
    If ProcessExists("logonui.exe") then
        $iSystray_ButtonNumber = Get_Systray_Index($sToolTipTitle)

        If $iSystray_ButtonNumber = -1 Then
            MsgBox(16, "Error", "Icon not found in system tray")
            Exit
        Else
            ;Sleep(500)
            WinActivate('[Class:Shell_TrayWnd]')
            _GUICtrlToolbar_ClickButton($hSysTray_Handle, $iSystray_ButtonNumber, "right", True, 1, 0)
            Send("{UP}")
            Send("{ENTER}")
            MsgBox(0, "Success", "program closed")
        EndIf

        Exit        
    EndIf
WEnd



Func Get_Systray_Index($sToolTipTitle)

    ; Find systray handle
    $hSysTray_Handle = ControlGetHandle("[Class:Shell_TrayWnd]", "", "[Class:ToolbarWindow32;Instance:1]")
    If @error Then
        MsgBox(16, "Error", "System tray not found")
        Exit
    EndIf

    ; Get systray item count
    Local $iSystray_ButCount = _GUICtrlToolbar_ButtonCount($hSysTray_Handle)
    If $iSystray_ButCount = 0 Then
        MsgBox(16, "Error", "No items found in system tray")
        Exit
    EndIf

    ; Look for wanted tooltip
    ;For $iSystray_ButtonNumber = 0 To $iSystray_ButCount - 1 =========== "OLD" instruction
    For $iSystray_ButtonNumber = 1 To $iSystray_ButCount  ; =========== MODIFIED instruction
         If StringInStr(_GUICtrlToolbar_GetButtonText($hSysTray_Handle, $iSystray_ButtonNumber), $sToolTipTitle) = 1 Then ExitLoop
    Next

    ;If $iSystray_ButtonNumber = $iSystray_ButCount Then ;=========== "OLD" instruction
    If $iSystray_ButtonNumber = $iSystray_ButCount + 1 Then ; =========== MODIFIED instruction
        Return 0 ; Not found
    Else
        Return $iSystray_ButtonNumber ; Found
    EndIf

EndFunc

Had to set Evernote to always show its icon for it to work.

Any idea on how to still get this working even though the Computer is then locked?

Share this post


Link to post
Share on other sites

Just a quick note: The presence of 'logonui.exe' doesn't mean the session is locked, especially on Windows Vista+. Hit Ctrl-Alt-Del and 'logonui.exe' runs, but you aren't logged out, nor is the session locked - the O/S brings you to a screen of choices (like 'Start Task Manager', 'Log Off', 'Change a password', etc).

One way to get around this is to use WTSRegisterSessionNotification, WTSUnRegisterSessionNotification, and the WM_WTSSESSION_CHANGE notification. I've used these myself successfully, and was able to detect the various changes in session activity.

Share this post


Link to post
Share on other sites

One way to get around this is to use WTSRegisterSessionNotification, WTSUnRegisterSessionNotification, and the WM_WTSSESSION_CHANGE notification. I've used these myself successfully, and was able to detect the various changes in session activity.

Can you please share the code snippet with us?

[size="2"][font="arial, verdana, tahoma, sans-serif"]ProtectData - A Data Protection software for floppies[/font][/size] [size="2"][hr][/size][size="2"]Sessionchange - A Windows service capable of tracking session change events[/size][size="2"][b][/b][/size]

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Took me a minute to find it.. but here ya go:

; ===============================================================================================================================
; <LogOnOffFunctionsTest.au3>
;
; Author: Ascend4nt
; ===============================================================================================================================

#include <Misc.au3>
$hGUI=GUICreate("MyGUI",100,100)
;~ GUISetState($hGUI,@SW_HIDE)
ConsoleWrite("Phantom GUI Created:"&$hGUI&@CRLF)

$bLogonUIActive=False
$bSuccess=_LogOnOffRegister($hGUI,"_MY_WM_WTSSESSION_CHANGE")
ConsoleWrite("LogOnOffRegister return:"&$bSuccess&", @error="&@error&", @extended="&@extended&@CRLF)
While 1
    If _IsPressed("1B") Then ExitLoop   ; Exit on 'ESC' keypress
    If ProcessExists("logonui.exe") Then
        If Not $bLogonUIActive Then
            $bLogonUIActive=True
            ConsoleWrite("Logon UI interface is active, but session isn't necessarily locked"&@CRLF)
        EndIf
    ElseIf $bLogonUIActive Then
        ConsoleWrite("Logon UI interface is no longer active"&@CRLF)
        $bLogonUIActive=False
    EndIf
    Sleep(10)
WEnd
$bSuccess=_LogOnOffRegister($hGUI,"")
ConsoleWrite("LogOnOffRegister return:"&$bSuccess&", @error="&@error&", @extended="&@extended&@CRLF)



; ===================================================================================================================
; Func _LogOnOffRegister($hWnd,$sFunc)
;
; Register/Unregisters callback for Session-change notifications
;
; Author: Ascend4nt
; ===================================================================================================================

Func _LogOnOffRegister($hWnd,$sFunc)
    If Not IsHWnd($hWnd) Then Return SetError(1,0,False)
    Local $aRet,$iErr

;   UnRegistering?
    If $sFunc="" Then
        $aRet=DllCall("wtsapi32.dll","bool","WTSUnRegisterSessionNotification","hwnd",$hWnd)
        $iErr=@error
        ; WM_WTSSESSION_CHANGE = 0x02B1
        GUIRegisterMsg(0x02B1,"")
        If $iErr Then Return SetError(2,$iErr,False)
        If Not $aRet[0] Then Return SetError(3,0,False)
        Return True
    EndIf

;   Registering New

    ; WM_WTSSESSION_CHANGE = 0x02B1
    If Not GUIRegisterMsg(0x02B1,$sFunc) Then Return SetError(1,0,False)
    $aRet=DllCall("wtsapi32.dll","bool","WTSRegisterSessionNotification","hwnd",$hWnd,"dword",0)
    If @error Or Not $aRet[0] Then
        $iErr=@error
        GUIRegisterMsg(0x02B1,"")
        If $iErr Then Return SetError(2,$iErr,False)
        Return SetError(3,0,False)
    EndIf
    Return True
EndFunc


; ===================================================================================================================
; Func _MY_WM_WTSSESSION_CHANGE($hWnd,$vMsg,$wParam,$lParam)
;
; WM_WTSSession_Change callback
;
; Author: Ascend4nt
; ===================================================================================================================

Func _MY_WM_WTSSESSION_CHANGE($hWnd,$vMsg,$wParam,$lParam)
    ; 'Session was Disconnected from/Connected to the Console Terminal' = User switching
    Dim $aMsgs[9]=["Session was Connected to the Console Terminal","Session was Disconnected from the Console Terminal", _
        "Session was Connected to the Remote Terminal","Session was Disconnected from the Remote Terminal", _
        "User logged on to session","User logged off session","Session has been locked","Session has been unlocked", _
        "Session changed its remote control status"]
    ConsoleWrite("Session Change notification received (0x"&Hex($vMsg,4)&"). Window receiving Session Change notification:"&$hWnd&@CRLF)
    $wParam=Number($wParam)
    $lParam=Number($lParam)
    If $wParam>0 And $wParam<10 Then
        ConsoleWrite("Message (ID # "&$wParam&") received: '"&$aMsgs[$wParam-1]&"'"&@CRLF)
    Else
        ConsoleWrite("Unknown message received: ID # "&$wParam&@CRLF)
    EndIf
    ConsoleWrite("Message originated from session # "&$lParam&@CRLF)
    Return 'GUI_RUNDEFMSG'  ; $GUI_RUNDEFMSG from <GUIConstantsEx.au3>
EndFunc
Edited by Ascend4nt

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Took me a minute to find it.. but here ya go:

Thank you Ascend4nt. But, the problem is I'm coding a Windows service using where I'm not supposed to create a GUI & thereby can't trap events using WTSRegisterSessionNotification. Instead, this page says that

To receive session change notifications from a service, use the HandlerEx function.

Can you or anybody please help in implementing HandlerEx as I'm lacking in knowledge to play with Windows API ?

Edited by HolmesShelock

[size="2"][font="arial, verdana, tahoma, sans-serif"]ProtectData - A Data Protection software for floppies[/font][/size] [size="2"][hr][/size][size="2"]Sessionchange - A Windows service capable of tracking session change events[/size][size="2"][b][/b][/size]

Share this post


Link to post
Share on other sites

Holmes, I don't work with Service-level stuff, so I can't help you really, other than telling you to pay attention to the DLLCall() structure, to use 'RegisterServiceCtrlHandlerEx' to register your HandlerEx callback, to use the correct params in that callback definition, and to follow the MSDN guidelines. (it says that "The RegisterServiceCtrlHandlerEx function must be called before the first SetServiceStatus").

If you can't figure this stuff out on your own, starting a new thread might be the best idea.

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
Sign in to follow this  
Followers 0