Reequipamento log de eventos do Windows para um aplicativo Delphi 5
Pergunta
Eu estou procurando um meio (razoavelmente livre de dor) de adicionar algum apoio Windows Application Event-Log para um pequeno legado Delphi 5 aplicação. Nós apenas queremos que log quando ele começa-se, fecha-down, não consegue se conectar a um banco de dados etc.
Várias das soluções / componentes que vi parecem sugerir que nós vamos precisar fazer uma DLL de recursos que o Visualizador de Log de Eventos do Windows irá conectar-se a ao tentar ler nossos 'entradas'. Enquanto isso não parece muito oneroso, eu acho que é outra coisa a ter em mente se / quando desenvolver a aplicação no futuro - nós vamos precisar manter esta DLL até à data.
Em algum ponto no futuro vamos querer transformar o aplicativo em um serviço, provavelmente escrito em D2007.
Então, alguém pode recomendar um trajecto adequado para a adição de eventos no log de eventos em D5? Eu estou procurando específica ' usamos este e foi ok ' comentários em vez de uma rede de arrasto Google (que eu posso fazer eu mesmo!) Grátis ou pagos para, realmente não importa - mas algo que eu poderia migrar para D2007 no futuro é importante.
Solução 4
Graças ao J e respostas de Pedro, eu tenho a minha escrita código em log de eventos imediatamente. Há um pouco mais para fazer, especialmente se você quer que seus eventos para aparecer 'bem' no registo de eventos sem uma mensagem padrão do Windows por não ser capaz de encontrar a descrição (de acordo com a parte inferior da J 's post).
Eu segui as dicas aqui para fazer uma DLL adequada e inserindo-o no registro, e muito rapidamente tinha tudo resolvido.
Este foi tudo em Delphi5, conforme a pergunta, mas não vi nada que me faz pensar que não seria também trabalho na D2007.
Outras dicas
Resumo: Escrevendo no log de eventos do Windows usando o Delphi
Se você estiver escrevendo um serviço e necessidade do Windows para gravar o log de eventos do Windows da máquina local então você pode chamar TService. LogMessage como mencionado aqui .
//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 qualquer outro tipo de aplicações que você pode usar o SvcMgr. TEventLogger indocumentados auxiliar de classe para TService para escrever o log de eventos do Windows da máquina local como mencionado aqui , aqui e aqui .
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;
Você também pode usar a API do Windows ReportEvent função como mencionado aqui e aqui .
Eu criei uma classe simples para torná-lo mais fácil, é disponível no 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 suportes escrever uma entrada de log para log de eventos, quer de uma máquina local ou remota. Para um exemplo remoto ver EDN de John Kaster artigo .
Note que você também teria de criar um arquivo de mensagem e registar o seu origem do evento caso contrário, todas as suas mensagens de log serão começando com algo como isto:
A descrição para Event ID xxx xxxx de origem não pode ser encontrado. Ou o componente que gera esse evento não está instalado no seu computador local ou a instalação está danificada. Você pode instalar ou reparar o componente no computador local.
Se o evento se originou em outro computador, a informação do mostrador tinha de ser salvo com o evento.
As informações a seguir foi incluído com o evento:
1, Para mais informações sobre como criar um arquivo de mensagem consulte Finn Tolderlund tutorial ou de Michael Hex artigo ou você pode usar um e RES arquivo MC existente incluído no o projeto GitHub .
2, incorporar o arquivo RES em sua aplicação, incluindo as MessageFile.res em seu arquivo DPR. Alternativamente, você pode criar uma dll para as mensagens.
program MyTestApp;
uses
Forms,
FormMain in 'FormMain.pas' {MainForm},
EventLog in 'EventLog.pas';
{$R *.res}
{$R MessageFile\MessageFile.res}
begin
Application.Initialize;
3, o registro, uma vez-off requer direitos de administrador escrevendo para o registro assim que nós geralmente feito como parte do processo de instalação do aplicativo.
//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 você tem necessidade de registro de eventos do Windows e outros requisitos de registro, você também pode usar o log de estruturas, como log4d e TraceTool
aqui se você quiser escrever para o log de eventos janela no Delphi IDE.
Para o registro de eventos simples na D5, tenho usado o seguinte código para adicionar mensagens aos aplicativos de registro.
- Adicionar "SvcMgr" na cláusula uses
-
Use este código para adicionar a sua mensagem de texto e um número de identificação (último parâmetro em linhas 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;
Eu uso VCL padrão para isso em Delphi 6, eu não posso dizer se este é ou não disponível em Delphi 5. Tente você mesmo e deixe-nos saber se este material é lá em D5.
-
Declare uma variável de formulário / global do tipo TEventLogger. Esta é declarado na unidade SvcMgr assim que esta unidade terá de ser adicionado à sua lista de usos. Se esta é uma aplicação normal (ou seja, não a Service), em seguida, certifique-se SvcMgr é adicionado após a unidade de formulários.
MyEventLog: TEventLogger;
-
Criar uma instância do registrador.
MyEventLog: = TEventLogger.Create ( 'MyApplication');
-
Para escrever no registo de eventos:
MyEventLog.LogMessage ( 'MyApplication começou.'), EVENTLOG_INFORMATION_TYPE);
-
Não se esqueça de lançá-lo no final:
MyEventLog.Free;
Há outras coisas que você precisa fazer para registrar o aplicativo com o Windows Event Log para que a mensagem aparece sem isso na frente dele:
A descrição para Event ID (1000) na origem (Microsoft Internet Explorer) não pode ser encontrada. O computador local pode não ter as informações de registro ou DLL mensagem arquivos necessários para exibir mensagens de um computador remoto. As seguintes informações são parte do evento: