使用Delphi写入Windows事件日志

使用Delphi写入Windows事件日志,delphi,event-log,Delphi,Event Log,我的Delphi应用程序如何轻松写入Windows事件日志 Teventloger和ReportEvent之间有什么区别? 如何使用ReportEvent函数?如果您正在编写Windows服务,并且需要写入本地计算机的Windows事件日志,则可以调用 如前所述 对于任何其他类型的应用程序,您可以使用TService的SvcMgr.Teventlogerhelper类来编写本地计算机的Windows事件日志,如前所述,以及 您还可以使用前面提到的Windows API函数和 我已经创建了一个

我的Delphi应用程序如何轻松写入Windows事件日志

Teventloger和ReportEvent之间有什么区别?
如何使用ReportEvent函数?

如果您正在编写Windows服务,并且需要写入本地计算机的Windows事件日志,则可以调用 如前所述


对于任何其他类型的应用程序,您可以使用TService的SvcMgr.Teventlogerhelper类来编写本地计算机的Windows事件日志,如前所述,以及


您还可以使用前面提到的Windows API函数和

我已经创建了一个简单的类来简化它,它是

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事件日志记录和其他日志记录要求,也可以使用和等日志记录框架



查看是否要写入Delphi IDE中的事件日志窗口。

搜索堆栈溢出以查找这个看似简单的问题,将返回分布在多个问题之间的答案。我创建了一个新的简单问题,并花时间将答案组合起来,添加其他答案中没有的额外信息。我这么做是因为这不是我第一次来这里寻找这个答案,我认为详细的答案和示例项目可能也会帮助其他人。你可以在另一个问题上这样做。这里也很好。这些问题现在已经联系起来了。一切都很好。啊,好的,谢谢大卫,我现在更了解它的工作原理了。干得好!只是为了你的日志类。我希望他们的方法是实例方法,而不是类方法,以避免重复注册和取消注册事件源。我会在创建类的实例时注册事件源,在销毁时取消注册。或者创建一个全局threadvar并初始化它一次。如果在实例被销毁时取消注册,是否会导致无法再读取现有的事件日志条目?换句话说,实例必须处于活动状态,操作员才能查看旧的事件日志条目?我认为注册事件源应该是安装的一部分,并注销可执行文件的卸载。嗨,TOndrey,我怀疑TLama是指“RegisterEventSource”API调用,而不是“通过将其添加到注册表来注册事件源”:-)嗨,谢谢你的建议。我最初认为这可能是微优化,我喜欢类方法的一行易用性:-)我将其更改为使用全局threadvar,不确定它是否100%正确,请看我还添加了实例方法版本
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;
//----------------- 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.
program MyTestApp;

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

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

begin
  Application.Initialize;
//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;