Entwickler-Ecke

Windows API - Ereignis bei Dateiänderungen


lambruco - Mi 23.07.03 17:44
Titel: Ereignis bei Dateiänderungen
Moin Forum;
als Newbie hab ich zwar keine Ahnung :oops: , aber gibt es ein Ereignis, wenn Dateien geändert werden und wie kann man es abfangen.
Ich möchte feststellen, wann zB in einer Log-Datei ein neuer Eintrag erfolgt ist und entsprechend reagieren.
Könnte mir gut vorstellen, das es da was gibt, oder??

mfg

Lars


Delete - Mi 23.07.03 18:23

In regelmäßigen das Dateidatum -zeit abfragen. Wurde die datei allerdings exklusiv geöffnet wirst du sie im geöffneten Zustand nicht einlesen können.


lambruco - Mi 23.07.03 19:44

daran hab ich auch schon gedacht, aber es geht eigentlich um folgendes: ich möchte eine art tail-funktion(UNIX) schreiben, dh. ich überwache eine textdatei und alle dateien die neu hinzukommen erscheinen in einem memofeld(wobei nur die neu hinzugefügten geladen werden).

nebenbei wollte ich in erfahrung bringen, ob windows vielleicht irgendein ereignis erzeugt, wenn eine datei geändert wird. wie ist es denn beim explorer, wenn ich dort auf aktualisieren gehe, wird dann alles neu geladen, oder schaut er nur nach veränderungen ??

Fragen über Fragen (und leider kein schlaues Buch zur Hand).


Delete - Do 24.07.03 02:29

Kuck mal hier: FindFirstChangeNotification.zip [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/findfirstchangenotification.asp]


lambruco - Do 24.07.03 10:37

:D

Perfekt, erstes Testprogramm lief sofort:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
procedure TForm1.Button1Click(Sender: TObject);
const
 R: array [false..true] of BOOL = (BOOL (0), BOOL (1));
var
 Notify: THandle;
 bool : boolean;
 dwWaitStatus : DWORD;
begin
 bool := True;

while bool do
  begin
    Notify:= FindFirstChangeNotification(PChar('c:\test\'), R[true], FILE_NOTIFY_CHANGE_FILE_NAME);
    if (Notify = INVALID_HANDLE_VALUE) and
       (getlasterror = ERROR_INVALID_PARAMETER) then
       begin
         button1.caption := 'ooops!';
         bool := False;
       end;
  dwWaitStatus := WaitForSingleObject( Notify, INFINITE);
  if dwWaitStatus = WAIT_FAILED then
     bool:=false;
  if dwWaitStatus = WAIT_OBJECT_0 then
    showmessage('Da war was');
  end;
end;


Danke, danke


Delete - Do 24.07.03 12:33

Ich würde es so machen (getestet):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
var
  bCancel: Boolean;

procedure TForm1.Button1Click(Sender: TObject);
var
 hNotify: THandle;
 dwWaitStatus : DWORD;
begin
  bCancel := FALSE;
  hNotify:= FindFirstChangeNotification(PChar('c:\'), TRUE, FILE_NOTIFY_CHANGE_FILE_NAME);
  if hNotify = INVALID_HANDLE_VALUE then
  begin
    RaiseLastOsError();
    exit;
  end;
  while (FindNextChangeNotification(hNotify)) and (bCancel = FALSE) do
  begin
    Application.ProcessMessages;
    dwWaitStatus := WaitForSingleObject(hNotify, 1000);
    if dwWaitStatus = WAIT_FAILED then
    begin
      RaiseLastOSError();
      break;
    end;
    if dwWaitStatus = WAIT_OBJECT_0 then
      showmessage('Da war was');
  end;
  FindCloseChangeNotification(hNotify);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  bCancel := TRUE;
end;

Mit INIFITE reagiert dein programm nicht mehr, es sei denn du packst das in einen Thread. Desweiteren läßt es sich nicht beenden, da es in der Schleife feststeckt. Außerdem hast du vergessen, die Beobachtung wieder freizugeben.