Avatar billede safl Nybegynder
20. juni 2005 - 23:45 Der er 6 kommentarer og
1 løsning

Evenlog hint

Hello!

Har denne lille snippet kode:

var
  lLog: THandle;
  lEvent: THandle;
  lResult: Cardinal;

begin
  lLog := OpenEventLog(nil, PChar('Security'));
  // create unnamed object
  lEvent := CreateEvent(nil, True, False, nil);
  // start the event log change notification
  NotifyChangeEventLog(lLog, lEvent);

  // reset event signal, so the system can signal it again
  ResetEvent(lEvent);

  repeat
    // wait for event to be signalled.
    if WaitForSingleObject(lEvent, INFINITE)=WAIT_OBJECT_0 then
    begin
      Memo1.Lines.Add('Changed at ' + DateTimeToStr(Now()));
      Application.ProcessMessages;
    end;
    // wait for change again
  until lTerminated;

Denne klump skulle være i stand til at fortælle når der blev foretaget skrivninger til windows eventlog. Problemet er at jeg ikke kan compile koden da Delphi siger "Undeclared identifier" ved lTerminated.

Er der nogle af jer der kan gennemskue hvad lTerminated skal være for at det virker? Koden er herfra:
http://bdn.borland.com/article/0,1410,32435,00.html#create_notify

mvh Simon
Avatar billede tolderlund Nybegynder
21. juni 2005 - 12:39 #1
Der fremgår ikke af artiklen, men det eneste det kan være er en boolean variabel (defineret som en variabel tilhørende formen eller som en global variabel) der sættes til true et andet sted når brugeren ønsker at stoppe programmet eller repeat loopet.
Avatar billede safl Nybegynder
21. juni 2005 - 14:45 #2
Hmm ok, hvor ville det være hensigtsmæssigt at starte selve proceduren?

Så hvis jeg erklærer en global variabel med navn lTerminated af typen boolean med værdi false. Og så sætte den til true når jeg ikke ønsker at køre mere så spiller det?
Avatar billede safl Nybegynder
21. juni 2005 - 18:30 #3
Hmm kan simpelthen ikke få det til at virke. Programmet fryser bare og foretager sig ingenting. Temmelig irriterende.

Nogen der har en ide hvordan man kan få notifications fra eventloggen? Så ens program får at vide så snart der skrives til den? Og derefter læse hvad der er blevet skrevet?
Avatar billede hrc Mester
07. august 2005 - 00:39 #4
Nu har jeg læst artiklen og der står jo hvordan man læser fra loggen.

Hvad angår notification-delen, så har jeg lavet det til en tråd:

uses
  Classes, Windows, SysUtils;

type
  TEventNotification = class(TThread)
  private
    fLog : TStrings;
  protected
    procedure Log;
    procedure Execute; override;
  public
    constructor Create(aLog : TStrings); reintroduce;
  end;

implementation

{ TEventNotification }

constructor TEventNotification.Create(aLog: TStrings);
begin
  fLog := aLog;
  FreeOnTerminate := true;
  inherited Create(false);
end;

procedure TEventNotification.Execute;
var
  lLog: THandle;
  lEvent: THandle;
begin
  lLog := OpenEventLog(nil, PChar('Application'));
  lEvent := CreateEvent(nil, True, False, nil);
  NotifyChangeEventLog(lLog, lEvent);
  ResetEvent(lEvent);
  repeat
    if WaitForSingleObject(lEvent, INFINITE)=WAIT_OBJECT_0 then
      Synchronize(Log);
  until Terminated;
end;

procedure TEventNotification.Log;
begin
  fLog.Add('Changed at ' + DateTimeToStr(Now()));
end;

Mit main-program kører en rettet version af Serge Dosyukovs "skriv til log" procedure. Bemærk, at 'Application' er loggen. Dette angives både i tråd og nedenfor.

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  fThread := TEventNotification.Create(mLog.Lines);
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
  fThread.Terminate;
end;

procedure TfrmMain.btnWriteToLogClick(Sender: TObject);
var
  lEventLog  : THandle;
  lValue      : PChar;
  lLength    : integer;
  lSomeString : string;
begin
  // when application is started
  lEventLog := RegisterEventSource(nil, PChar('Application'));

  // this is just temp varuable
  lSomeString := 'A test event message';
  lLength := Length(lSomeString) + 2;
  // Allocate memory and copy string
  lValue := AllocMem(lLength);
  StrPCopy(lValue, lSomeString);
  // Information type record is created
  ReportEvent(lEventLog, EVENTLOG_INFORMATION_TYPE, 0, 0, nil, 1, 0, @lValue, nil);

  // when application is about to be closed
  if (lEventLog <> 0) then
    DeregisterEventSource(lEventLog);
end;
Avatar billede hrc Mester
07. august 2005 - 00:41 #5
Umiddelbart så er det et skridt på vejen, men mine notifications kommer ikke i samme hast som jeg banker data ind i loggen. Interessant emne. Arbejder videre på det om jeg får tid
Avatar billede hrc Mester
07. august 2005 - 00:56 #6
Nå. Trådens loop fik lige en loop(0) sat ind.

Main-delen ser nu således ud (kunne bl.a. ikke lide variabelnavnene).

type
  TfrmMain = class(TForm)
    btnWriteToLog: TButton;
    mLog: TMemo;
    eLogText: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnWriteToLogClick(Sender: TObject);
  private
    fEventLog : THandle;
    fThread : TEventNotification;
  public
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  fThread := TEventNotification.Create(mLog.Lines);
  fEventLog := RegisterEventSource(nil, PChar('Application'));
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
  fThread.Terminate;
  if (fEventLog <> 0) then
    DeRegisterEventSource(fEventLog);
end;

procedure TfrmMain.btnWriteToLogClick(Sender: TObject);
var
  buffer : PChar;
  lgd : integer;
  st : string;
begin
  st := eLogText.Text;
  lgd := Length(st) + 2; // én burde da være nok, men jeg gider ikke tjekke
  buffer := AllocMem(lgd);
  try
    StrPCopy(buffer, st);
    ReportEvent(fEventLog, EVENTLOG_INFORMATION_TYPE, 0, 0, nil, 1, 0, @buffer, nil);
    Application.ProcessMessages;
  finally
    FreeMem(buffer);
  end;
end;

end.

Når der sættes data ind i loggen, så styres notifikationen af en funktion der hedder PulseEvent (Microsoft) og det sker kun hvert 5 sekund. Ved flere events indenfor dette 5s slot trigger altså kun den første. Derfor ustabiliteten.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester