TEventLogger和ReportEvent有什么区别?
如何使用ReportEvent功能?
解决方法
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,here和here.
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功能,如here和here所述.
我创建了一个简单的类,使其更容易,它是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 file和register 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 tutorial或Michael 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事件日志记录和其他日志记录要求,还可以使用日志框架,如log4d和TraceTool
如果要写入Delphi IDE中的事件日志窗口,请参阅here.