摘要:使用Delphi写入Windows事件日志
如果您正在编写一个 Windows 服务并需要写入本地计算机的 Windows 事件日志,则可以调用
TService.LogMessage,如
此处 所述。
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上可用。
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;
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));
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的文章,或者您可以使用现有的MC和
GitHub项目中包含的RES文件。
2、将MessageFile.res包含在您的DPR文件中,将RES文件嵌入到您的应用程序中。或者,您可以为消息创建一个dll。
program MyTestApp;
uses
Forms,
FormMain in 'FormMain.pas' ,
EventLog in 'EventLog.pas';
{$R *.res}
{$R MessageFile\MessageFile.res}
begin
Application.Initialize;
3、一次性注册需要管理员权限写入注册表,因此通常作为应用程序安装过程的一部分完成。
AddEventSourceToRegistry('My Application Name', ParamStr(0));
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 中写入事件日志窗口,请单击此处。