Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi ReadDirectoryChangesW endet in einer Endlosschleife (https://www.delphipraxis.net/88765-readdirectorychangesw-endet-einer-endlosschleife.html)

BenjaminH 20. Mär 2007 17:25


ReadDirectoryChangesW endet in einer Endlosschleife
 
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;

Christian Seehase 20. Mär 2007 17:53

Re: ReadDirectoryChangesW endet in einer Endlosschleife
 
Moin Benjamin,

der Code kommt mir so bekannt vor ;-)


Ich weiss, dass ich da irgendwo einen Schnitzer drin hatte.
Probier's mal mit

Delphi-Quellcode:
ZeroMemory(@FNI,SizeOf(FNI));
CopyMemory(@FNI,pWork,dwRead);
sResult     := trim(WideCharLenToString(@FNI.wFilename[1],FNI.dwFileNameLength));
PChar(pWork) := PChar(pWork)+FNI.dwNextEntryOffset;
im repeat/until, natürlich um das was Du brauchst ergänzt.
Wo der Thread in der Endlosschleife hängenbleibt kannst Du übrigens wohl recht schnell ermitteln, wenn Du es mal im Einzelschritt durchgehst. Ausserdem kannst Du auch einfach mal ein oder mehrere OutputDebugString, dann kannst Du Dir den Ablauf anschliessend noch einmal anschauen. (View\Debug Windows\Event Log)

BenjaminH 21. Mär 2007 16:32

Re: ReadDirectoryChangesW endet in einer Endlosschleife
 
Ja, funktioniert.
Danke! :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:34 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz