Einzelnen Beitrag anzeigen

BenjaminH

Registriert seit: 14. Okt 2004
Ort: Freiburg im Breisgau
713 Beiträge
 
Turbo Delphi für Win32
 

ReadDirectoryChangesW endet in einer Endlosschleife

  Alt 20. Mär 2007, 17:25
Hallo,
ich beschäftige mich seit einer Zeit mit MSDN-Library durchsuchenReadDirectoryChangesW
Das funktioniert im Allgemeinen auch. Nur nicht im besonderen.
Es passiert manchmal, dass ich eine Datei erstelle und dann das ganze stecken bleibt.
D.h. weitere Dateiänderungen nicht festgestellt werden, oder immer wieder dasselbe ausgegeben wird, und währenddessen andere Dateiänderungen auch nichts zu sagen haben.
Das passiert im Prinzip immer dann, wenn mit OpenOffice eine neue Datei angelegt wird. Ist meiner Meinung nach also reproduzierbar.
Was noch passierte ist folgendes:
Code:
\Verzeichnis\Date.odt - erstellt
\Verzeichis\ - geändert
\Verzeichnis\Date.odt - gelöscht
Alles was danach passierte wurde ignoriert, die Datei existierte aber definitiv.

Als ich in einer dieser "Endlosschleifen" das Programm beendet habe, endete das in einer AccessViolation, die ich im Thread vermute. Da der ja beim Terminate ruhig abgeschaltet werden müsste vermute ich den Fehler in der Repeat Schleife, damals hatte ich da das or terminated nicht drinnne.

Vll. weiß ja jemand eine Möglichkeit das zu unterbinden.

Vielen Dank,
Benjamin

Den Code, den ich verwende, habe ich hier irgendwo gefunden und eventuell leicht abgeändert.
Delphi-Quellcode:
procedure TFileMonitorThread.Execute;
var
  pBuf : Pointer;
  dwBufLen : DWORD;
  dwRead : DWORD;
  FNI : FILE_NOTIFY_INFORMATION;
  pWork : Pointer;
  sFileName : Widestring;

begin
  Self.FreeOnTerminate:=True;
  FhFile := CreateFile(PChar(FsDirPath),FILE_LIST_DIRECTORY or GENERIC_READ,
              FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil,
              OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
  if (FhFile = INVALID_HANDLE_VALUE) or (FhFile = 0) then
  Begin
    Self.Terminate;
    exit;
  End;
  dwBufLen := 65536;
  pBuf := AllocMem(dwBufLen);
  try
    while not terminated do begin
      if ReadDirectoryChangesW(FhFile,pBuf,dwBufLen,true,
                                FILE_NOTIFY_CHANGE_FILE_NAME or
                                FILE_NOTIFY_CHANGE_DIR_NAME or
                                FILE_NOTIFY_CHANGE_LAST_WRITE,
                                @dwRead,nil,nil) then
      begin
        pWork := pBuf;
        repeat//Ich vermute hier bleibt's stecken
          StrMove(@FNI,pWork,12);
          PChar(pWork) := PChar(pWork)+12;
          sFileName := StringOfChar(#00,FNI.dwFileNameLength);
          StrMove(@sFileName[1],pWork,FNI.dwFileNameLength);
          FsFileName := WideCharToString(PWideChar(sFileName));
          FsFileName := copy(FsFileName,1,length(FsFileName) shl 1);
          dwReason := FNI.dwAction;//GetReason(FNI.dwAction);
          Synchronize(AddReasonToMemo);
          Synchronize(AddFileToMemo);
          PChar(pWork) := PChar(pBuf)+FNI.dwNextEntryOffset;
        until (FNI.dwNextEntryOffset = 0) or (terminated);
      end else begin
        break;
      end;
    end;
  finally
    FreeMem(pBuf,dwBufLen);
  end;
end;
Benjamin
  Mit Zitat antworten Zitat