Wie kann meine Delphi-App problemlos in das Windows-Ereignisprotokoll schreiben?Mit Delphi in das Windows-Ereignisprotokoll schreiben
Was ist der Unterschied zwischen TEventLogger und ReportEvent? Wie verwende ich die ReportEvent-Funktion?
Wie kann meine Delphi-App problemlos in das Windows-Ereignisprotokoll schreiben?Mit Delphi in das Windows-Ereignisprotokoll schreiben
Was ist der Unterschied zwischen TEventLogger und ReportEvent? Wie verwende ich die ReportEvent-Funktion?
Wenn Sie einen Windows-Dienst schreiben und müssen dem lokalen Computer des Windows-Ereignisprotokoll schreiben, dann können Sie TService.LogMessage wie erwähnt here nennen.
//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;
Für jede andere Art von Anwendungen, die Sie die SvcMgr verwenden können. TEventLoggerundocumented Hilfsklasse für TService zum Schreiben des Windows-Ereignisprotokolls des lokalen Rechners wie erwähnt here, here und here.
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;
Sie können auch die Windows-API-ReportEvent Funktion als here und here erwähnt.
Ich habe eine einfache Klasse erstellt, um es einfacher zu machen, es ist available on 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 unterstützt auf einem lokalen oder Remote-Rechner Ereignisprotokoll einen Protokolleintrag zu schreiben. Für ein Remote-Beispiel siehe John Kaster's EDN article.
Beachten Sie, dass Sie auch an create a message file und register your event source sonst alle Ihre Log-Meldungen wie diese werden beginnend mit etwas hätte:
Die Beschreibung für Ereignis-ID xxx von der Quelle xxxx nicht sein kann gefunden. Entweder ist die Komponente, die dieses Ereignis auslöst, nicht auf Ihrem lokalen Computer installiert oder die Installation ist beschädigt. Sie können installieren oder die Komponente auf dem lokalen Computer reparieren. Wenn das Ereignis von einem anderen Computer stammt, müssen die Anzeigeinformationen mit dem Ereignis gespeichert werden.
Die folgenden Informationen wurden mit dem Ereignis enthalten:
1, Für weitere Informationen darüber, wie eine Nachrichtendatei Finn Tolderlund's tutorial oder Michael Hex's article sehen erstellen oder Sie können eine vorhandene MC und RES file included in the GitHub project verwenden.
2, Betten Sie die RES-Datei in Ihre Anwendung ein, indem Sie MessageFile.res in Ihre DPR-Datei einfügen. Alternativ können Sie eine DLL für die Nachrichten erstellen.
program MyTestApp;
uses
Forms,
FormMain in 'FormMain.pas' {MainForm},
EventLog in 'EventLog.pas';
{$R *.res}
{$R MessageFile\MessageFile.res}
begin
Application.Initialize;
3, Die einmalige Registrierung erfordert Admin-Rechte für die Registrierung zu schreiben, so dass es uns in der Regel als Teil Ihrer Anwendung Installationsprozess durchgeführt.
//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;
Wenn Sie Windows-Ereignisprotokollierung benötigen und andere Protokollierung Anforderungen Sie auch Logging Frameworks wie log4d und TraceTool
Siehe here verwenden können, wenn Sie in das Ereignisprotokoll schreiben wollen Fenster in der Delphi-IDE.
Gut gemacht! Nur zu deinem Logbuch. Ich würde bevorzugen, dass ihre Methoden die Instanzmethoden und nicht die Klassenmethoden sind, um die sich wiederholende Ereignisquelle für das Registrieren und das Aufheben der Registrierung zu vermeiden. Ich würde die Ereignisquelle registrieren, wenn die Instanz der Klasse erstellt wird, und die Registrierung bei der Zerstörung aufheben. Oder machen Sie eine globale Threadvariable und initialisieren Sie sie einmal. – TLama
Wenn Sie die Registrierung bei der Vernichtung der Instanz aufheben, führt dies nicht dazu, dass vorhandene Ereignisprotokolleinträge nicht mehr gelesen werden können? Mit anderen Worten, die Instanz musste aktiv sein, damit der Operator alte Ereignisprotokolleinträge anzeigen konnte. Ich denke eher, dass die Registrierung der Ereignisquelle Teil der Installation und Aufhebung der Registrierung für die Deinstallation der ausführbaren Datei sein sollte. –
Hallo Tondrey, ich vermute, TLama meinte den "RegisterEventSource" API Aufruf, nicht "Registrieren Sie die Ereignisquelle, indem Sie sie der Registry hinzufügen" :-) –
Suche Stack Overflow für diese scheinbar einfache Frage gibt Antworten zwischen vielen Fragen verteilt. Ich habe eine neue einfache Frage erstellt und Zeit investiert, um die Antworten zu kombinieren und zusätzliche Informationen hinzuzufügen, die in den anderen Antworten nicht enthalten waren. Ich habe das getan, weil ich nicht zum ersten Mal nach dieser Antwort suchte und dachte, die detaillierte Antwort und das Beispielprojekt könnten auch anderen Menschen helfen. –
Sie hätten das bei der anderen Frage tun können. Es ist auch hier in Ordnung. Die Fragen sind jetzt verknüpft. Es ist alles gut. http://blog.stackoverflow.com/2010/11/dr-strangedupe-or-how-i-learned-to-stop-beorrying-and-love-duplication/ –
Ah ok, danke David, ich verstehe jetzt besser wie Es klappt. –