문제

저는 소규모 레거시 Delphi 5 응용 프로그램에 일부 Windows 응용 프로그램 이벤트 로그 지원을 추가하는 (상당히 고통스럽지 않은) 방법을 찾고 있습니다.우리는 시작, 종료, 데이터베이스 연결 실패 등을 기록하기를 원합니다.

내가 본 몇몇 솔루션/구성 요소는 '항목'을 읽으려고 할 때 Windows 이벤트 로그 뷰어가 연결할 리소스 DLL을 만들어야 한다고 제안하는 것 같습니다.이것이 그다지 번거롭지는 않은 것 같지만, 향후에 응용 프로그램을 추가로 개발할 경우 이 DLL을 최신 상태로 유지해야 한다는 점을 염두에 두어야 할 다른 사항이라고 생각합니다.

미래의 어느 시점에서 우리는 애플리케이션을 아마도 D2007로 작성된 서비스로 전환하고 싶을 것입니다.

그렇다면 D5의 이벤트 로그에 이벤트를 추가하는 데 적합한 경로를 추천할 수 있는 사람이 있습니까?나는 구체적인 '을 찾고 있습니다우리 이거 써봤는데 괜찮더라' Google 트롤(내가 직접 할 수 있음!)보다는 댓글이 무료든 유료든 상관없습니다. 하지만 나중에 D2007로 마이그레이션할 수 있는 것이 중요합니다.

도움이 되었습니까?

해결책 4

감사합니다 제이 그리고 Peter의 답변, 나는 코드를 이벤트 로그에 곧바로 작성했습니다. 특히 할 일이 조금 더 있습니다. 특히 이벤트 로그에서 이벤트 로그에서 이벤트 로그에 표준 Windows 메시지가없는 경우 (설명을 찾을 수없는 것에 대한 표준 Windows 메시지가 표시되기를 원한다면) 제이포스트).

나는 팁을 따랐다 여기 적절한 DLL을 만들어 레지스트리에 입력하고 매우 빠르게 분류했습니다.

이것은 질문에 따라 Delphi5에 있었지만 D2007에서도 작동하지 않을 것이라고 생각하는 것은 아무것도 보지 못했습니다.

다른 팁

요약:Delphi를 사용하여 Windows 이벤트 로그에 쓰기


Windows 서비스를 작성 중이고 로컬 시스템의 Windows 이벤트 로그에 작성해야 하는 경우 다음을 호출할 수 있습니다.TService.로그메시지 말한 바와 같이 여기.

//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을 사용할 수 있습니다.TEventLogger 문서화되지 않은 언급한 대로 로컬 시스템의 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, 일회성 등록에는 레지스트리에 대한 관리자 권한 쓰기가 필요하므로 일반적으로 응용 프로그램 설치 프로세스의 일부로 수행됩니다.

//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 그리고 TraceTool


보다 여기 Delphi IDE의 이벤트 로그 창에 쓰려는 경우.

D5로 간단한 이벤트 로깅의 경우 다음 코드를 사용하여 응용 프로그램 로그에 메시지를 추가했습니다.

  • 사용 절에 "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;
    

나는 델파이 6에서 표준 VCL을 사용합니다. 델파이 5에서 이것을 사용할 수 있는지 여부를 말할 수 없습니다. 직접 시도해 보고이 물건이 D5에 있는지 알려주십시오.

  1. 유형 teventlogger의 글로벌/양식 변수를 선언합니다. 이것은 SVCMGR 장치에서 선언 되므로이 장치는 귀하의 사용 목록에 추가되어야합니다. 이것이 정상적인 응용 프로그램 인 경우 (예 : 서비스가 아님) 양식 단위 후에 SVCMGR이 추가되어 있는지 확인하십시오.

    MyeventLog : TeventLogger;

  2. 로거 인스턴스를 만듭니다.

    myeventLog : = teventLogger.create ( 'myApplication');

  3. 이벤트 로그에 작성하려면 :

    myeventLog.logMessage ( 'myApplication start.'), eventLog_information_type);

  4. 마지막에 해제하는 것을 잊지 마십시오.

    myeventlog.free;

응용 프로그램을 Windows 이벤트 로그에 등록하기 위해 수행해야 할 다른 작업이 있습니다.

소스 (Microsoft Internet Explorer)의 이벤트 ID (1000)에 대한 설명을 찾을 수 없습니다. 로컬 컴퓨터에는 원격 컴퓨터에서 메시지를 표시하는 데 필요한 레지스트리 정보 또는 메시지 파일이 없을 수 있습니다. 다음 정보는 이벤트의 일부입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top