使用Delphi写入Windows事件日志

前端之家收集整理的这篇文章主要介绍了使用Delphi写入Windows事件日志前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我的Delphi应用程序如何轻松地写入Windows事件日志?

TEventLogger和ReportEvent有什么区别?
如何使用ReportEvent功能

解决方法

如果您正在编写Windows服务,并且需要写入本地计算机的Windows事件日志,那么您可以调用
TService.LogMessage如上所述 here.
//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 undocumented辅助程序类来为TService写入本地机器的Windows事件日志,如所述here,herehere.

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 ReportEvent功能,如herehere所述.

我创建了一个简单的类,使其更容易,它是available on 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,AEventId,nil,1,@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.

ReportEvent支持将日志条目写入本地或远程计算机的事件日志.有关远程示例,请参阅John Kaster’s EDN article.

请注意,您也必须使用create a message fileregister your event source,否则您的所有日志消息将以以下开始:

The description for Event ID xxx from source xxxx cannot be
found. Either the component that raises this event is not installed on
your local computer or the installation is corrupted. You can install
or repair the component on the local computer.

If the event originated on another computer,the display information
had to be saved with the event.

The following information was included with the event:

1,有关如何创建消息文件的更多信息,请参阅Finn Tolderlund’s tutorialMichael Hex’s article
或者您可以使用现有的MC和RES file included in the GitHub project.

2,通过在您的DPR文件中包含MessageFile.res,将RES文件嵌入到应用程序中.或者,您可以为邮件创建一个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,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事件日志记录和其他日志记录要求,还可以使用日志框架,如log4dTraceTool

如果要写入Delphi IDE中的事件日志窗口,请参阅here.

猜你在找的Delphi相关文章