Что нового

[Файловая система] Запуск программы при блокировке/разблокировке системы

Iniar

Новичок
Сообщения
9
Репутация
0
Здравствуйте.
Прошу помощи у знающих ибо уже дальше моих познаний не хватает.
Задача:
Необходим скрипт который бы проверял заблокировал ли пользователь компьютер или разблокировал и при каждом этом действии запускал Bat файл который бы в свою очередь записывал в файл текущую дату и время блокировки/разблокировки (и желательно входа/выхода пользователя).
Запись в файл должна производиться построчно. То есть не затирая старые записи.


Поиски в гуглах и яндексах не помогли ибо там по моим запросам выдаётся столько воды, что мозг закипает только от просмотра...
Нашёл вот что:
Код:
Global Const $DESKTOP_SWITCHDESKTOP = 0x100

Func _CheckLocked()
    $hLockedDLL = DllOpen("user32.dll")
    $hDesktop = DllCall($hLockedDLL, "int", "OpenDesktop", "str", "Default", "int", 0, "int", 0, "int", $DESKTOP_SWITCHDESKTOP)
    $ret = DllCall($hLockedDLL, "int", "SwitchDesktop", "int", $hDesktop[0])
    DllCall($hLockedDLL, "int", "CloseDesktop", "int", $hDesktop[0])

    If $ret[0] = 0 Then
        $iLocked = 1
    ElseIf $ret[0] = 1 Then
        $iLocked = 0
    EndIf

    DllClose($hLockedDLL)

    If $iLocked Then
        Return 1
    Else
        Return 0
	 EndIf

While Not $iLocked = 1
   MsgBox(32, "Error", "некое сообщение")
WEnd
EndFunc

Красным обвёл то, что попытался добавить для проверки работы скрипта. При выполнении в трее на секунду появляется значок скрипта и тут же закрывается. Сообщение не выводится. Попробовал уже во все варианты if добавить сообщение... Результат один - секунда значка в трее и более ничего.
Позже нашёл ещё:
Код:
; Detect if System is Locked

Global Const $DESKTOP_ENUMERATE = 0x40
Global Const $SPI_GETSCREENSAVERRUNNING = 114
Global Const $DESKTOP_SWITCHDESKTOP = 0x100

HotKeySet("{ESC}", "_Terminate")

AdlibEnable("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
Но это для меня пока немного сложно и при выполнении выдаёт ошибку -
Код:
AdlibEnable("IsDeskTopLocked", 500)
^ ERROR

Так же столкнулся с проблемой, что при компиляции обоих скриптов выпадает ошибка - "Error:Error copying cource to destination file." Ниже путь к предполагаемому файлу exe. Что за проблема при компиляции?

Как можно реализовать мою задачу? Возможно запись даты и времени можно реализовать и в AutoIt' е. Прошу помощи.
Дополнение к задаче:
Ещё желательно бы записывать напротив даты и времени пользователя который зашёл/вышел/разблокировал/заблокировал...

Используйте для AutoIt кода тег [autoit]
autoit.gif

madmasles.
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
Если скрипт скомпилировать и добавить в автозагрузку пользователя, то старт/стоп фактически будет фиксировать вход/выход
Код:
#include <WinAPISys.au3>

OnAutoItExitRegister("OnExit")

Global $Locked, $LogFile = @ScriptDir & "\log.txt"

FileWriteLine($LogFile, @UserName & ": старт " & Now())

Do
  If $Locked <> IsLocked() Then
    Switch $Locked
      Case 0
        FileWriteLine($LogFile, @UserName & ": заблокирован  " & Now())
      Case 1
        FileWriteLine($LogFile, @UserName & ": разблокирован " & Now())
    EndSwitch
    $Locked = Not $Locked
  EndIf
  Sleep(1000)
Until 0

Func IsLocked()
  $hDesktop = _WinAPI_OpenDesktop("Default", $DESKTOP_SWITCHDESKTOP)
  $Result = _WinAPI_SwitchDesktop($hDesktop)
  _WinAPI_CloseDesktop($hDesktop)
  Return Not $Result
EndFunc

Func Now()
  Return @MDAY & "." & @MON & " " & @HOUR & ":" & @MIN & ":" & @SEC
EndFunc

Func OnExit()
  FileWriteLine($LogFile, @UserName & ": стоп  " & Now())
  FileWriteLine($LogFile, "------------------------------------")
EndFunc
 
Автор
I

Iniar

Новичок
Сообщения
9
Репутация
0
InnI сказал(а):
Если скрипт скомпилировать и добавить в автозагрузку пользователя, то старт/стоп фактически будет фиксировать вход/выход
Код:
#include <WinAPISys.au3>

OnAutoItExitRegister("OnExit")

Global $Locked, $LogFile = @ScriptDir & "\log.txt"

FileWriteLine($LogFile, @UserName & ": старт " & Now())

Do
  If $Locked <> IsLocked() Then
    Switch $Locked
      Case 0
        FileWriteLine($LogFile, @UserName & ": заблокирован  " & Now())
      Case 1
        FileWriteLine($LogFile, @UserName & ": разблокирован " & Now())
    EndSwitch
    $Locked = Not $Locked
  EndIf
  Sleep(1000)
Until 0

Func IsLocked()
  $hDesktop = _WinAPI_OpenDesktop("Default", $DESKTOP_SWITCHDESKTOP)
  $Result = _WinAPI_SwitchDesktop($hDesktop)
  _WinAPI_CloseDesktop($hDesktop)
  Return Not $Result
EndFunc

Func Now()
  Return @MDAY & "." & @MON & " " & @HOUR & ":" & @MIN & ":" & @SEC
EndFunc

Func OnExit()
  FileWriteLine($LogFile, @UserName & ": стоп  " & Now())
  FileWriteLine($LogFile, "------------------------------------")
EndFunc

Большое спасибо. Подскажите ещё пожалуйста, можно ли скрыть значок висящего в трее скрипта?
 
Верх