![]() |
Durch SHFileOperation gelöschte Ordner bleiben bis Programmende bestehen
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:
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:
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.
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; 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) |
AW: Durch SHFileOperation gelöschte Ordner bleiben bis Programmende bestehen
Was nicht direkt mit der Frage zu tun hat ist meine Frage.
Warum definierst du funktionen wenn keine der beiden in irgendeiner weise behandelt wird? H: THandle was für ein H: was tust du damit? gruss |
AW: Durch SHFileOperation gelöschte Ordner bleiben bis Programmende bestehen
Wie schon gesagt, der gesamte Quellcode ist deutlich länger, als hier gepostet.
Die DLL kann mehrere Import-Objekte verwalten, von denen jedes einen anderen Import-Ordner überwacht und sich anders verhalten kann. Damit die Clear-Funktion nicht blind alle Import-Ordner säubert, wird das Handle zu dem Import-Objekt übergeben, dessen Ordner gesäubert werden soll. Und die Ergebnisse der Funktionen werden natürlich auch ausgewertet. Ich wollte nur nicht hunderte Zeilen von Code posten, die mit dem eigentlichen Problem nichts zu tun haben. |
AW: Durch SHFileOperation gelöschte Ordner bleiben bis Programmende bestehen
So einen Effekt hatte ich auch schon einmal im Windows Explorer, da waren die Ordner aber manuell im Windows Explorer gelöscht worden. Ich hatte da das Antivirenprogramm (damals leider noch Antivir) in Verdacht als Ursache. Und die genannten Funktionen verursachen das jedenfalls nicht immer, da das in ähnlicher Form bei mir funktioniert.
Kannst du das vielleicht in ein kleines Demoprogramm verpacken, das bei dir das Problem zeigt? Denn dann ließe sich testen, ob das mit dem selben Programm auch woanders auftritt. |
AW: Durch SHFileOperation gelöschte Ordner bleiben bis Programmende bestehen
Liste der Anhänge anzeigen (Anzahl: 1)
So, das hat leider etwas länger gedauert.
Ich habe ein kleines Testprojekt mit einer Exe und einer DLL erstellt. Beide sind auf die zwingend nötigen Codezeilen zusammengeschrumpft, also bitte nicht wundern, wenn einige Zeilen sinnlos erscheinen. Verzeichnisstruktur: 000DeleteFolders = Projektdateien 000DeleteFolders\dcu = wie der Name schon sagt ... DCU-Verzeichnis 000DeleteFolders\source = alle *.pas und *.dfm Dateien 000DeleteFolders\binary = alle fertigen Kompilate 000DeleteFolders\binary\Import_Folder = Das Import-Verzeichnis, aus dem alle Unterverzeichnisse gelöscht werden sollen Der Ablauf: Die DLL überwacht den Import-Ordner und meldet der Exe importierbare Dateien per Callback, welche den Import-Button enabled. Beim Click auf den Import-Button ruft die Exe die Liste der Dateien aus der DLL ab und importiert (zu Testzwecken: löscht) alle Dateien. Der Clear-Button wird enabled. Ein Klick darauf ruft nur die Funktion Clear() der DLL auf, in der genau das eingangs beschriebene Problem zu beobachten ist. |
AW: Durch SHFileOperation gelöschte Ordner bleiben bis Programmende bestehen
Hat denn niemand eine Idee? Ist das Problem wenigstens auf anderen Rechnern / Betriebssystemen nachvollziehbar?
|
AW: Durch SHFileOperation gelöschte Ordner bleiben bis Programmende bestehen
Schick doch einfach ein refresh in welcher form auch immer an das jeweilige Fensterhandle (Ordner)
in dem sich die zu löschenden Dateien/Ordner befinden. gruss |
AW: Durch SHFileOperation gelöschte Ordner bleiben bis Programmende bestehen
In deiner
Delphi-Quellcode:
hast du für das zweite FindFirst (Zeile 277) das entsprechende FindClose vergessen.
function Clear()
|
AW: Durch SHFileOperation gelöschte Ordner bleiben bis Programmende bestehen
Oh man, da war ich wohl doppelt blind :oops:. Ich hab den Code im Original mehrmals untersucht und beim Ableiten des Testprojektes nochmal, und dieser blöde Fehler ist mir nicht aufgefallen ... :wall:
Mich hat nur verwundert, dass die Ordner noch bis zum Schließen der Hauptapplikation bestehen blieben. Ich dachte, wenn die DLL noch irgendwelche Handles benutzt, müssten die Ordner beim Entladen der DLL verschwinden. Vielen Dank an Björn Ole für die Lösung des Mysteriums, das bei genauer Betrachtung gar keins war. |
AW: Durch SHFileOperation gelöschte Ordner bleiben bis Programmende bestehen
[QUOTE=Y.Elm;1200463]
...
Delphi-Quellcode:
QUOTE]
...
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; Hallo, schau mal den folgenden Code an und ersetze die Unterschiede zu Deinem Code.
Delphi-Quellcode:
MfG,
uses ShellAPI;
function DeleteFiles(const AFile: string): boolean; var sh: SHFileOpStruct; begin ZeroMemory(@sh, SizeOf(sh)); with sh do begin Wnd := Application.Handle; wFunc := FO_DELETE; pFrom := PChar(AFile +#0); fFlags := FOF_SILENT or FOF_NOCONFIRMATION; end; result := SHFileOperation(sh) = 0; end; Beispielaufruf: procedure TForm1.Button1Click(Sender: TObject); begin if DeleteFiles('c:\test.txt') then //um eine Datei zu löschen ... if DeleteFiles('c:\test') then //um ein Verzeichnis zu löschen ... if DeleteFiles('c:\test\*.*') then // Um alle Dateien eines Verzeichnisses zu löschen ... end; Statt 'c:\test\*.*' kann z.B. auch 'c:\test\*.txt' übergeben werden, um alle Textdateien in einem Verzeichnis zu löschen. terence |
AW: Durch SHFileOperation gelöschte Ordner bleiben bis Programmende bestehen
Übrigens: Wenn schon Polling, dann tut der CPU z.B. ein Sleep(1000) innerhalb der Schleife im Thread ganz gut. Bessere Alternative:
![]() |
AW: Durch SHFileOperation gelöschte Ordner bleiben bis Programmende bestehen
Danke terence14 für die Optimierung.
@ Björn Ole: Ja, im Originalcode steht da irgendwo weiter unten ein
Delphi-Quellcode:
. Ist mir beim Ableiten des Testprojektes wohl abhanden gekommen, weil drüber noch einige Zeilen nicht relavten Codes stehen.
Sleep(ObserveIntervall);
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:48 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz