将Windows事件日志改装为Delphi 5应用程序

将Windows事件日志改装为Delphi 5应用程序,delphi,delphi-5,event-log,Delphi,Delphi 5,Event Log,我正在寻找一种(相当轻松)的方法,将一些Windows应用程序事件日志支持添加到一个小型的传统Delphi 5应用程序中。我们只希望它在启动、关闭、无法连接到数据库等情况下进行日志记录 我看到的几个解决方案/组件似乎建议我们需要创建一个资源DLL,Windows事件日志查看器在尝试读取“条目”时将链接到该DLL。虽然这看起来不太繁重,但我想如果/当我们将来进一步开发应用程序时,还需要记住另外一件事——我们需要使这个DLL保持最新 在将来的某个时候,我们会希望将应用程序转换为服务,可能是用D200

我正在寻找一种(相当轻松)的方法,将一些Windows应用程序事件日志支持添加到一个小型的传统Delphi 5应用程序中。我们只希望它在启动、关闭、无法连接到数据库等情况下进行日志记录

我看到的几个解决方案/组件似乎建议我们需要创建一个资源DLL,Windows事件日志查看器在尝试读取“条目”时将链接到该DLL。虽然这看起来不太繁重,但我想如果/当我们将来进一步开发应用程序时,还需要记住另外一件事——我们需要使这个DLL保持最新

在将来的某个时候,我们会希望将应用程序转换为服务,可能是用D2007编写的


那么,有人能推荐一个合适的路径来将事件添加到D5中的事件日志中吗?我正在寻找具体的“我们使用了这个,一切都好”的评论,而不是谷歌拖网(我可以自己做!)免费或付费,真的不介意——但我可以在将来迁移到D2007的东西很重要。

我在Delphi 6中使用标准VCL,我无法告诉你Delphi 5中是否有这个功能。你自己试试,让我们知道D5中是否有这种东西

  • 声明TEventLogger类型的全局/表单变量。这是在SvcMgr单元中声明的,因此需要将此单元添加到用户列表中。如果这是一个普通的应用程序(即不是服务),则确保在表单单元之后添加SvcMgr

    MyEventLog:Teventloger

  • 创建记录器的实例

    MyEventLog:=TEventLogger.Create('MyApplication')

  • 要写入事件日志,请执行以下操作:

    LogMessage('MyApplication started')、EVENTLOG\u信息\u类型)

  • 不要忘记在最后发布它:

    MyEventLog.Free

  • 要在Windows事件日志中注册应用程序,您还需要执行其他操作,以便消息显示时不会出现以下内容:


    找不到源(Microsoft Internet Explorer)中事件ID(1000)的说明。本地计算机可能没有必要的注册表信息或消息DLL文件来显示来自远程计算机的消息。以下信息是事件的一部分:

    对于D5中的简单事件记录,我使用以下代码将消息添加到应用程序日志中

    • 在uses子句中添加“SvcMgr”
    • 使用此代码添加文本消息和ID号(LogMessage行上的最后一个参数)

    多亏了J和Peter的回复,我的代码立即写入了事件日志。还有一点事情要做,特别是如果你想让你的事件在事件日志中“漂亮地”出现,而没有一条关于无法找到描述的标准windows消息(如J文章的底部所示)

    我按照提示制作了一个合适的DLL并将其输入注册表,很快就把它整理好了

    根据问题,这都是在Delphi5中完成的,但我没有看到任何让我认为它在D2007中也不起作用的东西。

    摘要:使用Delphi写入Windows事件日志


    如果您正在编写Windows服务,并且需要写入本地计算机的Windows事件日志,则可以调用 如前所述


    对于任何其他类型的应用程序,您可以使用TService的SvcMgr.Teventlogerhelper类来编写本地计算机的Windows事件日志,如前所述,以及


    您还可以使用前面提到的Windows API函数和

    我已经创建了一个简单的类来简化它,它是

    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事件日志记录和其他日志记录要求,也可以使用和等日志记录框架



    查看是否要写入Delphi IDE中的事件日志窗口。

    谢谢-在这和Peter McMinn的回答之间,我已经开始了。我会回来发布一些关于设置注册表/资源DLL的更新信息,一旦一切正常。再次感谢!谢谢你,彼得,我请客了。我只是想弄清楚我需要对注册表和资源DLL做些什么,使它变得干净整洁。干杯,Rob你能告诉我哪个Windows库包含这些函数吗?我真的怀疑这是一个聪明的想法,增加整个单位!!!只使用少数!!!其中的功能。。。是advapi32.dll还是winnt.dll。。。还是哪个?提前感谢……我接受了这个答案,只是因为它包含了J和Peter的回答,以及你必须做的其他部分的链接。我不会从中获得任何声誉:-)
    //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;
    
    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;
    
    //----------------- 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.
    
    program MyTestApp;
    
    uses
      Forms,
      FormMain in 'FormMain.pas' {MainForm},
      EventLog in 'EventLog.pas';
    
    {$R *.res}
    {$R MessageFile\MessageFile.res}
    
    begin
      Application.Initialize;
    
    //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;