質問

私は、Windows アプリケーション イベント ログのサポートを小規模な従来の Delphi 5 アプリケーションに追加する (かなり手間のかからない) 手段を探しています。起動時、シャットダウン時、データベースへの接続失敗時などをログに記録したいだけです。

私が見たソリューション/コンポーネントのいくつかは、Windows イベント ログ ビューアーが「エントリ」を読み取ろうとするときにリンクするリソース DLL を作成する必要があることを示唆しているようです。これはそれほど面倒なことではないようですが、将来アプリケーションをさらに開発する場合には、この DLL を最新の状態に保つ必要があるため、留意すべき点があると思います。

将来のある時点で、おそらく D2007 で書かれたアプリケーションをサービスに変えたいと考えています。

それでは、D5 のイベント ログにイベントを追加するための適切なルートを誰かが推奨できますか?特定のものを探しています私たちはこれを使用しましたが、大丈夫でしたGoogle のトロールではなく、コメントを投稿する (これは自分で行うことができます!) 無料か有料かはまったく問題ありませんが、将来的に D2007 に移行できるものは重要です。

役に立ちましたか?

他のヒント

まとめ:Delphi を使用した Windows イベント ログへの書き込み


Windows サービスを作成していて、ローカル マシンの Windows イベント ログに書き込む必要がある場合は、次のように呼び出すことができます。Tサービス。ログメッセージ 述べたように ここ.

//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 を使用できます。Tイベントロガー 文書化されていない 前述のように、ローカル マシンの Windows イベント ログを書き込むための TService のヘルパー クラス ここ, ここ そして ここ.

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を使用することもできます レポートイベント 前述したような機能 ここ そして ここ.

簡単にするために簡単なクラスを作成しました。 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 の EDN 記事.


また、次のことも行う必要があることに注意してください。 メッセージファイルを作成する そして イベントソースを登録する そうしないと、すべてのログ メッセージが次のような内容で始まります。

ソースxxxxのイベントID xxxの説明は見つかりません。このイベントを提起するコンポーネントがローカルコンピューターにインストールされていないか、インストールが破損しています。ローカルコンピューターのコンポーネントをインストールまたは修復できます。

イベントが別のコンピューターで発生した場合、イベントでディスプレイ情報を保存する必要がありました。

イベントには次の情報が含まれていました。

1、メッセージ ファイルの作成方法の詳細については、「メッセージ ファイルの作成方法」を参照してください。 Finn Tolderlund のチュートリアル または マイケル・ヘックスの記事 または、既存の MC を使用して、 GitHub プロジェクトに含まれる 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 イベント ログやその他のログ要件が必要な場合は、次のようなログ フレームワークを使用することもできます。 ログ4d そして トレースツール


見る ここ Delphi IDE のイベント ログ ウィンドウに書き込む場合。

D5 での単純なイベント ログの場合、次のコードを使用してメッセージをアプリケーション ログに追加しました。

  • uses句に「SvcMgr」を追加
  • このコードを使用して、テキスト メッセージと ID 番号 (LogMessage 行の最後のパラメータ) を追加します。

    with TEventLogger.create('My Application Name') do
    begin
      try
        LogMessage('Information Message!', EVENTLOG_INFORMATION_TYPE, 0, 1);
        LogMessage('Error Message!', EVENTLOG_ERROR_TYPE, 0, 2);
        LogMessage('Warning Message!', EVENTLOG_WARNING_TYPE, 0, 3);
        LogMessage('Audit Success Message!', EVENTLOG_AUDIT_SUCCESS, 0, 4);
        LogMessage('Audit Failure Message!', EVENTLOG_AUDIT_FAILURE, 0, 5);
      finally
        free;
      end;
    end;
    

Delphi 6 ではこれに標準 VCL を使用していますが、これが Delphi 5 で利用できるかどうかはわかりません。自分で試してみて、このようなものが D5 にあるかどうかをお知らせください。

  1. TEventLogger 型のグローバル/フォーム変数を宣言します。これは SvcMgr ユニットで宣言されているため、このユニットを使用リストに追加する必要があります。これが通常のアプリケーションの場合 (つまり、サービスではありません)、SvcMgr が Forms ユニットの後に追加されていることを確認してください。

    私のイベントログ:TEventLogger;

  2. ロガーのインスタンスを作成します。

    MyEventLog := TEventLogger.Create('MyApplication');

  3. イベント ログに書き込むには:

    MyEventLog.LogMessage('MyApplication が開始されました。'), EVENTLOG_INFORMATION_TYPE);

  4. 最後に忘れずに解放してください。

    MyEventLog.無料;

アプリケーションを Windows イベント ログに登録して、メッセージの前にこれを付けずにメッセージが表示されるようにするには、他にも行う必要がある作業があります。

ソース (Microsoft Internet Explorer) にイベント ID ( 1000 ) の説明が見つかりません。ローカル コンピュータには、リモート コンピュータからのメッセージを表示するために必要なレジストリ情報またはメッセージ DLL ファイルがない可能性があります。以下の情報はイベントの一部です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top