Einzelnen Beitrag anzeigen

Y.Elm

Registriert seit: 19. Sep 2011
Ort: Berlin
21 Beiträge
 
Delphi 2010 Professional
 
#1

Durch SHFileOperation gelöschte Ordner bleiben bis Programmende bestehen

  Alt 24. Jan 2013, 16:10
Hallo an alle,
ich habe mir eine DLL erstellt, die einen "Import"-Ordner überwachen soll (C:\Mein_Programm\Import\). Sobald in diesem Import-Ordner ein Unterverzeichnis mit Dateien erstellt wird, sendet die DLL die Liste der Dateien an das Hauptprogramm, welches diese dann importiert (also Datei verschiebt und Datenbank-Eintrag erzeugt).

Nach dem Importieren bleiben also leere Verzeichnisse in meinem Import-Ordner, welche ich anschließend mit der Funktion Clear() löschen möchte. Mein Problem ist, dass das Löschen offenbar fehlerfrei funktioniert (SHFileOperation gibt 0 zurück), aber die eigentlich gelöschten Verzeichnisse so lange existieren, bis das Hauptprogramm beendet wurde.
Im Detail heißt das:
  1. Beim Importieren werden alle Dateien in den Unterordnern gelöscht
  2. Nach dem Import (im Hauptprogramm) und vor dem Aufruf von Clear() (in der DLL) kann ich ohne Probleme Unterverzeichnisse im Windows-Explorer löschen. Deshalb nehme ich an, dass das Problem nicht in meinem Hauptprogramm liegt
  3. Nach dem Aufruf von Clear() verschwinden alle Unterordner aus dem Windows-Explorer
  4. Ich navigiere im Explorer einen Ordner aufwärts und wieder zurück in meinen Import-Ordner
  5. Alle "gelöschten" Unterordner sind wieder im Explorer zu sehen
  6. Beim Versuch, einen der "gelöschten" Ordner zu öffnen oder zu löschen, erhalte ich die Windows-Fehlermeldung "Zugriff verweigert"
  7. Mein Observer-Thread, der mit FindFirst() & FindNext() alle Unterordner im Import-Ordner zählt, zählt alle "gelöschten" Verzeichnisse mit
  8. Dieser Zustand hält auch nach dem Entladen der DLL im Hauptprogramm an
  9. Nach dem vollständigen Beenden des Hauptprogramms verschwinden alle "gelöschten" Ordner wieder und bleiben verschwunden

Der Löschvorgang findet in der DLL statt. Da der Quellcode recht lang ist, versuch ich es mal mit ner Mischung aus Delphi- und Pseudocode...
Delphi-Quellcode:
function Clear(H: THandle): Boolean; export; stdcall;
var
  searchRec : TSearchRec;
  dirList : Array of String;
  i: Integer;
begin
  if DirectoryExists(ImportPath) then begin
    Mit FindFirst() & FindNext() alle Verzeichnisnamen in dirList eintragen;
    FindClose(searchRec);
    for i := 0 to High(dirList) do begin
      Mit FindFirst() & FindNext() alle Dateien in dirList[i] finden;
      FindClose(searchRec);
      if keine Dateien gefunden then
        DeleteDirectory(dirList[i]); // siehe unten
    end;
  end;
end;

function DeleteDirectory(DirName : string): Boolean;
var
  SHFileOpStruct : TSHFileOpStruct;
  DirBuf : array [0..255] of char;
  res: Integer;
begin
  try
   Fillchar(SHFileOpStruct,Sizeof(SHFileOpStruct),0) ;
   FillChar(DirBuf, Sizeof(DirBuf), 0);
   StrPCopy(DirBuf, DirName);
   with SHFileOpStruct do begin
    Wnd := 0;
    pFrom := @DirBuf;
    pTo := nil;
    wFunc := FO_DELETE;
    fFlags := FOF_NOCONFIRMATION or FOF_SILENT;
   end;
    res := SHFileOperation(SHFileOpStruct); // res enthält immer 0, also kein Fehler
    Result := (res = 0) ;
   except
    Result := False;
  end;
end;
Mir scheint es so, als würde mein Programm oder meine DLL noch Handles zu den "gelöschten" Ordnern halten, aber ich verstehe nicht, wo. DirList ist nur ein Array of String, das kann keine Handles verwalten. Und die Suche nach Ordnern und Dateien habe ich mit FindClose() beendet, bevor die Ordner gelöscht werden. Außerdem gibt SHFileOperation() immer 0 zurück, also war die Aktion eigentlich erfolgreich.

Hat jemand Erfahrungen mit diesem oder einem ähnlichen Problem? Habe ich einen Fehler in meinem Programm oder ist das ein bekanntes Verhalten von Windows? (Ich arbeite hauptsächlich auf Windows 7 64 Bit, habe das gleiche Verhalten aber auch auf Windows XP beobachtet)
  Mit Zitat antworten Zitat