Retrofitting registro eventi di Windows ad un Delphi 5 app
Domanda
Sto cercando un (abbastanza indolore) i mezzi di aggiunta di un po 'di supporto di Windows Application Event-Log a una piccola eredità Delphi 5 applicazione. Vogliamo solo che per accedere quando inizia-up, chiude verso il basso, non riesce a connettersi a un database, ecc
Molte delle soluzioni / componenti che ho visto sembrano suggerire che avremo bisogno di fare una DLL risorsa che il registro Visualizzatore eventi di Windows si collegherà a quando si cerca di leggere i nostri 'voci'. Anche se questo non sembra troppo oneroso, Credo che sia qualcos'altro da tenere a mente se / quando sviluppiamo ulteriormente l'applicazione in futuro - avremo bisogno di mantenere questa DLL aggiornata.
Ad un certo punto in futuro vorremo trasformare l'applicazione in un servizio, probabilmente scritto in D2007.
Quindi, chiunque può consigliare un itinerario adatto per l'aggiunta di eventi nel registro eventi in D5? Sto cercando specifica ' abbiamo usato questo e non era male ' commenti, piuttosto che una rete a strascico di Google (che posso fare io!) Gratis oa pagamento-per, in realtà non importa - ma qualcosa che ho potuto migrare a D2007 in futuro è importante.
Soluzione 4
Grazie a J e le risposte di Pietro, ho ottenuto il mio codice di scrittura in caso di log immediatamente. C'è un po 'di più da fare, soprattutto se si desidera che le manifestazioni di apparire 'bene' nel registro eventi senza un messaggio standard di Windows di non essere in grado di trovare la descrizione (come per il fondo di J s 'post).
Ho seguito i suggerimenti di qui a fare una DLL adatto e di entrare nel registro di sistema, e molto rapidamente se fosse tutto risolto.
Questo era tutto in Delphi5, come per la domanda, ma ho visto niente che mi fa pensare che non avrebbe funzionato anche in D2007.
Altri suggerimenti
Sommario: scrittura nel registro eventi di Windows utilizzando Delphi
Se si sta scrivendo un servizio di Windows e la necessità di scrivere al registro eventi di Windows del computer locale, allora è possibile chiamare TService. LogMessage come qui .
//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;
In qualsiasi altro tipo di applicazioni che è possibile utilizzare lo SvcMgr. TEventLogger non documentata classe helper per TService per scrivere il registro eventi di Windows del computer locale come detto qui , qui e qui .
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;
È inoltre possibile utilizzare l'API di Windows ReportEvent funzione come detto qui e qui .
Ho creato una semplice classe per rendere più facile, è disponibili su 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 supporta la scrittura di una voce di registro per registro eventi sia una macchina locale o remoto. Per un esempio remota vedere di John Kaster EDN articolo .
Nota che si avrebbe anche per creare un file di messaggi e registrare il origine eventi in caso contrario tutti i messaggi di log sarà a partire con qualcosa di simile:
La descrizione per l'ID evento xxx xxxx da fonte non può essere trovato. Il componente che genera questo evento non è installato computer locale o l'installazione è danneggiata. È possibile installare o riparare il componente sul computer locale.
Se l'evento ha avuto origine in un altro computer, le informazioni sul display doveva essere salvato con l'evento.
Le seguenti informazioni è stato incluso con l'evento:
1, Per ulteriori informazioni su come creare un file di messaggio vedere di Finn Tolderlund esercitazione o di Michael Hex articolo oppure è possibile utilizzare un MC esistente e file di RES compresi nel il progetto GitHub .
2, incorporare il file nella vostra applicazione del RES includendo le MessageFile.res nel file DPR. In alternativa è possibile creare una DLL per i messaggi.
program MyTestApp;
uses
Forms,
FormMain in 'FormMain.pas' {MainForm},
EventLog in 'EventLog.pas';
{$R *.res}
{$R MessageFile\MessageFile.res}
begin
Application.Initialize;
3, L'iscrizione una tantum richiede diritti di amministratore di scrittura al Registro di sistema in modo che noi di solito fatto come parte del processo di installazione dell'applicazione.
//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;
Se avete bisogno di registrazione degli eventi di Windows e di altri requisiti di registrazione è anche possibile utilizzare quadri di registrazione, come log4d e TraceTool
qui se si desidera scrivere nel registro eventi finestra nella IDE Delphi.
Per la semplice registrazione degli eventi in D5, ho usato il seguente codice per aggiungere messaggi alle applicazioni log.
- Aggiungi "SvcMgr" alla clausola di usi
-
Utilizza questo codice per aggiungere il vostro messaggio di testo e un numero ID (ultimo parametro sulle linee 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;
Io uso standard di VCL per questo in Delphi 6, non posso dirvi se questo è disponibile in Delphi 5. Provare per credere e farci sapere se questa roba è lì in D5.
-
Dichiarare una forma variabile globale / di tipo TEventLogger. Questo è dichiarato nell'unità SvcMgr così dovrà essere aggiunto alla tua lista usi questa unità. Se si tratta di una normale applicazione (vale a dire non a Service) quindi assicurarsi SvcMgr viene aggiunto dopo che l'unità Forms.
MyEventLog: TEventLogger;
-
Crea un'istanza del registratore.
MyEventLog: = TEventLogger.Create ( 'MyApplication');
-
Per scrivere nel registro eventi:
MyEventLog.LogMessage ( 'MyApplication iniziato.'), EVENTLOG_INFORMATION_TYPE);
-
Non dimenticate di rilasciarlo alla fine:
MyEventLog.Free;
Non v'è altra roba che devi fare per registrare l'applicazione con il registro eventi di Windows in modo che venga visualizzato il messaggio senza questo di fronte ad essa:
La descrizione per l'identificazione di evento (1000) nell'origine (Microsoft Internet Explorer) non può essere trovata. Il computer locale non può avere i file di informazioni Registro di sistema o DLL messaggio necessari per visualizzare i messaggi da un computer remoto. Le seguenti informazioni sono parte dell'evento: