Время непрерывной работы (Uptime) Windows
Для получения времени непрерывной работы системы обычно используется функция API GetTickCount. Она возвращает количество миллисекунд, прошедших с момента последнего старта системы. Проблема в том, что счетчик имеет тип dword, и по прошествии примерно 50 дней (49,7 если быть точным) достигает предельного значения и обнуляется. Конечно, продержать систему без перезагрузки почти два месяца трудно, но не значит что невозможно. Поэтому для получения гарантированно точного времени работы системы воспользуемся функцией NtQuerySystemInformation. Достаточно долго эта функция относилась к разряду недокументированных, теперь же на MSDN по ней имеется описание с примечанием, что ее использование в прикладных программах все равно нежелательно.Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- ; По умолчанию структура в FASM не определена, сделаем это самостоятельно
- ; Для получения необходимой информации нужны только два первых значения
- struct SYSTEM_TIME_INFORMATION
- liKeBootTime dq ? ; Время старта системы
- liKeSystemTime dq ? ; Текущее время
- liExpTimeZoneBias dq ?
- uCurrentTimeZoneId dd ?
- dwReserved dw ?
- ends
- SystemTime SYSTEM_TIME_INFORMATION ; Наша структура с данными
- ; Константа нужного класса информации тоже не определена, сделаем это сами
- GET_SYSTEM_TIME_INFORMATION = 3
- ; Сегмент кода
- section '.code' code readable executable
- ...
- invoke NtQuerySystemInformation, GET_SYSTEM_TIME_INFORMATION,\
- SystemTime, sizeof.SYSTEM_TIME_INFORMATION, 0
- ; Записать в регистры EDX:EAX текущее время в миллисекундах
- mov eax, dword [SystemTime.liKeSystemTime]
- mov edx, dword [SystemTime.liKeSystemTime+4]
- ; Вычесть время старта системы
- sub eax, dword [SystemTime.liKeBootTime]
- sbb edx, dword [SystemTime.liKeBootTime+4]
- ; Теперь в регистры EDX:EAX записано реальное количество миллисекунд,
- ; прошедшее с момента старта системы
- ...
Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- ; По умолчанию структура в FASM не определена, сделаем это самостоятельно
- ; Для получения необходимой информации нужны только два первых значения
- struct SYSTEM_TIME_INFORMATION
- liKeBootTime dq ? ; Время старта системы
- liKeSystemTime dq ? ; Текущее время
- liExpTimeZoneBias dq ?
- uCurrentTimeZoneId dd ?
- dwReserved dw ?
- ends
- SystemTime SYSTEM_TIME_INFORMATION ; Наша структура с данными
- ; Добавляются две стандартные структуры для работы с датой и временем
- ftSystemTime FILETIME
- stSystemTime SYSTEMTIME
- ; Константа нужного класса информации тоже не определена, сделаем это сами
- GET_SYSTEM_TIME_INFORMATION = 3
- ; Сегмент кода
- section '.code' code readable executable
- ...
- invoke NtQuerySystemInformation, GET_SYSTEM_TIME_INFORMATION,\
- SystemTime, sizeof.SYSTEM_TIME_INFORMATION, 0
- ; Получить текущее системное время. Для получения времени старта
- ; системы замените в вызове SystemTime.liKeSystemTime на
- ; SystemTime.liKeBootTime
- invoke FileTimeToLocalFileTime, SystemTime.liKeSystemTime,\
- ftSystemTime
- ; Преобразовать в системный формат даты и времени
- invoke FileTimeToSystemTime, ftSystemTime, stSystemTime
- ; Теперь к элементам структуры stSystemTime можно обращаться
- ; обычными способами: [stSystemTime.wDay], [stSystemTime.wMonth] и т.д.
- ...
В приложении пример программы с исходным текстом, которая выводит дату последнего запуска и время непрерывной работы системы.
Просмотров: 6264 | Комментариев: 1
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Tam-Tam
(15.02.2012 в 15:16):
Мелкомягкие утилиту написали uptime, вполне пригодную для употребления, однако в дистрибутивы её не кладут, она где то в глубинах их сайта скрывается.
Добавить комментарий
Заполните форму для добавления комментария