Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > ОС и железо
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 06.01.2015, 21:41
Romix Romix вне форума
Начинающий
 
Регистрация: 10.02.2008
Сообщения: 136
Версия Delphi: XE2
Репутация: 41
Вопрос Аварийное выключение компьютера

Доброе время суток, уважаемые форумчане!

Пришло время когда нужно определить "Аварийное выключение компьютера". Естественно не в момент его выключения, а при следующей загрузке Windows XP или 7. Например пользователь решил выдернуть комп из розетки или пропало электричество или ядерный взрыв. Предполагаю что Windows куда то пишет эту информацию или оставляет файл метку, что бы при загрузке, после аварийного отключения питания, запустить проверку chkdsk или предложить выбор загрузки системы.

Буду рад любой информации на эту тему. Читать не боюсь, просто отчаялся уже искать. Как будто секретная информация. Заранее благодарен всем откликнувшимся.
Ответить с цитированием
  #2  
Старый 06.01.2015, 22:54
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Ну самое простейшее — это файл (бит, запись в реестре, или еще какой признак), создающийся при корректном завершении работы и проверяющийся при загрузке.
Если нет необходимости в завязке на систему, то я бы посоветовал писать в реестр какой-нибудь флаг.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #3  
Старый 06.01.2015, 23:10
Romix Romix вне форума
Начинающий
 
Регистрация: 10.02.2008
Сообщения: 136
Версия Delphi: XE2
Репутация: 41
По умолчанию

Цитата:
Сообщение от M.A.D.M.A.N.
Ну самое простейшее — это файл (бит, запись в реестре, или еще какой признак), создающийся при корректном завершении работы и проверяющийся при загрузке.
Если нет необходимости в завязке на систему, то я бы посоветовал писать в реестр какой-нибудь флаг.
Уже обдумывал этот вариант! Но если моя программа висит например в трее и юзер завершает работу правильно, программа это увидела и записала бит в реестр и Винда закрыла мою тулзу, тут надпись на голубом экране "Сохранение параметров" и тут юзер выдергивает из розетки комп... Такой вариант не совсем верный, но все равно спасибо. Теперь я вижу что мыслил в правильном направлении. Очень хотелось бы отследить метку которую создаёт Windows.
Ответить с цитированием
  #4  
Старый 07.01.2015, 08:36
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Журналы Windows - Система | Системное время завершения работы операционной системы
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #5  
Старый 07.01.2015, 10:13
Romix Romix вне форума
Начинающий
 
Регистрация: 10.02.2008
Сообщения: 136
Версия Delphi: XE2
Репутация: 41
По умолчанию

Цитата:
Сообщение от NumLock
Журналы Windows - Система | Системное время завершения работы операционной системы
Ты NumLock прям озадачил меня, у меня 7-ка ну не нашел я там такого. Уже гуглить начал, пока безрезультатно. Ща пойду в XP смотреть.
Ответить с цитированием
  #6  
Старый 07.01.2015, 11:42
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Romix
Уже обдумывал этот вариант!
Не, при запуске программы устанавливать бит, а удалять при завершении. Не успело удалиться — значит система завершилась некорректно.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #7  
Старый 07.01.2015, 12:41
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Цитата:
Сообщение от Romix
у меня 7-ка ну не нашел я там такого. Уже гуглить начал, пока безрезультатно. Ща пойду в XP смотреть.
да хоть 8-ка, Event Logging Functions Minimum supported client Windows 2000.
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #8  
Старый 07.01.2015, 14:05
Romix Romix вне форума
Начинающий
 
Регистрация: 10.02.2008
Сообщения: 136
Версия Delphi: XE2
Репутация: 41
По умолчанию

MADMAN да я понял тебя. Но при правильном завершении работы винда закроет мою программу, программа увидит что её пытаются закрыть и удалит тот самый условный "бит" и вроде все хорошо. Но непредсказуемый юзер выдернет комп из розетки уже после того как винда закроет мою программу и винда определит это как некорректное завершение работы, а для программы все будет ОК.

NUMLOCK, разжуй пожалуйста для меня, что ты имеешь ввиду. Можно поподробнее. Как из Delphi прочитать это событие?
Ответить с цитированием
  #9  
Старый 07.01.2015, 14:12
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

OpenEventLog / ReadEventLog / CloseEventLog
Event Logging Functions
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #10  
Старый 07.01.2015, 14:43
Romix Romix вне форума
Начинающий
 
Регистрация: 10.02.2008
Сообщения: 136
Версия Delphi: XE2
Репутация: 41
По умолчанию

Цитата:
Сообщение от NumLock
OpenEventLog / ReadEventLog / CloseEventLog
Event Logging Functions
Уже как то стыдно просить, но не мог бы ты выложить маленький пример?
Ответить с цитированием
  #11  
Старый 07.01.2015, 15:58
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Romix
Пришло время когда нужно определить "Аварийное выключение компьютера". Естественно не в момент его выключения, а при следующей загрузке Windows XP или 7. Например пользователь решил выдернуть комп из розетки или пропало электричество или ядерный взрыв.
Информация о ядерных взрывах пишется где-то в загрузочном секторе FAT, для каждого тома отдельно. При загрузке Windows монтирует тома и проверяет радиоактивное заражение, и если находит, выполняет деактивацию.

С точки зрения последствий ядерному взрыву аналогичен приход уборщицы или внезапное выдергивание флешки из USB-порта. Если флешка в FAT, последствия те же.

По FAT инфа легко гуглится в интернетах, такие темы обычно на форумах разработки ОС обсуждают, в разделе загрузчиков.

NTFS устроена сложнее, в ней файловые операции журналируются и поэтому могут быть откачены при обнаружении рассогласования. В теории так, по крайней мере. В разных версиях NTFS свои особенности, в версиях Windows от Vista и выше вроде добавили полноценные транзакции. Подробно не изучал.

Еще exFAT есть, по ней вообще ничего не знаю. По организации она на NTFS похожа, но без журнала.
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
  #12  
Старый 07.01.2015, 19:35
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,723
Репутация: 52347
По умолчанию

Тоже покопался в инете по этой теме - на удивление скудно с решениями, а уж вопросов по ним море. Самое адекватное решение наверное такое:
Код:
{$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  
Старый 08.01.2015, 11:58
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

ну как-то вот так, к примеру:
Код:
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)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 16:34.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter