Escribir en el registro de eventos de Windows usando Delphi
event-log (1)
¿Cómo puede mi aplicación Delphi escribir fácilmente en el Registro de eventos de Windows?
¿Cuál es la diferencia entre TEventLogger y ReportEvent? ¿Cómo uso la función ReportEvent?
Si está escribiendo un Servicio de Windows y necesita escribir en el Registro de eventos de Windows de la máquina local, puede llamar a TService. LogMessage como se menciona aquí .
//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;
Para cualquier otro tipo de aplicaciones puede usar el SvcMgr. TEventLogger clase de ayuda no documentada para TService para escribir el registro de eventos de Windows de la máquina local como se menciona aquí , aquí y aquí .
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;
También puede usar la función ReportEvent de API de Windows como se menciona aquí y aquí .
Creé una clase simple para que sea más fácil, está disponible en 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 admite escribir una entrada de registro en el registro de eventos de una máquina local o remota. Para un ejemplo remoto, vea el artículo EDN de John Kaster .
Tenga en cuenta que también deberá crear un archivo de mensaje y registrar su fuente de evento, de lo contrario, todos sus mensajes de registro comenzarán con algo como esto:
La descripción para el Id. De evento xxx de la fuente xxxx no se puede encontrar. O el componente que genera este evento no está instalado en su computadora local o la instalación está dañada. Puede instalar o reparar el componente en la computadora local.
Si el evento se originó en otra computadora, la información de la pantalla se debe guardar con el evento.
La siguiente información fue incluida con el evento:
1, Para obtener más información sobre cómo crear un archivo de mensaje, consulte el tutorial de Finn Tolderlund o el artículo de Michael Hex o puede usar un archivo MC y RES existente incluido en el proyecto GitHub .
2, incruste el archivo RES en su aplicación incluyendo el MessageFile.res en su archivo DPR. Alternativamente, puede crear un dll para los mensajes.
program MyTestApp;
uses
Forms,
FormMain in ''FormMain.pas'' {MainForm},
EventLog in ''EventLog.pas'';
{$R *.res}
{$R MessageFile/MessageFile.res}
begin
Application.Initialize;
3, el registro de una sola vez requiere la escritura de los derechos de administrador en el registro, por lo que usualmente lo hacemos como parte del proceso de instalación de su aplicación.
//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;
Si necesita el registro de eventos de Windows y otros requisitos de registro, también puede usar marcos de registro tales como log4d y TraceTool
Consulte aquí si desea escribir en la ventana Registro de eventos en Delphi IDE.