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 Ordner löschen, auch wenn darauf zugegriffen wird (https://www.delphipraxis.net/138944-ordner-loeschen-auch-wenn-darauf-zugegriffen-wird.html)

e-gon 20. Aug 2009 10:22


Ordner löschen, auch wenn darauf zugegriffen wird
 
Hallo Delphifreunde,

ich muss Daten von mehreren Festplatten auf einer zusammenfassen. Um die ganzen doppelten Datei herauszufinden, Dateien umzubenennen usw. habe ich mir viele kleine Helferlei programmiert. Leider benutzen diese fast alle ShellTreeView oder FileListBox. Und wenn ich dann endlich ein doppeltes Verzeichnis gefunden habe und es im Windows-Explorer löschen will bekomme ich nur zur Antwort "Der Ordner BlaBla kann nicht entfernt werden: Die Datei wird von einer anderen Person bzw. einem anderen Programm verwendet. Schließen Sie alle Programme, die die Datei eventuell verwenden können, und wiederholen Sie den Vorgang."

Da ich aber keine Lust habe zum Löschen eines dämlichen Ordners sämtliche Helferlei zu schließen (und auch wieder zu öffnen!), nur weil diese irgendwann mal auf das Verzeichnis zugegriffen haben, schreibe ich ein weiteres Helferlei. Das Problem ist allerdings, dass es mir auch mit SHFileOperation und RemoveDir nicht gelingt den Ordner zu löschen.

Kennt jemand eine Möglichkeit ein Verzeichnis zu löschen, sch**ßegal wer oder was auch immer darauf zugreift?

Gruß eines verzweifelten
E-gons

himitsu 20. Aug 2009 10:32

Re: Ordner löschen, auch wenn darauf zugegriffen wird
 
Deine Helferlein müssen nur nach dem Auslesen die Datei-/Verzeichnishandles wieder freigeben, dann gibt's da auch keine Probleme mehr :zwinker:

OK, TOpenDialog und Co. halten in einem Thread oftmals einige handles offen, aber dafür hab ich irgendwo noch 'nen "Patch" ... müßte ich mal suchen bzw. es kann ja mal wer die Beiträge zu meinem FileSplitter durchsuchen, ich glaub da hatte ich dieses mal erwähnt. :gruebel:

Zitat:

Kennt jemand eine Möglichkeit ein Verzeichnis zu löschen, sch**ßegal wer oder was auch immer darauf zugreift?
nein, sowas gibt's nicht

Man kann aber die Handles freigeben, welche von anderen Programmen genutzt werden (Stichwort: Unlocker),
oder man sagt Windows, daß es einen Ordner/Datei nach dem nächsten Neustart löschen soll (wo diese ja dann wohl frei sind)

e-gon 20. Aug 2009 10:45

Re: Ordner löschen, auch wenn darauf zugegriffen wird
 
Hallo himitsu,

vielen Dank für die schnelle Antwort.

Mit Handles kenne ich mich nicht aus, werde aber mal recherchieren...

Gruß
E-gon

Luckie 20. Aug 2009 10:55

Re: Ordner löschen, auch wenn darauf zugegriffen wird
 
Zitat:

Zitat von e-gon
Mit Handles kenne ich mich nicht aus, werde aber mal recherchieren...

:mrgreen: Wenn ich so was lese muss ich immer grinsen. Das Handle Konzept ist ein essentieller Bestandteil von Windows. Und man sollte als Entwickler eigentlich damit vertraut sein. Ist ungefähr so, als wenn sich ein Automechaniker nicht mit Zylinderkopfdichtungen auskennt:
"Der Motor verbrennt nicht richtig. Könnte an der Zylinderkopfdichtung liegen."
"Ja wissen Sie, mit Zylinderkopfdichtungen kenne ich mich nicht so, aber ich werde mal Recherchieren. Mein Spezialgebiet sind eigentlich Zündkerzen."
;)

e-gon 20. Aug 2009 13:29

Re: Ordner löschen, auch wenn darauf zugegriffen wird
 
@Luckie:

Das kann ich jetzt natürlich nicht so stehen lassen. Ich bin eigentlich Spezialist für Datenmigration. Mein einziger Berührungspunkt mit dem "Handle Konzept" ist das Einlesen und Schreiben der Daten.

Oder um bei Deinem Beispiel zu bleiben: Ein Karosserieblechner gehört auch zu den Automechanikern. Den brauchen jedoch die Zylinderkopfdichtungen nicht zu interessieren. Und nebenbei gesagt verdient er auch noch besser. ;-)

@all:
Aber zurück zum Thema.

Wie es aussieht habe ich nun zwei Möglichkeiten
1. Meinen Helferlein das Handle unter den Füßen wegziehen oder
2. Bei meinen Helferlein die Verzeichnishandles wieder freigeben

Das mit dem Handle Wegziehen ist nicht unbedingt die feine Art. Deshalb würde ich doch eher zweiteres bevorzugen.

@himitsu:
Könntest Du das mit dem Freigeben von Datei-/Verzeichnishandles bei Dialogsobjekten bitte etwas genauer beschreiben?

shmia 20. Aug 2009 17:40

Re: Ordner löschen, auch wenn darauf zugegriffen wird
 
Um ein geöffnete File von einem anderen Prozess zu löschen, muss man tief ins Betriebssystem einsteigen.
Es gibt einige Tools, die das können, aber wahrscheinlich keinen Sourcecode dafür.
http://ccollomb.free.fr/unlocker/

Ich muss mich berichtigen - es gibt Sourcecode:
http://www.codeguru.com/Cpp/W-P/file...cle.php/c1287/

e-gon 21. Aug 2009 07:49

Re: Ordner löschen, auch wenn darauf zugegriffen wird
 
Danke shmia, aber wie schon gesagt würde ich inzwischen die Möglichkeit bevorzugen bei den Helferlein nach dem Auslesen des Verzeichnisses das Verzeichnishandle einfach wieder freizugeben. Wie auch immer das funktioniert...

himitsu 21. Aug 2009 08:21

Re: Ordner löschen, auch wenn darauf zugegriffen wird
 
Es kommt ja erstmal drauf an, was genau für Komponenten/Funktionen und wie du sie benutzt.

e-gon 21. Aug 2009 08:30

Re: Ordner löschen, auch wenn darauf zugegriffen wird
 
Ok, ich habe jetzt Testweise die FileListBox durch eine einfache ListBox ersetzt (LBFile) und lese das Verzeichnis wie folgt selbst aus:

Delphi-Quellcode:
procedure TForm1.ReadLBFile(Path: string);
var FileExt: string;
     FileInfo: TSearchRec;
begin
  LBFile.Clear;
  if FindFirst(Path+'*.*',0, FileInfo)=0 then begin
    repeat
      FileExt:= UpperCase(ExtractFileExt(FileInfo.Name));
      if FileExt='.TXT' then
        LBFile.Items.Add(FileInfo.Name);
    until FindNext(FileInfo)<>0;
    FindClose(FileInfo);
  end;
end;
Obwohl ich FileInfo ordnungsgemäß schließe, lassen sich zwar die Dateien nicht aber der Ordner, in denen sich die Dateien befinden, von anderen Programmen löschen. Was muss ich tun um den ausgelesenen Ordner für andere Programme wieder zum Löschen freizugeben ohne gleich das ganze Programm schließen zu müssen?

e-gon 21. Aug 2009 08:55

Re: Ordner löschen, auch wenn darauf zugegriffen wird
 
Bei der ShellTreeView-Komponente ist es genauso. Einmal ein Verzeichnis selektiert kann man dieses mit einem anderen Programm nicht mehr löschen, selbst wenn im ShellTreeView längst ein anderer Ordner ausgewählt und das zu löschende Verzeichnis noch nicht mal eingeblendet ist.

Deshalb wollte ich schlau sein und habe ShellTreeView durch die Funktion SelectDirectory ersetzt. Aber gleiches Spiel! Die ausgewählten Verzeichnisse lassen sich erst nach dem Beenden des Programms von anderen Programm löschen...

Satty67 21. Aug 2009 08:59

Re: Ordner löschen, auch wenn darauf zugegriffen wird
 
Ist der Ordner nach einer Operation der Default-Pfad? Vielleicht mit SetCurrentDir('C:\') anders setzten, damit der Ordner quasi nicht mehr benutzt wird.

Ansonsten, wie löscht Du die Ordner?

e-gon 21. Aug 2009 09:15

Re: Ordner löschen, auch wenn darauf zugegriffen wird
 
Als ich noch mit der FileListBox gearbeitet habe, setzte ich die Eigenschaft Directory nach dem Auslesen bereits erfolglos auf 'C:\', was wohl den gleichen Effekt wie SetCurrentDir('C:\') hat. Aber ich versuche es trotzdem mal...
Bei der ShellTreeView-Komponente bringt das allerdings wenig.

Das Löschen versuchte ich schon auf die verschiedensten Arten. Vom Druck auf die Entferntaste im Windows-Explorer bis hin zu den Schweizern habe ich schon alles mögliche ausprobiert.

himitsu 21. Aug 2009 09:18

Re: Ordner löschen, auch wenn darauf zugegriffen wird
 
Zitat:

Delphi-Quellcode:
procedure TForm1.ReadLBFile(Path: string);
var FileExt: string;
     FileInfo: TSearchRec;
begin
  LBFile.Clear;
  if FindFirst(Path+'*.*',0, FileInfo)=0 then begin
    repeat
      FileExt:= UpperCase(ExtractFileExt(FileInfo.Name));
      if FileExt='.TXT' then
        LBFile.Items.Add(FileInfo.Name);
    until FindNext(FileInfo)<>0;
    FindClose(FileInfo);
  end;
end;

also erstmal ... dieser Code funktioniert bei mir ganz normal und es bleibt auch nichts blockiert
(sicherheitshalber mal mit Delphi 7 getestet)

wobei da ein paar Fragen aufkommen:
- warum nicht gleich nach .TXT suchen?
- und sicher, daß bei dir alle gwünschten Dateien gefunden werden? (also nur die, welche kein einziges Attribut besitzen, wie z.B. faArchive)

Delphi-Quellcode:
procedure ReadLBFile(Path: string);
var FileInfo: TSearchRec;
begin
  LBFile.Clear;
  if FindFirst(Path + '*.txt', faAnyFile and not faDirectory, FileInfo) = 0 then begin
    repeat
      LBFile.Items.Add(FileInfo.Name);
    until FindNext(FileInfo) <> 0;
    FindClose(FileInfo);
  end;
end;

e-gon 21. Aug 2009 09:39

Re: Ordner löschen, auch wenn darauf zugegriffen wird
 
Du hast recht! Ich habe jetzt mal ein Beispiel ohne ShellTreeView gemacht und es tut. Dann liegt das Übel wohl alleine an ShellTreeView!

Warum ich nicht gleich nach *.txt suche liegt daran, dass es ja auch mehrere Dateiendungen gibt, nach denen man suchen könnte. Oder gibt es etwa eine Möglichkeit mit FindFirst gleichzeitig nach *.txt, *.doc und *.xls suchen zu lassen?

Und nochmal hast Du recht! Ich habe die Attribute vergessen. Danke für den Hinweis!

himitsu 21. Aug 2009 10:10

Re: Ordner löschen, auch wenn darauf zugegriffen wird
 
nee, mehrere Masken kann man leider nicht angeben, also dann isses schon OK so :angel:

ich hab das jetzt bei meinem SearchSameFiles praktisch in etwa so gelöst:
Delphi-Quellcode:
uses MatchTextUnit;

procedure TForm1.ReadFiles(const Path, Mask: String; List: TStrings);
var
  FileInfo: TSearchRec;
begin
  List.BeginUpdate;
  try
    List.Clear;
    if FindFirst(Path + '*.*', faAnyFile and not faDirectory, FileInfo) = 0 then begin
      repeat
        if MatchText(Mask, FileInfo.Name) then
          List.Items.Add(FileInfo.Name);
      until FindNext(FileInfo) <> 0;
      FindClose(FileInfo);
    end;
  finally
    List.EndUpdate;
  end;
end;
> MatchText

Delphi-Quellcode:
ReadFiles('C:\', '*.txt', LBFile);
ReadFiles('C:\Path\', '*.txt|*.doc', LBFile);
PS: es macht sich immer gut, wenn du GUI und Logik etwas trennst
z.B. spätere Umbauten sind dann einfacher und man kann den Code auch mal wiederverwenden


Bezüglich deiner ShellTreeView gibt es das Problem, daß sie immer wohl angezeigt wird.
Bei mir war es damals so, daß ich den OpenDirectoryDialog statisch aufgerufen hatte, vorher mir ansehn konnte, welche Handles vorhanden sind und nachher im Vergleich prüfen konnte, welche Handles neu waren.
Und da ich wußte, daß an anderen Stellen sich keine Handle währenddessen ändern konnten und ich wußte daß nix schlimmes passiert, wenn ich diese Handles nun selber bereinige, konnte ich die Unterschiede dann einfach selber beheben.

e-gon 21. Aug 2009 10:27

Re: Ordner löschen, auch wenn darauf zugegriffen wird
 
Vielen Dank für Eure Unterstützung (besonders Dir himitsu), aber ich habe die Nase jetzt voll! Ich stelle einen Linuxrechner daneben und mache die Verzeichnisse darüber ohne Rücksicht auf Verluste platt!!!

OldGrumpy 21. Aug 2009 11:24

Re: Ordner löschen, auch wenn darauf zugegriffen wird
 
Bei diesen Holzhammermethoden möchte ich meine Daten aber nicht mehr von Dir migrieren lassen :mrgreen:


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:11 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