我正在寻找一种(相当无痛)的方法,将一些Windows应用程序事件日志支持添加到一个小型的传统Delphi 5应用程序中.我们只是希望它在启动,关闭,无法连接到数据库等时进行记录.
我见过的几个解决方案/组件似乎暗示我们需要创建一个资源DLL,Windows事件日志查看器将在尝试读取我们的"条目"时链接到该资源DLL.虽然这似乎并不太繁琐,但我想如果/我们将来进一步开发应用程序时要记住这一点 - 我们需要保持这个DLL是最新的.
在未来的某个时刻,我们希望将应用程序转变为服务,可能是在D2007中编写的.
那么有人可以推荐一个合适的路径来将事件添加到D5中的事件日志吗?我正在寻找具体的' 我们用过这个,这是好的 '评论而不是谷歌拖网(我可以自己做!)免费或付费,真的不介意 - 但我可以迁移到D2007未来很重要.
简介:使用Delphi写入Windows事件日志
如果您正在编写Windows服务并需要写入本地计算机的Windows事件日志,则可以调用 TService.这里提到的LogMessage.
//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 ReportEvent函数.
我已经创建了一个简单的类来使它更容易,它可以在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.
ReportEvent支持将日志条目写入本地或远程计算机的事件日志.有关远程示例,请参阅 John Kaster的EDN文章.
请注意,您还必须创建一个消息文件并注册您的事件源,否则所有日志消息都将以这样的方式开头:
无法找到源xxxx的事件ID xxx的描述.引发此事件的组件未安装在本地计算机上,或者安装已损坏.您可以在本地计算机上安装或修复该组件.
如果事件源自另一台计算机,则必须随事件一起保存显示信息.
活动中包含以下信息:
1,有关如何创建消息文件的更多信息,请参阅Finn Tolderlund的教程或Michael Hex的文章, 或者您可以使用GitHub项目中包含的现有MC和RES文件.
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, 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事件日志等日志记录的要求,您还可以使用日志框架,如log4d和的TraceTool
如果要写入Delphi IDE中的"事件日志"窗口,请在此处查看.