概要: 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 を使用できます。ここ、ここ、ここで説明されているように、ローカル マシンの Windows イベント ログを書き込む TService のTEventLogger ドキュメント化されていないヘルパー クラス。
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;
hereおよびhere で説明されているように、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. 1 回限りの登録には管理者権限によるレジストリへの書き込みが必要なため、通常はアプリケーションのインストール プロセスの一部として行います。
//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 のイベント ログ ウィンドウに書き込みたい場合は、こちらを参照してください。