Определение времени бездействия системы

Иногда приложениям требуется узнать время бездействия системы, то есть интервал времени, прошедший с момента когда пользователь последний раз пошевелил мышкой или нажал какую-нибудь кнопку на клавиатуре. Для определения время бездействия системы в системах Windows 2000 и старше используется функция API GetLastInputInfo. Она возвращает количество миллисекунд (тиков таймера), прошедшее от старта системы до момента последнего ввода. Время бездействия вычисляется как арифметическая разница между данными, возвращаемыми функцией GetTickCount и данными из GetLastInputInfo. В FASM, как обычно, ничего из нужных структур не определено, лезем в MSDN:
section '.data' data readable writeable
 
struct  LASTINPUTINFO
        cbSize   dd ?   ; Размер структуры
        dwTime   dd ?   ; Время бездействия
ends
 
lii     LASTINPUTINFO  
Получение времени бездействия системы:
Code (Assembler) : Убрать нумерацию
        ...
        ; Получить время последнего ввода
        mov     [lii.cbSize],sizeof.LASTINPUTINFO
        invoke  GetLastInputInfo,lii
 
        ; Получить текущее время в миллисекундах
        invoke  GetTickCount
 
        ; EAX - время бездействия системы в миллисекундах
        sub     eax,[lii.dwTime]
        ...

Это был самый простой способ, работающий на всех новых системах. В старых операционках типа Windows 9x функция GetLastInputInfo отсутствует, поэтому там придется использовать другой, более громоздкий способ с применением глобальных системных хуков.

Чтобы перехват получился глобальным, придется загружать в память DLL с нужными функциями и устанавливать хуки уже на нее. Хуки будем ставить двух типов: через WH_MOUSE на мышь и через WH_KEYBOARD на клавиатуру. При наступлении любого из этих событий в переменную, находящуюся в shared-памяти DLL, будет записываться значение из функции GetTickCount, а при вызове какой-нибудь заранее определенной функции, это значение будет передаваться нашему приложению. Полный текст DLL я тут приводить не буду, можете посмотреть его, скачав прилагаемый файл с исходниками. В основное приложение DLL подгружается через импорт, при инициализации DLL ставятся глобальные хуки, а при выходе из приложения хуки должны обязательно сниматься.
        ...
        ; Получить время последнего ввода
        invoke  GetLastInputTime
        mov     ebx,eax
 
        ; Получить текущее время в миллисекундах
        invoke  GetTickCount
 
        ; EAX - время бездействия системы в миллисекундах
        sub     eax,ebx
        ...
        ...
        ...
.wmclose:
        ; Снять глобальные хуки
        invoke  UnloadDll
        ...

Этот метод универсальный и работает на всех системах. Но приходится таскать за собой дополнительную DLL, к установке глобальных хуков некоторые "как-бы-антивирусы" и мониторы могут отнестись с подозрением, ну и вдобавок получается много лишнего кода. Выбор оставляю за вами.

В приложении две программы, реализующие оба описанных выше метода. В диалоговом окне они показывают счетчик секунд, прошедших с момента последней активности пользователя. Чтобы сбросить счетчик пошевелите мышкой или нажмите любую клавишу.
Теги:
бездействие системы
Добавлено: 10 Апреля 2018 20:42:13 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...