Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Einen Ordner komplett löschen (https://www.delphipraxis.net/70195-einen-ordner-komplett-loeschen.html)

qb-tim 26. Mai 2006 16:58


Einen Ordner komplett löschen
 
Delphi-Quellcode:
RemoveDir(Ordner)
Das ist der Befehl einen Ordner zu löschen - dies geht aber nur, wenn der Ordner leer ist... :?

Wie lösche ich ALLE sich in dem Ordner befindenden Dateien UND Ordner auch?

Hawkeye219 26. Mai 2006 17:22

Re: Einen Ordner komplett löschen
 
Hallo,

du könntest es so machen, wie es in diesem Thread beschrieben wird.

Gruß Hawkeye

SirThornberry 26. Mai 2006 17:25

Re: Einen Ordner komplett löschen
 
hier noch eine Variante:
Delphi-Quellcode:
procedure DeleteFiles(FilenameMask: String);
var LRec: TSearchRec;
    LPath: String;
begin
  if FindFirst(FilenameMask, faAnyFile, LRec) = 0 then
  begin
    LPath := ExtractFilePath(FilenameMask);
    repeat
      if (LRec.Name <> '.') and (LRec.Name <> '..') then
        DeleteFile(LPath + LRec.Name);
    until FindNext(LRec) <> 0;
  end;
  FindClose(LRec);
end;

function DeleteDirectory(ADirName: String): Boolean;
var LRec: TSearchRec;
begin
  DeleteFiles(ADirName + '\*');
  if FindFirst(ADirName + '\*', faDirectory + faHidden + faSysFile, LRec) = 0 then
  begin
    repeat
      if (copy(LRec.name, 1, 1) <> '.') and DirectoryExists(ADirName + '\' + LRec.Name) then
        DeleteDirectory(ADirName + '\' + LRec.Name);
    until FindNext(LRec) <> 0;
  end;
  FindClose(LRec);
  Result := RemoveDir(ADirName)
end;

himitsu 26. Mai 2006 17:30

Re: Einen Ordner komplett löschen
 
Oder mit Hier im Forum suchenSHFileOperation, obwohl ich es auch gern selber mache (wie oben beschrieben), denn da kann man notfalls auch mal etwas mehr Einfluß (z.B. 'ne genauere FehlerMeldung ausgeben, also auch mal an wlcher Datei es ganz genau hängt).

qb-tim 26. Mai 2006 18:00

Re: Einen Ordner komplett löschen
 
@ SirThornberry

Ich blicke leider nicht durch. :wiejetzt:

Nehmen wir an ich möchte den Ordner "C:\test" mitsamt den Inhalt löschen.

Wie wende ich dann deine Prozeduren in einer OnClick prozedur an?

SirThornberry 26. Mai 2006 18:05

Re: Einen Ordner komplett löschen
 
Dann musst du die Funktion DeleteDirectory aufrufen:
Delphi-Quellcode:
DeleteDirectory('c:\test');

qb-tim 26. Mai 2006 18:16

Re: Einen Ordner komplett löschen
 
[Fehler] Unit3.pas(129): Undefinierter Bezeichner: 'DeleteDirectory'

Klaus01 26. Mai 2006 18:26

Re: Einen Ordner komplett löschen
 
Wo hast denn Du die Prozeduren hingeschrieben.

Hast Du sie als Methode der Form zugewiesen? Das ist nicht nötig.

Grüße
Klaus

qb-tim 26. Mai 2006 18:29

Re: Einen Ordner komplett löschen
 
Ich habe Sie mit allen anderen Prozeduren (wie FormActivate oder ButtonClick)

Ich habe nichts anderes getan, als den Quellentext von SirThornberry und eine Zeile in einer OnClick prozedur hinzugefügt.

Klaus01 26. Mai 2006 18:32

Re: Einen Ordner komplett löschen
 
.. und steht diese OnClick Methode vor oder hinter den eingefügten Prozeduren?
Sie (die OnClick Methode) sollte dahinter stehen.

Grüße
Klaus

qb-tim 26. Mai 2006 18:38

Re: Einen Ordner komplett löschen
 
Danke!

Das war der fehler!

Glühwürmchen 6. Okt 2006 09:49

Re: Einen Ordner komplett löschen
 
Es gibt bereits sooo viele Threads zu dem Thema, daß ich mir einfach mal DEN hier rauspicke:

Thema: RemoveDir funzt nicht!
Unterthema: RemoveDir funzt manchmal(!) nicht.

Ich habe alle Threads in der DP wieder und wieder durchgelesen. Viele nutzen diese SHFileOperation-Funktion. Leider ruft die aber "ZeroMemory" oder sowas auf und mein Delphi 5 kann damit nichts anfangen.

Also habe ich die Funktionen von SirThornberry "DeleteFiles" und "DeleteDirectory" benutzt, in der Hoffnung, daß diese besser tun, als meine eigenen.
Naja, es war ein Versuch wert.

Folgendes Problem:
Ich lege im Programm (per Button-Klick) mit "ForceDirectories(Dir)" Verzeichnisse an, in die ich mit "CopyFile" Dateien hinein kopiere.
Gleich im nächsten Schritt (natürlich nur in der Testphase) lösche ich (per Button-Klick) alle gerade angelegten Verzeichnisse inklusive aller in ihnen enthaltenen Dateien wieder.

In allen Fällen werden restlos alle Dateien gelöscht. ABER:
Nur in 50 Prozent der Fälle werden auch alle Verzeichnisse gelöscht!
In den anderen 50 Prozent läßt das Programm ein paar LEERE Verzeichnisse zurück. Um nichts in der Welt ist mein Programm hinterher nochmal dazu zu bewegen, diese Leichen ebenfalls noch zu entfernen!
Lösche ich sie jedoch von Hand und starte einen neuen Durchlauf, mit den gleichen Startbedingungen, dann stehen die Chancen 1:2 daß diesmal alle Verzeichnisse gelöscht werden.

Lege ich von Hand Verzeichnisse an, löscht das Programm sie niemals!


Der folgende Quellcode kann von Euch so nicht ausprobiert werden, da Euch alle selbst geschrieben Methoden u.ä. fehlen. Er dient nur dazu, ein bißchen einen Überblick zu bekommen was ich tue...

Zum Kopieren:
Delphi-Quellcode:
  // Suche in jedem ...
  for iDvzIdx := 0 to ZSI.iGetAnzUnterDVZ - 1 do begin
    // ... der angegebenen Unter-Verzeichnisse ...
    if ZSI.bGetUnterDvzStatus((ZSI.slGetUnterDVZ)[iDvzIdx]) = TRUE then begin
      // ... nach jedem ...
      for iTypIdx := 0 to ZSI.iGetAnzTypenAM - 1 do begin
        // ... der ausgewählten Datei-Typen ...
        if ZSI.bGetDateiTypStatus((ZSI.slGetDateiTypenAM)[iTypIdx]) = TRUE then begin
          // ... und kopiere diese in´s Ziel-Verzeichnis.
          sQuelle := ZSI.sGetQuellDVZ + (ZSI.slGetUnterDVZ)[iDvzIdx] + '\';
          sTeilVerzeichnis := ZSI.sGetUnterDVZ_OhneErstes((ZSI.slGetUnterDVZ)[iDvzIdx]);
          sZiel := ZSI.sGetZielDVZ + '\' + sTeilVerzeichnis + '\';

          if SindFilesinDir(sQuelle, '*.' + (ZSI.slGetDateiTypenAM)[iTypIdx], TRUE) = TRUE then begin
            DirErzeugen(sZiel);
            sDatei := '*.' + (ZSI.slGetDateiTypenAM)[iTypIdx];
            CopyFiles(sQuelle, sZiel, sDatei, FALSE);
          end;
        end; // end - if
      end; // end - for
    end; // end - if
  end; // end - for
Zum Löschen:
Delphi-Quellcode:
function TFrmZipSave.DeleteDirectory(ADirName: String): Boolean;
var
  LRec   : TSearchRec;
 
begin
  DeleteFiles(ADirName + '\*');
  if FindFirst(ADirName + '\*', faDirectory, LRec) = 0 then
  begin
    repeat
      if (copy(LRec.name, 1, 1) <> '.') and DirectoryExists(ADirName + '\' + LRec.Name) then
        DeleteDirectory(ADirName + '\' + LRec.Name)
      ;
    until FindNext(LRec) <> 0;
  end;
  SysUtils.FindClose(LRec);

  result := RemoveDir(ADirName);
  if result = TRUE then begin
    iAnzDvzGeloescht := iAnzDvzGeloescht + 1;
    pnlErgebnis.Caption := IntToStr(iAnzDateienWeg) + ' Dateien und ' + 
                           IntToStr(iAnzDvzGeloescht) + ' Verzeichnisse gelöscht...';
    Application.ProcessMessages;
  end;
end; {*** DeleteDirectory ***}

procedure TFrmZipSave.DeleteFiles(FilenameMask: String);
var
  LRec   : TSearchRec;
  LPath  : String;
  bResult : Boolean;
   
begin
  if FindFirst(FilenameMask, faAnyFile + $80 + $2000, LRec) = 0 then begin
    LPath := ExtractFilePath(FilenameMask);
    repeat
      if (LRec.Name <> '.') and (LRec.Name <> '..') then begin
        // ggf. Schreibschutz entfernen
        If (LRec.Attr and SysUtils.faReadOnly) <> 0 then
          FileSetAttr(LPath + LRec.Name, LRec.Attr - SysUtils.faReadOnly)
        ;
       
        bResult := SysUtils.DeleteFile(LPath + LRec.Name);
        if bResult = TRUE then begin
          iAnzDateienWeg := iAnzDateienWeg + 1;
          pnlErgebnis.Caption := IntToStr(iAnzDateienWeg) + ' Dateien und ' + 
                                 IntToStr(iAnzDvzGeloescht) + ' Verzeichnisse gelöscht...';
          Application.ProcessMessages;
        end;
      end;
    until FindNext(LRec) <> 0;
  end;
  SysUtils.FindClose(LRec);
end; {*** DeleteFiles ***}
Meine Frage:
Woran kann es liegen, daß RemoveDir mal tut und mal nicht?
Gibt es vielleicht irgendwelche DateiAttribute, die ich noch abfragen sollte?

Luckie 6. Okt 2006 10:09

Re: Einen Ordner komplett löschen
 
Zitat:

Zitat von Glühwürmchen
Viele nutzen diese SHFileOperation-Funktion. Leider ruft die aber "ZeroMemory" oder sowas auf und mein Delphi 5 kann damit nichts anfangen.

Strukturen kann man auch mit Delphi-Referenz durchsuchenFillChar initialisieren.

Go2EITS 6. Okt 2006 10:16

Re: Einen Ordner komplett löschen
 
@Glühwürmchen
Button1 auf Form legen.
C:\test anlegen
Einige Dateien unter C:\test rein. Stetze einige Dateien auf Hidden oder Versteckt.
Button1 betätigen und Du wirst sehen: Alles gelöscht!
Selbst gerade probiert. Ich glaube DelDir ist Torrycode.

Delphi-Quellcode:
function DelDir(dir: string): Boolean; {$IFDEF INLINE}INLINE;{$ENDIF}
var
  fos: TSHFileOpStruct;
begin
  ZeroMemory(@fos, SizeOf(fos));
  with fos do
  begin
    wFunc := FO_DELETE;
    fFlags := FOF_SILENT or FOF_NOCONFIRMATION;
    pFrom := PChar(dir + #0);
  end;
  Result := (0 = ShFileOperation(fos));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
DelDir('C:\test');
if DirectoryExists('C:\test') then ShowMessage('DelDir fehlgeschlagen') else
ShowMessage('DelDir funktioniert');
end;
Und: Geht es jetzt?
Gruß Go2EITS

Glühwürmchen 6. Okt 2006 10:23

Re: Einen Ordner komplett löschen
 
@Go2EITS

Undefinierter Bezeichner: 'TSHFileOpStruct'

Was ist TorryCode?

@luckie
FillChar?
Habe die Hilfe gelsen, aber - was soll ich damit?

Luckie 6. Okt 2006 10:25

Re: Einen Ordner komplett löschen
 
ShellAPI eingebunden?

Go2EITS 6. Okt 2006 10:34

Re: Einen Ordner komplett löschen
 
@Glühwürmchen
Sorry, hab nicht aufgepasst und Uses mitgeteilt.
Filectrl unter USES für Directoryexits einfügen.


Torrycode?
Damit meine ich die hervorragenden Snippets für Delphi hier:
"Torrycode"
(Sucheseite) unter Tips kannst Du die die Kategorie "manuell" auswählen.

Glühwürmchen 6. Okt 2006 10:39

Re: Einen Ordner komplett löschen
 
ShellAPI und FileCtrl einzubinden haben das Compiler-Problem gelöst.

Aber das Programm tut nicht.
Alle rüberkopierten Dateien sind weg.
Das Verzeichnis wiedersteht jedoch dem Löschversuch: "DelDir fehlgeschlagen" (ABER ES IST DA!!)

Luckie 6. Okt 2006 10:41

Re: Einen Ordner komplett löschen
 
Was liefert denn SHFileOperation für einen Fehlercode zurück?

Glühwürmchen 6. Okt 2006 10:42

Re: Einen Ordner komplett löschen
 
hm, bei zwei weiteren Versuchen ging es.

Glühwürmchen 6. Okt 2006 10:48

Re: Einen Ordner komplett löschen
 
Weiß nicht, was in den ersten Versuchen schief ging, aber die letzten 20 Versuche waren alle erfolgreich.

Vielen Dank erstmal!

Luckie 6. Okt 2006 10:55

Re: Einen Ordner komplett löschen
 
Einen Fehlercode auszuwerten ist nie verkehrt. Auch wenn es anscheinend immer funktioniert. Wenn es mal nicht funktioniert, weiß man wemfalls warum.

Glühwürmchen 6. Okt 2006 11:08

Re: Einen Ordner komplett löschen
 
Jetzt hätte ich noch ein paar Fragen zum besseren Verständnis:

Delphi-Quellcode:
function DelDir(dir: string): Boolean; {$IFDEF INLINE}INLINE;{$ENDIF}
1. Was passiert bei --> {$IFDEF INLINE}INLINE;{$ENDIF} ?

Delphi-Quellcode:
var
  fos: TSHFileOpStruct;

begin
  ZeroMemory(@fos, SizeOf(fos));
  with fos do
  begin
    wFunc := FO_DELETE;
    fFlags := FOF_SILENT or FOF_NOCONFIRMATION;
    pFrom := PChar(dir + #0);
  end;
  Result := (0 = ShFileOperation(fos));
end;
2. Ich finde "ShFileOperation" nicht in der Hilfe. Was tut das?
3. Ich finde "ZeroMemory" nicht in der Hilfe. Was tut das?
4. Was bedeuten jeweils die Parameter?

Luckie 6. Okt 2006 11:13

Re: Einen Ordner komplett löschen
 
Das ist eine Windows-API Funktion, die nicht zum Delphi Sprachumfang gehört, also findet man sie auch nicht in der Delphi-Hilfe. Du musst im PSDK oder online im MSDN gucken: MSDN-Library durchsuchenSHFileOperation. (Eine Suche mit Google hätte aber auch schon geholfen.) Das gleiche gilt für ZeroMemory.

Glühwürmchen 6. Okt 2006 11:27

Re: Einen Ordner komplett löschen
 
Habe den Code jetzt in meine Anwendung eingebaut und ausprobiert und erhalte den ReturnCode 32.
'DelDir fehlgeschlagen'.

Luckie 6. Okt 2006 12:18

Re: Einen Ordner komplett löschen
 
Zitat:

C:\Dokumente und Einstellungen\mp>net helpmsg 32

Der Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen Prozess verwendet wird.


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