Keine der am 01.06.2018 veröffentlichten Antworten, mit Ausnahme der einzelnen Befehlszeile von foxidrive , hat wirklich alle Dateien und alle Ordner / Verzeichnisse in gelöscht %PathToFolder%
. Dies ist der Grund für das Posten einer weiteren Antwort mit einer sehr einfachen Befehlszeile zum Löschen aller Dateien und Unterordner eines Ordners sowie einer Batchdatei mit einer komplexeren Lösung, in der erklärt wird, warum alle anderen Antworten am 01.06.2018 mit DEL veröffentlicht wurden und FOR mit RD konnte einen Ordner nicht vollständig bereinigen.
Die einfache Einzelbefehlszeilenlösung, die natürlich auch in einer Batchdatei verwendet werden kann:
pushd "%PathToFolder%" 2>nul && ( rd /Q /S "%PathToFolder%" 2>nul & popd )
Diese Befehlszeile enthält drei Befehle, die nacheinander ausgeführt werden.
Der erste Befehl PUSHD überträgt den aktuellen Verzeichnispfad auf den Stapel und macht den nächsten%PathToFolder%
das aktuelle Verzeichnis zum Ausführen des Befehlsprozesses.
Dies funktioniert standardmäßig auch für UNC- Pfade, da Befehlserweiterungen standardmäßig aktiviert sind und in diesem Fall PUSHD erstellt einen temporären Laufwerksbuchstaben, der auf die angegebene Netzwerkressource verweist, und ändert dann das aktuelle Laufwerk und Verzeichnis mithilfe des neu definierten Laufwerksbuchstabens.
PUSHD gibt die folgende Fehlermeldung aus, um STDERR zu behandeln, wenn das angegebene Verzeichnis überhaupt nicht vorhanden ist:
Das System kann den angegebenen Pfad nicht finden.
Diese Fehlermeldung wird unterdrückt, indem sie 2>nul
an das Gerät NUL umgeleitet wird .
Der nächste Befehl RD wird nur ausgeführt, wenn das Ändern des aktuellen Verzeichnisses für den aktuellen Befehlsprozess in das angegebene Verzeichnis erfolgreich war, dh das angegebene Verzeichnis überhaupt existiert.
Der Befehl RD mit den Optionen /Q
und /S
entfernt leise ein Verzeichnis mit allen Unterverzeichnissen, auch wenn das angegebene Verzeichnis Dateien oder Ordner mit ausgeblendeten Attributen oder mit schreibgeschützten Attributen enthält. Das Systemattribut verhindert niemals das Löschen einer Datei oder eines Ordners.
Nicht gelöscht sind:
Ordner, die als aktuelles Verzeichnis für einen laufenden Prozess verwendet werden. Der gesamte Ordnerbaum eines solchen Ordners kann nicht gelöscht werden, wenn ein Ordner als aktuelles Verzeichnis für einen laufenden Prozess verwendet wird.
Dateien, die derzeit von einem laufenden Prozess geöffnet werden, wobei die Dateizugriffsberechtigungen für "Datei geöffnet" festgelegt sind, um das Löschen der Datei beim Öffnen durch die laufende Anwendung / den laufenden Prozess zu verhindern. Eine solche geöffnete Datei verhindert auch das Löschen des gesamten Ordnerbaums in der geöffneten Datei.
Dateien / Ordner, für die der aktuelle Benutzer nicht über die erforderlichen Berechtigungen (NTFS) zum Löschen der Datei / des Ordners verfügt, wodurch auch das Löschen des Ordnerbaums in diese Datei / diesen Ordner verhindert wird.
Der erste Grund, warum ein Ordner nicht gelöscht wird, wird von dieser Befehlszeile verwendet, um alle Dateien und Unterordner des angegebenen Ordners zu löschen, nicht jedoch den Ordner selbst. Der Ordner wird vorübergehend zum aktuellen Verzeichnis für die Ausführung des Befehlsprozesses gemacht, wodurch das Löschen des Ordners selbst verhindert wird. Dies führt natürlich zur Ausgabe einer Fehlermeldung mit dem Befehl RD :
Der Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen Prozess verwendet wird.
Datei ist hier der falsche Begriff, da der Ordner in Wirklichkeit von einem anderen Prozess verwendet wird, dem aktuellen Befehlsprozess, der den Befehl RD ausgeführt hat . Nun, in Wirklichkeit ein Ordner ist für das Dateisystem eine spezielle Datei mit Dateiattribut Verzeichnis , die diese Fehlermeldung erklärt. Aber ich möchte nicht zu tief in die Dateisystemverwaltung einsteigen.
Diese Fehlermeldung wird wie alle anderen Fehlermeldungen, die aus den drei oben genannten Gründen auftreten können, unterdrückt, indem sie 2>nul
vom Handle STDERR zum Gerät NUL umgeleitet wird .
Der dritte Befehl, POPD , wird unabhängig vom Exit-Wert des Befehls RD ausgeführt .
POPD öffnet den von PUSHD geposteten Verzeichnispfad vom Stapel und ändert das aktuelle Verzeichnis zum Ausführen des Befehlsprozesses in dieses Verzeichnis, dh stellt das ursprüngliche aktuelle Verzeichnis wieder her. POPD löscht den von PUSHD erstellten temporären Laufwerksbuchstaben im Falle eines UNC- Ordnerpfads .
Hinweis: POPD kann das ursprüngliche aktuelle Verzeichnis möglicherweise nicht wiederherstellen, wenn das anfängliche aktuelle Verzeichnis ein Unterverzeichnis des zu bereinigenden Verzeichnisses war, das nicht mehr vorhanden ist. In diesem Sonderfall %PathToFolder%
bleibt das aktuelle Verzeichnis. Es ist daher ratsam, die obige Befehlszeile nicht in einem Unterverzeichnis von auszuführen %PathToFolder%
.
Eine weitere interessante Tatsache:
Ich habe versucht, die Befehlszeile auch unter Verwendung eines UNC-Pfads zu verwenden, indem ich das lokale Verzeichnis C:\Temp
mit dem Freigabenamen freigegeben Temp
und den UNC-Pfad verwendet habe, \\%COMPUTERNAME%\Temp\CleanTest
der der Umgebungsvariablen PathToFolder
unter Windows 7 zugewiesen wurde . Wenn das aktuelle Verzeichnis beim Ausführen der Befehlszeile ein Unterverzeichnis eines freigegebenen lokalen Verzeichnisses ist Der Ordner, auf den über den UNC-Pfad zugegriffen wird C:\Temp\CleanTest\Subfolder1
, Subfolder1
wird von RD gelöscht , und das nächste POPD schlägt stillschweigend C:\Temp\CleanTest\Subfolder1
das aktuelle Verzeichnis wieder her, sodass es Z:\CleanTest
als aktuelles Verzeichnis für den ausgeführten Befehlsprozess verbleibt. In diesem ganz besonderen Fall bleibt der temporäre Laufwerksbuchstabe so lange bestehen, bis das aktuelle Verzeichnis beispielsweise mit geändert wirdcd /D %SystemRoot%
in ein wirklich vorhandenes lokales Verzeichnis. Leider wird POPDwird nicht mit einem Wert größer 0 beendet, wenn das ursprüngliche aktuelle Verzeichnis nicht wiederhergestellt werden kann, sodass es unmöglich ist, diesen ganz besonderen Fehlerzustand nur mit dem Exit-Code von POPD zu erkennen . Es kann jedoch davon ausgegangen werden, dass niemand jemals auf diesen ganz besonderen Fehlerfall stößt, da UNC-Pfade normalerweise nicht für den Zugriff auf lokale Dateien und Ordner verwendet werden.
Um die verwendeten Befehle noch besser zu verstehen, öffnen Sie ein Eingabeaufforderungsfenster, führen Sie dort die folgenden Befehle aus und lesen Sie die für jeden Befehl angezeigte Hilfe sorgfältig durch.
Einzelne Linie mit mehreren Befehlen Windows - Batch - Datei erklärt die Operatoren &&
und &
verwendet hier.
Als nächstes betrachten wir die Batch-Dateilösung mit dem Befehl DEL zum Löschen von Dateien in %PathToFolder%
und FOR und RD zum Löschen der Unterordner in %PathToFolder%
.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Clean the folder for temporary files if environment variable
rem PathToFolder is not defined already outside this batch file.
if not defined PathToFolder set "PathToFolder=%TEMP%"
rem Remove all double quotes from folder path.
set "PathToFolder=%PathToFolder:"=%"
rem Consisted the folder path only of double quotes?
if not defined PathToFolder goto EndCleanFolder
rem Remove a backslash at end of folder path.
if "%PathToFolder:~-1%" == "\" set "PathToFolder=%PathToFolder:~0,-1%"
rem Consisted folder path only of a backslash (with one or more double quotes)?
if not defined PathToFolder goto EndCleanFolder
rem Delete all files in specified folder including files with hidden
rem or read-only attribute set, except the files currently opened by
rem a running process which prevents deletion of the file while being
rem opened by the application, or on which the current user has not
rem the required permissions to delete the file.
del /A /F /Q "%PathToFolder%\*" >nul 2>nul
rem Delete all subfolders in specified folder including those with hidden
rem attribute set recursive with all files and subfolders, except folders
rem being the current directory of any running process which prevents the
rem deletion of the folder and all folders above, folders containing a file
rem opened by the application which prevents deletion of the file and the
rem entire folder structure to this file, or on which the current user has
rem not the required permissions to delete a folder or file in folder tree
rem to delete.
for /F "eol=| delims=" %%I in ('dir "%PathToFolder%\*" /AD /B 2^>nul') do rd /Q /S "%PathToFolder%\%%I" 2>nul
:EndCleanFolder
endlocal
Die Batch-Datei stellt zunächst sicher, dass die Umgebungsvariable PathToFolder
wirklich mit einem Ordnerpfad ohne doppelte Anführungszeichen und ohne Backslash am Ende definiert ist. Der Backslash am Ende wäre kein Problem, aber doppelte Anführungszeichen in einem Ordnerpfad könnten problematisch sein, da der Wert von PathToFolder
während der Ausführung der Batchdatei mit anderen Zeichenfolgen verkettet wird.
Wichtig sind die beiden Zeilen:
del /A /F /Q "%PathToFolder%\*" >nul 2>nul
for /F "eol=| delims=" %%I in ('dir "%PathToFolder%\*" /AD /B 2^>nul') do rd /Q /S "%PathToFolder%\%%I" 2>nul
Mit dem Befehl DEL werden alle Dateien im angegebenen Verzeichnis gelöscht.
- Die Option
/A
ist erforderlich, um wirklich alle Dateien zu verarbeiten, einschließlich Dateien mit dem versteckten Attribut, das DEL ohne Verwendung der Option ignorieren würde /A
.
- Die Option
/F
ist erforderlich, um das Löschen von Dateien mit dem schreibgeschützten Attributsatz zu erzwingen.
- Die Option
/Q
ist erforderlich, um mehrere Dateien stillschweigend zu löschen, ohne den Benutzer zu fragen, ob mehrere Dateien wirklich gelöscht werden sollen.
>nul
ist erforderlich, um die Ausgabe der für STDOUT geschriebenen Dateinamen auf das Gerät NUL umzuleiten , das nicht gelöscht werden kann, da gerade eine Datei geöffnet ist oder der Benutzer keine Berechtigung zum Löschen der Datei hat.
2>nul
ist erforderlich, um die Ausgabe der Fehlermeldung für jede Datei, die nicht vom Handle STDERR gelöscht werden kann, an das Gerät NUL umzuleiten .
Mit den Befehlen FOR und RD werden alle Unterverzeichnisse im angegebenen Verzeichnis entfernt. Wird for /D
aber nicht verwendet, da FOR in diesem Fall Unterverzeichnisse mit dem versteckten Attributsatz ignoriert. Aus diesem Grund for /F
wird die folgende Befehlszeile in einem separaten Befehlsprozess ausgeführt, der im Hintergrund mit gestartet wird %ComSpec% /c
:
dir "%PathToFolder%\*" /AD /B 2>nul
DIR- Ausgaben im Bare-Format aufgrund /B
der Verzeichniseinträge mit Attribut D
, dh der Namen aller Unterverzeichnisse im angegebenen Verzeichnis, unabhängig von anderen Attributen wie dem versteckten Attribut ohne Pfad. 2>nul
wird verwendet, um die von DIR ausgegebene Fehlermeldung in einem Verzeichnis, das vom Handle STDERR gefunden wurde, an das Gerät NUL umzuleiten .
Der Umleitungsoperator >
muss mit dem Caret-Zeichen ^
in der FOR- Befehlszeile maskiert werden, um als Literalzeichen interpretiert zu werden, wenn der Windows-Befehlsinterpreter diese Befehlszeile verarbeitet, bevor der Befehl FOR ausgeführt wird, der die eingebettete dir
Befehlszeile in einem separaten Befehlsprozess ausführt im Hintergrund.
FOR verarbeitet die erfasste Ausgabe, die für STDOUT eines gestarteten Befehlsprozesses geschrieben wurde. Dies sind die Namen der Unterverzeichnisse ohne Pfad, die niemals in doppelte Anführungszeichen gesetzt werden.
FOR mit Option /F
ignoriert leere Zeilen, die hier nicht vorkommen, da DIR mit Option /B
keine leeren Zeilen ausgibt.
FOR würde auch Zeilen ignorieren, die mit einem Semikolon beginnen, das das Standardzeichen für das Zeilenende ist. Ein Verzeichnisname kann mit einem Semikolon beginnen. Aus diesem Grund eol=|
wird das vertikale Balkenzeichen als Zeilenendezeichen definiert, dessen Name kein Verzeichnis oder keine Datei enthalten darf.
FOR würde die Zeile unter Verwendung von Leerzeichen und horizontaler Tabulator als Trennzeichen in Teilzeichenfolgen aufteilen und der angegebenen Schleifenvariablen nur die erste durch Leerzeichen / Tabulatoren getrennte Zeichenfolge zuweisen I
. Dieses Aufteilungsverhalten ist hier nicht erwünscht, da ein Verzeichnisname ein oder mehrere Leerzeichen enthalten kann. Daher delims=
wird eine leere Liste von Trennzeichen definiert, um das Verhalten der Zeilenteilung zu deaktivieren und der Schleifenvariablen I
immer den vollständigen Verzeichnisnamen zuzuweisen .
Der Befehl FOR führt den Befehl RD für jeden Verzeichnisnamen ohne Pfad aus. Aus diesem Grund muss in der RD- Befehlszeile der Ordnerpfad erneut angegeben werden, der mit dem Namen des Unterordners verknüpft ist.
Um die verwendeten Befehle und ihre Funktionsweise zu verstehen, öffnen Sie ein Eingabeaufforderungsfenster, führen Sie dort die folgenden Befehle aus und lesen Sie alle Hilfeseiten, die für jeden Befehl angezeigt werden, sorgfältig durch.
del /?
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
rd /?
rem /?
set /?
setlocal /?