Aucune des réponses publiées le 2018-06-01, à l'exception de la ligne de commande unique publiée par foxidrive , n'a vraiment supprimé tous les fichiers et tous les dossiers / répertoires de %PathToFolder%
. C'est la raison de publier une réponse de plus avec une seule ligne de commande très simple pour supprimer tous les fichiers et sous-dossiers d'un dossier ainsi qu'un fichier de commandes avec une solution plus complexe expliquant pourquoi toutes les autres réponses publiées le 2018-06-01 en utilisant DEL et FOR avec RD n'a pas réussi à nettoyer complètement un dossier.
La solution simple de ligne de commande unique qui bien sûr peut également être utilisée dans un fichier batch:
pushd "%PathToFolder%" 2>nul && ( rd /Q /S "%PathToFolder%" 2>nul & popd )
Cette ligne de commande contient trois commandes exécutées l'une après l'autre.
La première commande PUSHD pousse le chemin du répertoire actuel sur la pile et fait ensuite%PathToFolder%
le répertoire actuel pour l'exécution du processus de commande.
Cela fonctionne également pour les chemins UNC par défaut car les extensions de commande sont activées par défaut et dans ce cas PUSHD crée une lettre de lecteur temporaire qui pointe vers cette ressource réseau spécifiée, puis modifie le lecteur et le répertoire actuels, en utilisant la lettre de lecteur nouvellement définie.
PUSHD affiche le message d'erreur suivant pour gérer STDERR si le répertoire spécifié n'existe pas du tout:
Le système ne peut pas trouver le chemin spécifié.
Ce message d'erreur est supprimé en le redirigeant 2>nul
vers le périphérique NUL .
La prochaine commande RD n'est exécutée que si le changement du répertoire en cours pour le processus de commande en cours vers le répertoire spécifié a réussi, c'est-à-dire que le répertoire spécifié existe.
La commande RD avec les options /Q
et /S
supprime discrètement un répertoire avec tous les sous - répertoires même si le répertoire spécifié contient des fichiers ou des dossiers avec un attribut masqué ou avec un ensemble d'attributs en lecture seule. L'attribut système n'empêche jamais la suppression d'un fichier ou d'un dossier.
Les éléments non supprimés sont:
Dossiers utilisés comme répertoire courant pour tout processus en cours d'exécution. L'arborescence de dossiers complète d'un tel dossier ne peut pas être supprimée si un dossier est utilisé comme répertoire actuel pour tout processus en cours d'exécution.
Fichiers actuellement ouverts par tout processus en cours d'exécution avec des autorisations d'accès aux fichiers définies sur le fichier ouvert pour empêcher la suppression du fichier lorsqu'il est ouvert par l'application / le processus en cours d'exécution. Un tel fichier ouvert empêche également la suppression de l'arborescence de dossiers entière dans le fichier ouvert.
Fichiers / dossiers sur lesquels l'utilisateur actuel n'a pas les autorisations (NTFS) requises pour supprimer le fichier / dossier, ce qui empêche également la suppression de l'arborescence de dossiers dans ce fichier / dossier.
La première raison de ne pas supprimer un dossier est utilisée par cette ligne de commande pour supprimer tous les fichiers et sous-dossiers du dossier spécifié, mais pas le dossier lui-même. Le dossier devient temporairement le répertoire courant pour l'exécution du processus de commande, ce qui empêche la suppression du dossier lui-même. Bien sûr, cela entraîne la sortie d'un message d'erreur par la commande RD :
Le processus ne peut pas accéder au fichier car il est utilisé par un autre processus.
Fichier est le mauvais terme ici car en réalité le dossier est utilisé par un autre processus, le processus de commande actuel qui a exécuté la commande RD . Eh bien, en réalité , un dossier est pour le système de fichiers , un fichier spécial avec l' attribut de fichier répertoire qui explique ce message d'erreur. Mais je ne veux pas aller trop loin dans la gestion du système de fichiers.
Ce message d'erreur, comme tous les autres messages d'erreur, qui peuvent survenir pour les trois raisons écrites ci-dessus, est supprimé en le redirigeant avec 2>nul
du handle STDERR vers le périphérique NUL .
La troisième commande, POPD , est exécutée indépendamment de la valeur de sortie de la commande RD .
POPD fait sortir le chemin du répertoire poussé par PUSHD de la pile et change le répertoire courant pour exécuter le processus de commande dans ce répertoire, c'est-à-dire restaure le répertoire courant initial. POPD supprime la lettre de lecteur temporaire créée par PUSHD dans le cas d'un chemin de dossier UNC.
Remarque: POPD peut échouer en silence pour restaurer le répertoire courant initial dans le cas où le répertoire courant initial était un sous-répertoire du répertoire à nettoyer qui n'existe plus. Dans ce cas particulier %PathToFolder%
reste le répertoire courant. Il est donc conseillé d'exécuter la ligne de commande ci-dessus et non à partir d'un sous-répertoire de%PathToFolder%
.
Un autre fait intéressant :
j'ai essayé la ligne de commande en utilisant également un chemin UNC en partageant le répertoire local C:\Temp
avec le nom de partage Temp
et en utilisant le chemin UNC \\%COMPUTERNAME%\Temp\CleanTest
affecté à la variable d'environnement PathToFolder
sous Windows 7. Si le répertoire en cours d'exécution de la ligne de commande est un sous-répertoire d'un local partagé le dossier auquel on accède en utilisant le chemin UNC, c'est-à-dire C:\Temp\CleanTest\Subfolder1
, Subfolder1
est supprimé par RD , et POPD suivant échoue silencieusement à C:\Temp\CleanTest\Subfolder1
refaire le répertoire courant, ce qui Z:\CleanTest
reste le répertoire courant pour le processus de commande en cours. Donc, dans ce cas très, très spécial, la lettre de lecteur temporaire reste jusqu'à ce que le répertoire actuel soit modifié, par exemple aveccd /D %SystemRoot%
qui donne un répertoire local réellement existant. Malheureusement POPDne quitte pas avec une valeur supérieure à 0 s'il ne parvient pas à restaurer le répertoire courant initial, ce qui rend impossible la détection de cette condition d'erreur très spéciale en utilisant uniquement le code de sortie de POPD . Cependant, on peut supposer que personne ne rencontre jamais ce cas d'erreur très spécial car les chemins UNC ne sont généralement pas utilisés pour accéder aux fichiers et dossiers locaux.
Pour mieux comprendre les commandes utilisées, ouvrez une fenêtre d'invite de commandes, exécutez-y les commandes suivantes et lisez très attentivement l'aide affichée pour chaque commande.
Une seule ligne avec plusieurs commandes utilisant un fichier batch Windows explique les opérateurs &&
et &
utilisés ici.
Voyons maintenant la solution de fichiers batch en utilisant la commande DEL pour supprimer les fichiers dans %PathToFolder%
et FOR et RD pour supprimer les sous-dossiers dans %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
Le fichier de commandes vérifie d'abord que la variable d'environnement PathToFolder
est vraiment définie avec un chemin de dossier sans guillemets doubles et sans barre oblique inversée à la fin. La barre oblique inverse à la fin ne serait pas un problème, mais les guillemets doubles dans un chemin de dossier pourraient être problématiques en raison de la valeur de PathToFolder
est concaténée avec d'autres chaînes pendant l'exécution du fichier de commandes.
Les deux lignes sont importantes:
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
La commande DEL est utilisée pour supprimer tous les fichiers du répertoire spécifié.
- L'option
/A
est nécessaire pour traiter vraiment tous les fichiers, y compris les fichiers avec l'attribut caché que DEL ignorerait sans utiliser l'option /A
.
- L'option
/F
est nécessaire pour forcer la suppression des fichiers avec le jeu d'attributs en lecture seule.
- L'option
/Q
est nécessaire pour exécuter une suppression discrète de plusieurs fichiers sans demander à l'utilisateur si plusieurs fichiers doivent vraiment être supprimés.
>nul
est nécessaire pour rediriger la sortie des noms de fichiers écrits pour gérer STDOUT vers le périphérique NUL qui ne peut pas être supprimé car un fichier est actuellement ouvert ou l'utilisateur n'a pas l'autorisation de supprimer le fichier.
2>nul
est nécessaire pour rediriger la sortie du message d'erreur pour chaque fichier qui ne peut pas être supprimé de la poignée STDERR vers le périphérique NUL .
Les commandes FOR et RD sont utilisées pour supprimer tous les sous-répertoires du répertoire spécifié. Mais for /D
n'est pas utilisé car FOR ignore dans ce cas les sous-répertoires avec l'attribut caché défini. Pour cette raison, for /F
est utilisé pour exécuter la ligne de commande suivante dans un processus de commande distinct démarré en arrière-plan avec %ComSpec% /c
:
dir "%PathToFolder%\*" /AD /B 2>nul
Les sorties DIR au format nu en raison des /B
entrées de répertoire avec attribut D
, c'est-à-dire les noms de tous les sous-répertoires dans le répertoire spécifié indépendamment des autres attributs comme l'attribut caché sans chemin. 2>nul
est utilisé pour rediriger la sortie du message d'erreur par DIR sur aucun répertoire trouvé du handle STDERR vers le périphérique NUL .
L'opérateur de redirection >
doit être échappé avec le caractère caret,, ^
sur la ligne de commande FOR pour être interprété comme un caractère littéral lorsque l'interpréteur de commandes Windows traite cette ligne de commande avant d'exécuter la commande FOR qui exécute la dir
ligne de commande intégrée dans un processus de commande distinct démarré en arrière-plan.
FOR traite la sortie capturée écrite pour gérer STDOUT d'un processus de commande démarré qui sont les noms des sous-répertoires sans chemin et jamais entre guillemets.
FOR avec option /F
ignore les lignes vides qui ne se produisent pas ici car DIR avec option /B
ne produit pas de lignes vides.
FOR ignorerait également les lignes commençant par un point-virgule qui est le caractère de fin de ligne par défaut. Un nom de répertoire peut commencer par un point-virgule. Pour cette raison, eol=|
est utilisé pour définir le caractère de barre verticale comme le caractère de fin de ligne qu'aucun répertoire ou fichier ne peut avoir dans son nom.
FOR diviserait la ligne en sous-chaînes en utilisant l'espace et la tabulation horizontale comme délimiteurs et affecterait uniquement la première chaîne délimitée par un espace / tabulation à la variable de boucle spécifiée I
. Ce comportement de fractionnement n'est pas souhaité ici car un nom de répertoire peut contenir un ou plusieurs espaces. Par conséquent, delims=
est utilisé pour définir une liste vide de délimiteurs pour désactiver le comportement de fractionnement de ligne et être affecté à la variable de boucle I
, toujours le nom complet du répertoire.
La commande FOR exécute la commande RD pour chaque nom de répertoire sans chemin d'accès. C'est la raison pour laquelle sur la ligne de commande RD , le chemin d'accès au dossier doit être spécifié à nouveau, ce qui est concaténé avec le nom du sous-dossier.
Pour comprendre les commandes utilisées et leur fonctionnement, ouvrez une fenêtre d'invite de commandes, exécutez-y les commandes suivantes et lisez très attentivement toutes les pages d'aide affichées pour chaque commande.
del /?
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
rd /?
rem /?
set /?
setlocal /?