![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() Доброе время суток, уважаемые форумчане!
Пришло время когда нужно определить "Аварийное выключение компьютера". Естественно не в момент его выключения, а при следующей загрузке Windows XP или 7. Например пользователь решил выдернуть комп из розетки или пропало электричество или ядерный взрыв. Предполагаю что Windows куда то пишет эту информацию или оставляет файл метку, что бы при загрузке, после аварийного отключения питания, запустить проверку chkdsk или предложить выбор загрузки системы. Буду рад любой информации на эту тему. Читать не боюсь, просто отчаялся уже искать. Как будто секретная информация. Заранее благодарен всем откликнувшимся. |
#2
|
||||
|
||||
![]() Ну самое простейшее — это файл (бит, запись в реестре, или еще какой признак), создающийся при корректном завершении работы и проверяющийся при загрузке.
Если нет необходимости в завязке на систему, то я бы посоветовал писать в реестр какой-нибудь флаг. — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
#3
|
|||
|
|||
![]() Цитата:
|
#4
|
||||
|
||||
![]() Журналы Windows - Система | Системное время завершения работы операционной системы
Пишу программы за еду. __________________ |
#5
|
|||
|
|||
![]() Цитата:
|
#6
|
||||
|
||||
![]() Цитата:
— Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
#7
|
||||
|
||||
![]() Цитата:
Пишу программы за еду. __________________ |
#8
|
|||
|
|||
![]() MADMAN да я понял тебя. Но при правильном завершении работы винда закроет мою программу, программа увидит что её пытаются закрыть и удалит тот самый условный "бит" и вроде все хорошо. Но непредсказуемый юзер выдернет комп из розетки уже после того как винда закроет мою программу и винда определит это как некорректное завершение работы, а для программы все будет ОК.
NUMLOCK, разжуй пожалуйста для меня, что ты имеешь ввиду. Можно поподробнее. Как из Delphi прочитать это событие? |
#9
|
||||
|
||||
![]() OpenEventLog / ReadEventLog / CloseEventLog
Event Logging Functions Пишу программы за еду. __________________ |
#10
|
|||
|
|||
![]() Цитата:
|
#11
|
||||
|
||||
![]() Цитата:
С точки зрения последствий ядерному взрыву аналогичен приход уборщицы или внезапное выдергивание флешки из USB-порта. Если флешка в FAT, последствия те же. По FAT инфа легко гуглится в интернетах, такие темы обычно на форумах разработки ОС обсуждают, в разделе загрузчиков. NTFS устроена сложнее, в ней файловые операции журналируются и поэтому могут быть откачены при обнаружении рассогласования. В теории так, по крайней мере. В разных версиях NTFS свои особенности, в версиях Windows от Vista и выше вроде добавили полноценные транзакции. Подробно не изучал. Еще exFAT есть, по ней вообще ничего не знаю. По организации она на NTFS похожа, но без журнала. Не стоит путать форумы с богадельнями. © Bargest |
#12
|
||||
|
||||
![]() Тоже покопался в инете по этой теме - на удивление скудно с решениями, а уж вопросов по ним море. Самое адекватное решение наверное такое:
Код:
{$APPTYPE CONSOLE} uses SysUtils, ActiveX, ComObj, Variants; procedure GetLogEvents; const wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObjectSet:= FWMIService.ExecQuery('SELECT Category,ComputerName,EventCode,Message,RecordNumber FROM Win32_NTLogEvent '+ 'Where Logfile="System" and EventCode=1','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin Writeln(Format('Category %s',[String(FWbemObject.Category)])); Writeln(Format('Computer Name %s',[String(FWbemObject.ComputerName)])); Writeln(Format('EventCode %d',[Integer(FWbemObject.EventCode)])); Writeln(Format('Message %s',[String(FWbemObject.Message)])); Writeln(Format('RecordNumber %d',[Integer(FWbemObject.RecordNumber)])); FWbemObject:=Unassigned; end; end; begin try CoInitialize(nil); try GetLogEvents; finally CoUninitialize; end; except on E:EOleException do Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode])); on E:Exception do Writeln(E.Classname, ':', E.Message); end; Writeln('Press Enter to exit'); Readln; end. Жизнь такова какова она есть и больше никакова. Помогаю за спасибо. |
Этот пользователь сказал Спасибо Страдалецъ за это полезное сообщение: | ||
Romix (08.01.2015)
|
#13
|
||||
|
||||
![]() ну как-то вот так, к примеру:
Код:
var hEventLog: THandle; NumberOfRecords: DWORD; Buffer: PEVENTLOGRECORD; BytesRead, MinNumberOfBytesNeeded: DWORD; begin Memo1.Lines.BeginUpdate; try hEventLog:=OpenEventLog(nil, 'SYSTEM'); if hEventLog=0 then RaiseLastOSError; if GetNumberOfEventLogRecords(hEventLog, NumberOfRecords) then Memo1.Lines.Add('NumberOfRecords = '+IntToStr(NumberOfRecords)); Buffer:=GetMemory($10000); while True do begin if not ReadEventLog(hEventLog, EVENTLOG_SEQUENTIAL_READ or EVENTLOG_BACKWARDS_READ, 0, Buffer, 0, BytesRead, MinNumberOfBytesNeeded) then begin if GetLastError<>ERROR_INSUFFICIENT_BUFFER then Break; if not ReadEventLog(hEventLog, EVENTLOG_SEQUENTIAL_READ or EVENTLOG_BACKWARDS_READ, 0, Buffer, MinNumberOfBytesNeeded, BytesRead, MinNumberOfBytesNeeded) then Break; if PChar(Integer(Buffer)+SizeOf(EVENTLOGRECORD))='Microsoft-Windows-Kernel-General' then begin if Buffer^.EventID in [12, 13] then Memo1.Lines.Add('RecordNumber = '+IntToStr(Buffer^.RecordNumber)+' '+PChar(Integer(Buffer)+SizeOf(EVENTLOGRECORD))+' TimeGenerated = '+DateTimeToStr(UnixToDateTime(Buffer^.TimeGenerated))+' EventID = '+IntToStr(Buffer^.EventID)); end; end else Break; end; FreeMemory(Buffer); CloseEventLog(hEventLog); finally Memo1.Lines.EndUpdate; end; end; более подробно на C++ : Querying for Event Information Пишу программы за еду. __________________ |
Эти 2 пользователя(ей) сказали Спасибо NumLock за это полезное сообщение: | ||
M.A.D.M.A.N. (08.01.2015),
Romix (08.01.2015)
|