Żadna z odpowiedzi opublikowanych 01.01.2018, z wyjątkiem pojedynczego wiersza poleceń opublikowanego przez foxidrive , naprawdę usunęła wszystkie pliki i wszystkie foldery / katalogi w %PathToFolder%
. To jest powód opublikowania jeszcze jednej odpowiedzi za pomocą bardzo prostego pojedynczego wiersza polecenia, aby usunąć wszystkie pliki i podfoldery folderu, a także plik wsadowy z bardziej złożonym rozwiązaniem wyjaśniającym, dlaczego wszystkie inne odpowiedzi opublikowane w dniu 06.06.2018 przy użyciu DEL i FOR z RD nie udało się całkowicie wyczyścić folderu.
Proste rozwiązanie z pojedynczym wierszem poleceń, które oczywiście można również wykorzystać w pliku wsadowym:
pushd "%PathToFolder%" 2>nul && ( rd /Q /S "%PathToFolder%" 2>nul & popd )
Ten wiersz poleceń zawiera trzy polecenia wykonywane jeden po drugim.
Pierwsze polecenie PUSHD wypycha bieżącą ścieżkę katalogu na stos, a następnie tworzy %PathToFolder%
katalog bieżący do uruchomienia procesu poleceń.
Działa to również domyślnie dla ścieżek UNC, ponieważ rozszerzenia poleceń są domyślnie włączone, w tym przypadku PUSHD tworzy tymczasową literę dysku, która wskazuje na określony zasób sieciowy, a następnie zmienia bieżący dysk i katalog, używając nowo zdefiniowanej litery dysku.
PUSHD generuje następujący komunikat o błędzie, aby obsłużyć STDERR, jeśli określony katalog w ogóle nie istnieje:
System nie może odnaleźć określonej ścieżki.
Ten komunikat o błędzie jest pomijany przez przekierowanie go 2>nul
do urządzenia NUL .
Następne polecenie RD jest wykonywane tylko wtedy, gdy zmiana bieżącego katalogu dla bieżącego procesu poleceń na określony katalog zakończyła się powodzeniem, tzn. Podany katalog w ogóle istnieje.
Polecenie RD z opcjami /Q
i cicho/S
usuwa katalog ze wszystkimi podkatalogami, nawet jeśli określony katalog zawiera pliki lub foldery z ukrytym atrybutem lub z ustawionym atrybutem tylko do odczytu. Atrybut systemowy nigdy nie zapobiega usuwaniu pliku lub folderu.
Nie usunięte są:
Foldery używane jako bieżący katalog dla dowolnego uruchomionego procesu. Całe drzewo folderów takiego folderu nie może zostać usunięte, jeśli folder jest używany jako katalog bieżący dla dowolnego uruchomionego procesu.
Pliki aktualnie otwierane przez dowolny uruchomiony proces z uprawnieniami dostępu do pliku ustawionymi na plik otwarty, aby zapobiec usunięciu pliku podczas otwierania przez uruchomioną aplikację / proces. Taki otwarty plik zapobiega również usunięciu całego drzewa folderów do otwartego pliku.
Pliki / foldery, w których bieżący użytkownik nie ma wymaganych uprawnień (NTFS), aby usunąć plik / folder, co zapobiega również usunięciu drzewa folderów do tego pliku / folderu.
Pierwszy powód, dla którego folder nie jest usuwany, służy do usuwania wszystkich plików i podfolderów określonego folderu, ale nie samego folderu. Folder jest tymczasowo bieżącym katalogiem do uruchamiania procesu poleceń, co uniemożliwia usunięcie samego folderu. Oczywiście powoduje to wyświetlenie komunikatu o błędzie przez polecenie RD :
Proces nie może uzyskać dostępu do pliku, ponieważ jest używany przez inny proces.
Plik jest tutaj złym terminem, ponieważ w rzeczywistości folder jest używany przez inny proces, bieżący proces polecenia, który wykonał polecenie RD . W rzeczywistości folder jest dla systemu plików specjalnym plikiem z katalogiem atrybutów pliku, który wyjaśnia ten komunikat o błędzie. Ale nie chcę zagłębiać się w zarządzanie systemem plików.
Ten komunikat o błędzie, podobnie jak wszystkie inne komunikaty o błędach, które mogą wystąpić z trzech opisanych powyżej powodów, jest pomijany przez przekierowanie go z 2>nul
uchwytu STDERR na urządzenie NUL .
Trzecie polecenie POPD jest wykonywane niezależnie od wartości wyjściowej polecenia RD .
POPD usuwa ścieżkę katalogu wypchniętą przez PUSHD ze stosu i zmienia katalog bieżący w celu uruchomienia procesu komend na ten katalog, tzn. Przywraca początkowy katalog bieżący. POPD usuwa tymczasową literę dysku utworzoną przez PUSHD w przypadku ścieżki folderu UNC.
Uwaga: POPD może po cichu nie przywrócić początkowego katalogu bieżącego, w przypadku gdy początkowy katalog bieżący był podkatalogiem katalogu do czyszczenia, który już nie istnieje. W tym szczególnym przypadku %PathToFolder%
pozostaje bieżący katalog. Dlatego wskazane jest, aby uruchomić powyższy wiersz poleceń, a nie z podkatalogu %PathToFolder%
.
Jeszcze jeden interesujący fakt:
wypróbowałem wiersz poleceń również przy użyciu ścieżki UNC, udostępniając lokalny katalog C:\Temp
z nazwą udziału Temp
i używając ścieżki UNC \\%COMPUTERNAME%\Temp\CleanTest
przypisanej do zmiennej środowiskowej PathToFolder
w systemie Windows 7. Jeśli bieżący katalog podczas uruchamiania wiersza poleceń jest podkatalogiem udostępnionego lokalnego folderze dostępne przy użyciu ścieżki UNC, to znaczy C:\Temp\CleanTest\Subfolder1
, Subfolder1
są usuwane przez RD , a obok POPD nie cicho w podejmowaniu C:\Temp\CleanTest\Subfolder1
ponownie bieżący katalog prowadzące Z:\CleanTest
pozostałą jako bieżącego katalogu za prowadzenie procesu dowodzenia. Więc w tym bardzo szczególnym przypadku litera dysku tymczasowego pozostaje do momentu zmiany bieżącego katalogu, na przykład za pomocącd /D %SystemRoot%
do istniejącego katalogu lokalnego. Niestety POPD nie kończy działania z wartością większą 0, jeśli nie uda się przywrócić początkowego katalogu bieżącego, co uniemożliwia wykrycie tego bardzo szczególnego warunku błędu przy użyciu tylko kodu wyjścia POPD . Można jednak przypuszczać, że nikt nigdy nie napotyka tak szczególnego przypadku błędu, ponieważ ścieżki UNC zwykle nie są używane do uzyskiwania dostępu do lokalnych plików i folderów.
Aby jeszcze lepiej zrozumieć używane polecenia, otwórz okno wiersza polecenia, wykonaj tam następujące polecenia i bardzo uważnie przeczytaj pomoc wyświetlaną dla każdego polecenia.
Jedna linia z wieloma poleceniami przy użyciu pliku wsadowego systemu Windows wyjaśnia operatorów &&
i &
użyto ich tutaj.
Następnie spójrzmy na rozwiązanie pliku wsadowego za pomocą polecenia DEL, aby usunąć pliki z %PathToFolder%
oraz FOR i RD, aby usunąć podfoldery %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
Plik wsadowy najpierw upewnia się, że zmienna środowiskowa PathToFolder
jest naprawdę zdefiniowana ze ścieżką folderu bez podwójnych cudzysłowów i bez odwrotnego ukośnika na końcu. Odwrotny ukośnik na końcu nie stanowiłby problemu, ale podwójne cudzysłowy w ścieżce folderu mogą być problematyczne, ponieważ wartość PathToFolder
jest łączona z innymi łańcuchami podczas wykonywania pliku wsadowego.
Ważne są dwie linie:
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
Polecenie DEL służy do usunięcia wszystkich plików z określonego katalogu.
- Ta opcja
/A
jest niezbędna do przetworzenia naprawdę wszystkich plików, w tym plików z ukrytym atrybutem, które DEL zignorowałby bez użycia opcji /A
.
- Opcja
/F
jest konieczna, aby wymusić usunięcie plików z ustawionym atrybutem „tylko do odczytu”.
- Ta opcja
/Q
jest niezbędna, aby cicho usunąć wiele plików bez pytania użytkownika, czy wiele plików powinno zostać naprawdę usuniętych.
>nul
jest konieczne, aby przekierować dane wyjściowe nazw plików zapisanych do obsługi STDOUT na urządzenie NUL, którego nie można usunąć, ponieważ plik jest aktualnie otwarty lub użytkownik nie ma uprawnień do usunięcia pliku.
2>nul
jest konieczne, aby przekierować wyjście komunikatu o błędzie dla każdego pliku, którego nie można usunąć z uchwytu STDERR do urządzenia NUL .
Polecenia FOR i RD służą do usuwania wszystkich podkatalogów z określonego katalogu. Ale for /D
nie jest używany, ponieważ FOR ignoruje w tym przypadku podkatalogi z ustawionym ukrytym atrybutem. Z tego powodu for /F
służy do uruchomienia następującego wiersza poleceń w osobnym procesie poleceń uruchomionym w tle za pomocą %ComSpec% /c
:
dir "%PathToFolder%\*" /AD /B 2>nul
Dane wyjściowe DIR są w formacie nagim ze względu /B
na pozycje katalogu z atrybutem D
, tj. Nazwy wszystkich podkatalogów w określonym katalogu, niezależne od innych atrybutów, takich jak atrybut ukryty bez ścieżki. 2>nul
służy do przekierowania wyjścia komunikatu o błędzie przez DIR w żadnym katalogu nie znalezionym z uchwytu STDERR do urządzenia NUL .
Operator przekierowania >
musi być poprzedzony znakiem karetki ^
, w wierszu polecenia FOR, aby interpretować go jako znak dosłowny, gdy interpreter poleceń systemu Windows przetwarza ten wiersz polecenia przed wykonaniem polecenia FOR, które wykonuje osadzony dir
wiersz polecenia w oddzielnym procesie poleceń w tle.
FOR przetwarza wychwycone dane wyjściowe napisane w celu obsługi STDOUT uruchomionego procesu komend, które są nazwami podkatalogów bez ścieżki i nigdy nie są ujęte w podwójny cudzysłów.
FOR z opcją /F
ignoruje puste linie, które nie występują tutaj, ponieważ DIR z opcją /B
nie wyświetla pustych linii.
FOR zignoruje również linie zaczynające się od średnika, który jest domyślnym znakiem końca linii. Nazwa katalogu może zaczynać się średnikiem. Z tego powodu eol=|
służy do zdefiniowania znaku pionowego paska jako znaku końca wiersza, którego żaden katalog ani plik nie może mieć w nazwie.
FOR podzieli linię na podciągi, używając spacji i tabulacji poziomej jako ograniczników, i przypisze tylko pierwszy ciąg rozdzielany spacją / tabulacją do określonej zmiennej pętli I
. To zachowanie podziału nie jest tutaj potrzebne, ponieważ nazwa katalogu może zawierać jedną lub więcej spacji. Dlatego delims=
służy do zdefiniowania pustej listy ograniczników, aby wyłączyć zachowanie podziału linii i przypisać się do zmiennej pętli I
, zawsze pełnej nazwy katalogu.
Polecenie FOR uruchamia polecenie RD dla każdej nazwy katalogu bez ścieżki, co jest przyczyną, dla której w wierszu polecenia RD należy ponownie podać ścieżkę folderu, która jest połączona z nazwą podfolderu.
Aby zrozumieć używane polecenia i sposób ich działania, otwórz okno wiersza polecenia, wykonaj tam następujące polecenia i bardzo dokładnie przeczytaj wszystkie strony pomocy wyświetlane dla każdego polecenia.
del /?
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
rd /?
rem /?
set /?
setlocal /?