摘要:使用Delphi写入Windows事件日志
如果您正在写入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。
测温仪
undocumented
帮助程序类,用于tservice写入本地计算机的Windows事件日志,如前所述
在这里
,
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, 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.
报告者
支持将日志项写入本地或远程计算机的事件日志。有关远程示例,请参见
John Kaster's EDN article
.
请注意,您还必须
create a message file
和
register your event source
否则,所有日志消息都将以如下方式开始:
源XXXX中事件ID XXX的描述不能是
找到了。未安装引发此事件的组件
您的本地计算机或安装已损坏。你可以安装
或修复本地计算机上的组件。
如果事件源自另一台计算机,则显示信息
必须与事件一起保存。
活动包括以下信息:
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, 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
见
here
如果要写入DelphiIDE中的事件日志窗口。