![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Доброе время суток, уважаемые форумчане!
Пришло время когда нужно определить "Аварийное выключение компьютера". Естественно не в момент его выключения, а при следующей загрузке Windows XP или 7. Например пользователь решил выдернуть комп из розетки или пропало электричество или ядерный взрыв. Предполагаю что Windows куда то пишет эту информацию или оставляет файл метку, что бы при загрузке, после аварийного отключения питания, запустить проверку chkdsk или предложить выбор загрузки системы. Буду рад любой информации на эту тему. Читать не боюсь, просто отчаялся уже искать. Как будто секретная информация. Заранее благодарен всем откликнувшимся. |
|
#2
|
||||
|
||||
|
Ну самое простейшее — это файл (бит, запись в реестре, или еще какой признак), создающийся при корректном завершении работы и проверяющийся при загрузке.
Если нет необходимости в завязке на систему, то я бы посоветовал писать в реестр какой-нибудь флаг. |
|
#3
|
|||
|
|||
|
Цитата:
|
|
#4
|
||||
|
||||
|
Журналы Windows - Система | Системное время завершения работы операционной системы
|
|
#5
|
|||
|
|||
|
Цитата:
|
|
#6
|
||||
|
||||
|
Цитата:
|
|
#7
|
||||
|
||||
|
Цитата:
|
|
#8
|
|||
|
|||
|
MADMAN да я понял тебя. Но при правильном завершении работы винда закроет мою программу, программа увидит что её пытаются закрыть и удалит тот самый условный "бит" и вроде все хорошо. Но непредсказуемый юзер выдернет комп из розетки уже после того как винда закроет мою программу и винда определит это как некорректное завершение работы, а для программы все будет ОК.
NUMLOCK, разжуй пожалуйста для меня, что ты имеешь ввиду. Можно поподробнее. Как из Delphi прочитать это событие? |
|
#9
|
||||
|
||||
|
OpenEventLog / ReadEventLog / CloseEventLog
Event Logging Functions |
|
#10
|
|||
|
|||
|
Цитата:
|
|
#11
|
||||
|
||||
|
Цитата:
С точки зрения последствий ядерному взрыву аналогичен приход уборщицы или внезапное выдергивание флешки из USB-порта. Если флешка в FAT, последствия те же. По FAT инфа легко гуглится в интернетах, такие темы обычно на форумах разработки ОС обсуждают, в разделе загрузчиков. NTFS устроена сложнее, в ней файловые операции журналируются и поэтому могут быть откачены при обнаружении рассогласования. В теории так, по крайней мере. В разных версиях NTFS свои особенности, в версиях Windows от Vista и выше вроде добавили полноценные транзакции. Подробно не изучал. Еще exFAT есть, по ней вообще ничего не знаю. По организации она на NTFS похожа, но без журнала. |
|
#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)
| ||