Модернизация журнала событий Windows в приложении Delphi 5

StackOverflow https://stackoverflow.com/questions/684919

  •  22-08-2019
  •  | 
  •  

Вопрос

Я ищу (довольно безболезненный) способ добавления поддержки журнала событий приложений Windows в небольшое устаревшее приложение Delphi 5.Мы просто хотим, чтобы он регистрировался, когда он запускается, выключается, не может подключиться к базе данных и т. д.

Некоторые из решений/компонентов, которые я видел, похоже, предполагают, что нам нужно будет создать ресурсную DLL, на которую будет ссылаться средство просмотра журнала событий Windows при попытке прочитать наши «записи».Хотя это не кажется слишком обременительным, я думаю, что если/когда мы будем продолжать разработку приложения в будущем, следует иметь в виду еще кое-что — нам нужно будет поддерживать эту DLL в актуальном состоянии.

В какой-то момент в будущем мы захотим превратить приложение в сервис, возможно, написанный на D2007.

Так может ли кто-нибудь порекомендовать подходящий маршрут для добавления событий в журнал событий в D5?Я ищу конкретный 'мы использовали это, и все было в порядкекомментарии, а не трал Google (который я могу сделать сам!) Бесплатно или платно, действительно не против - но важно то, что я мог бы перейти на D2007 в будущем.

Это было полезно?

Решение 4

Благодаря Дж и ответы Питера, мой код сразу же записался в журнал событий.Нужно сделать еще кое-что, особенно если вы хотите, чтобы ваши события «красиво» отображались в журнале событий без стандартного сообщения Windows о невозможности найти описание (как показано в нижней части Джпост).

Я последовал советам здесь создать подходящую DLL и внести ее в реестр, и очень быстро во всем разобрались.

Согласно вопросу, все это было в Delphi5, но я не видел ничего, что заставило бы меня думать, что это не будет работать и в D2007.

Другие советы

Краткое содержание:Запись в журнал событий Windows с помощью Delphi


Если вы пишете службу Windows и вам необходимо выполнить запись в журнал событий Windows на локальном компьютере, вы можете вызватьТСервис.ЖурналСообщение как уже упоминалось здесь.

//TMyTestService = class(TService)

procedure TMyTestService.ServiceStart(Sender: TService; var Started: Boolean);
begin
  LogMessage('This is an error.');
  LogMessage('This is another error.', EVENTLOG_ERROR_TYPE);
  LogMessage('This is information.', EVENTLOG_INFORMATION_TYPE);
  LogMessage('This is a warning.', EVENTLOG_WARNING_TYPE);
end;

Для любого другого типа приложений вы можете использовать файл SvcMgr.TEventLogger недокументированный вспомогательный класс для TService для записи журнала событий Windows на локальном компьютере, как уже упоминалось. здесь, здесь и здесь.

uses
  SvcMgr;

procedure TForm1.EventLoggerExampleButtonClick(Sender: TObject);
begin
  with TEventLogger.Create('My Test App Name') do
  begin
    try
      LogMessage('This is an error.');
      LogMessage('This is another error.', EVENTLOG_ERROR_TYPE);
      LogMessage('This is information.', EVENTLOG_INFORMATION_TYPE);
      LogMessage('This is a warning.', EVENTLOG_WARNING_TYPE);
    finally
      Free;
    end;
  end;
end;

Вы также можете использовать Windows API ОтчетСобытие функционировать, как упоминалось здесь и здесь.

Я создал простой класс, чтобы упростить задачу, это доступен на GitHub.

//----------------- EXAMPLE USAGE: ---------------------------------

uses
  EventLog;

procedure TForm1.EventLogExampleButtonClick(Sender: TObject);
begin
  TEventLog.Source := 'My Test App Name';

  TEventLog.WriteError('This is an error.');
  TEventLog.WriteInfo('This is information.');
  TEventLog.WriteWarning('This is a warning.');
end;

//------------------------------------------------------------------


unit EventLog;

interface

type
  TEventLog = class
  private
    class procedure CheckEventLogHandle;
    class procedure Write(AEntryType: Word; AEventId: Cardinal; AMessage: string); static;
  public
    class var Source: string;
    class destructor Destroy;

    class procedure WriteInfo(AMessage: string); static;
    class procedure WriteWarning(AMessage: string); static;
    class procedure WriteError(AMessage: string); static;

    class procedure AddEventSourceToRegistry; static;
  end;

threadvar EventLogHandle: THandle;

implementation

uses Windows, Registry, SysUtils;

class destructor TEventLog.Destroy;
begin
  if EventLogHandle > 0 then
  begin
    DeregisterEventSource(EventLogHandle);
  end;
end;

class procedure TEventLog.WriteInfo(AMessage: string);
begin
  Write(EVENTLOG_INFORMATION_TYPE, 2, AMessage);
end;

class procedure TEventLog.WriteWarning(AMessage: string);
begin
  Write(EVENTLOG_WARNING_TYPE, 3, AMessage);
end;

class procedure TEventLog.WriteError(AMessage: string);
begin
  Write(EVENTLOG_ERROR_TYPE, 4, AMessage);
end;

class procedure TEventLog.CheckEventLogHandle;
begin
  if EventLogHandle = 0 then
  begin
   EventLogHandle := RegisterEventSource(nil, PChar(Source));
  end;
  if EventLogHandle <= 0 then
  begin
    raise Exception.Create('Could not obtain Event Log handle.');
  end;
end;

class procedure TEventLog.Write(AEntryType: Word; AEventId: Cardinal; AMessage: string);
begin
  CheckEventLogHandle;
  ReportEvent(EventLogHandle, AEntryType, 0, AEventId, nil, 1, 0, @AMessage, nil);
end;

// This requires admin rights. Typically called once-off during the application's installation
class procedure TEventLog.AddEventSourceToRegistry;
var
  reg: TRegistry;
begin
  reg := TRegistry.Create;
  try
    reg.RootKey := HKEY_LOCAL_MACHINE;
    if reg.OpenKey('\SYSTEM\CurrentControlSet\Services\Eventlog\Application\' + Source, True) then
    begin
      reg.WriteString('EventMessageFile', ParamStr(0)); // The application exe's path
      reg.WriteInteger('TypesSupported', 7);
      reg.CloseKey;
    end
    else
    begin
      raise Exception.Create('Error updating the registry. This action requires administrative rights.');
    end;
  finally
    reg.Free;
  end;
end;

initialization

TEventLog.Source := 'My Application Name';

end.

ОтчетСобытие поддерживает запись записи в журнал событий локального или удаленного компьютера.Удаленный пример см. Статья Джона Кастера в EDN.


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

Описание для идентификатора события xxx из источника XXXX не может быть найдено.Либо компонент, который повышает это событие, не установлен на вашем локальном компьютере, либо установка повреждена.Вы можете установить или восстановить компонент на локальном компьютере.

Если событие произошло на другом компьютере, информация о дисплее должна была быть сохранена с помощью события.

К мероприятию была приложена следующая информация:

1. Дополнительную информацию о том, как создать файл сообщения, см. Учебник Финна Толдерлунда или Статья Майкла Хекса или вы можете использовать существующий MC и RES-файл, включенный в проект GitHub..

2. Встройте файл RES в свое приложение, включив MessageFile.res в свой файл DPR.Альтернативно вы можете создать dll для сообщений.

program MyTestApp;

uses
  Forms,
  FormMain in 'FormMain.pas' {MainForm},
  EventLog in 'EventLog.pas';

{$R *.res}
{$R MessageFile\MessageFile.res}

begin
  Application.Initialize;

3. Для однократной регистрации требуются права администратора на запись в реестр, поэтому мы обычно делаем это как часть процесса установки вашего приложения.

//For example
AddEventSourceToRegistry('My Application Name', ParamStr(0));
//or
AddEventSourceToRegistry('My Application Name', 'C:\Program Files\MyApp\Messages.dll');

//--------------------------------------------------

procedure AddEventSourceToRegistry(ASource, AFilename: string);
var
  reg: TRegistry;
begin
  reg := TRegistry.Create;
  try
    reg.RootKey := HKEY_LOCAL_MACHINE;
    if reg.OpenKey('\SYSTEM\CurrentControlSet\Services\Eventlog\Application\' + ASource, True) then
    begin
      reg.WriteString('EventMessageFile', AFilename);
      reg.WriteInteger('TypesSupported', 7);
      reg.CloseKey;
    end
    else
    begin
      raise Exception.Create('Error updating the registry. This action requires administrative rights.');
    end;
  finally
    reg.Free;
  end;
end;

Если вам необходимо ведение журнала событий Windows и другие требования к ведению журнала, вы также можете использовать платформы ведения журнала, такие как журнал4d и Инструмент трассировки


Видеть здесь если вы хотите записать в окно журнала событий в Delphi IDE.

Для простой регистрации событий в D5 я использовал следующий код для добавления сообщений в журнал приложений.

  • Добавьте «SvcMgr» в раздел использования.
  • Используйте этот код, чтобы добавить текстовое сообщение и идентификационный номер (последний параметр в строках LogMessage).

    with TEventLogger.create('My Application Name') do
    begin
      try
        LogMessage('Information Message!', EVENTLOG_INFORMATION_TYPE, 0, 1);
        LogMessage('Error Message!', EVENTLOG_ERROR_TYPE, 0, 2);
        LogMessage('Warning Message!', EVENTLOG_WARNING_TYPE, 0, 3);
        LogMessage('Audit Success Message!', EVENTLOG_AUDIT_SUCCESS, 0, 4);
        LogMessage('Audit Failure Message!', EVENTLOG_AUDIT_FAILURE, 0, 5);
      finally
        free;
      end;
    end;
    

Я использую для этого стандартный VCL в Delphi 6, не могу сказать, доступно ли это в Delphi 5.Попробуйте сами и дайте нам знать, есть ли эта штука в D5.

  1. Объявите глобальную переменную/переменную формы типа TEventLogger.Это объявлено в модуле SvcMgr, поэтому этот модуль необходимо добавить в список использования.Если это обычное приложение (т.не служба), затем убедитесь, что SvcMgr добавлен после модуля Forms.

    Мой журнал событий:ТЕвентлогер;

  2. Создайте экземпляр регистратора.

    MyEventLog := TEventLogger.Create('MyApplication');

  3. Чтобы записать в журнал событий:

    MyEventLog.LogMessage('Мое приложение запущено.'), EVENTLOG_INFORMATION_TYPE);

  4. Не забудьте отпустить его в конце:

    МойEventLog.Free;

Есть и другие вещи, которые вам нужно сделать, чтобы зарегистрировать приложение в журнале событий Windows, чтобы сообщение появлялось без этого:

Невозможно найти описание идентификатора события (1000) в источнике (Microsoft Internet Explorer).На локальном компьютере может отсутствовать необходимая информация реестра или файлы DLL сообщений для отображения сообщений с удаленного компьютера.В рамках мероприятия представлена ​​следующая информация:

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top