为什么在批处理文件中没有使用RMDIR删除文件夹作为最后一个命令?

时间:2016-11-19 15:57:57

标签: batch-file

我在.bat文件中有以下代码:

@echo off
xcopy /Y /S %CD%\Code\Release C:\Users\%USERNAME%\Desktop\ShareIt /I
cls
cd C:\Users\%USERNAME%\Desktop\ShareIt\
call "Trabalho AEDA.exe"
xcopy /Y /S C:\Users\%USERNAME%\Desktop\ShareIt\FICHEIROS\ %CD%\Code\Release\FICHEIROS\
RMDIR /S /Q C:\Users\%USERNAME%\Desktop\ShareIt

将文件夹复制到某个位置,从中运行.exe,然后覆盖我文件夹中的原始文件,并删除最初复制的文件。

我复制到用户桌面的文件夹里面有其他文件夹和.exe。 在.bat的最后一行,它删除文件夹中的所有内容,但该文件夹保存在Desktop文件夹中。我也想删除它。我尝试了几条指令,但没有成功。

编辑:这就是问题,谢谢你们。

3 个答案:

答案 0 :(得分:4)

ShareIt文件夹未被删除,可能是因为您在文件夹中。 因此,在cd ..解决之前添加RMDIR /S /Q C:\Users\%USERNAME%\Desktop\ShareIt

答案 1 :(得分:1)

执行

cd C:\Users\%USERNAME%\Desktop\ShareIt\

执行now delete the directory命令时,它是当前目录。

转到另一个目录,然后尝试删除

答案 2 :(得分:1)

其他回答者已经回答了删除ShareIt文件夹的主要问题。

在Windows上,无法删除任何正在运行的进程的当前工作目录的文件夹,或者由具有文件锁定的应用程序打开文件以防止删除已打开文件的文件夹。

在这种情况下,ShareIt文件夹是执行批处理文件的命令进程的当前工作目录,因为批处理文件显式将此目录设置为工作目录。解决方案是将任何其他目录作为命令进程的工作目录。

但这不是此批处理文件中少数命令行的唯一潜在问题。还有一些。

%CD%可能会扩展到一个路径,该路径可能包含一个或多个空格或其他字符,例如&()[]{}^=;!'+,`~,这些字符需要用双引号括起完整的文件夹路径。在最后一个输出帮助页面的最后一段中,在命令提示符窗口cmd /?中运行时输出此字符列表。

此外,%CD%扩展为通常不以反斜杠结尾的文件夹路径,但当前目录是驱动器的根目录。因此%CD%\Code\Release例如可以在路径中使用两个反斜杠扩展为C:\\Code\Release。但是,这不是真正的问题,因为Windows内核会自动更正xcopy内部用于复制文件和文件夹的任何文件系统访问函数的路径。

参数/I允许xcopy将目标字符串解释为文件夹路径,即使文件夹路径没有以反斜杠结尾,但仅当复制多个文件时,如源路径是类似文件夹的路径显然是这样的。否则,/I会忽略仅复制单个文件xcopy。最适合作为目标的文件夹路径是使用反斜杠指定目标文件夹路径,因此xcopy始终将目标解释为文件夹路径。在这里使用相对于当前目录的路径更容易,并完全省略%CD%

C:\Users\%USERNAME%不好,因为用户的个人资料目录也可以位于与C:不同的驱动器上,并且可以位于与Users不同的目录中,例如Windows XP。 C:\Users\%USERNAME%是自Windows Vista以来用户配置文件目录的默认设置。但是,每个用户都可以自由地在Windows Vista和更高版本的Windows上进行更改。 Windows定义的环境变量USERPROFILE包含活动用户的配置文件目录的完整路径。有关预定义Windows环境变量的更多详细信息,请参阅Wikipedia有关Windows Environment Variables的文章。

当然,用户的配置文件目录路径可能包含一个或多个空格或其他字符,这些字符在完整文件夹路径或文件名周围需要双引号,例如,如果用户帐户名称包含空格字符。因此,只要在带有路径的文件夹或文件名中使用%USERPROFILE%%USERNAME%,就应该使用双引号。

如果新当前目录在当前驱动器上完全存在,则不带参数/D的命令 CD 仅更改当前驱动器上的当前目录。因此,在启动批处理文件的当前目录位于与驱动器C:不同的驱动器上时,使用已使用的代码更改当前目录根本不起作用。

如果Trabalho AEDA.exe是控制台应用程序,则根本不需要命令 CALL 。但 CALL 也可以用于控制台应用程序,尽管它主要用于运行子程序或从批处理文件中调用另一个批处理文件。

最后两行没有用,因为批处理文件将当前目录更改为当前用户的桌面文件夹中的ShareIt文件夹。因此%CD%\Code\Release\FICHEIROS\扩展为

C:\Users\%USERNAME%\Desktop\ShareIt\Code\Release\FICHEIROS\

作为xcopy的目标路径,最后一行删除整个文件夹

C:\Users\%USERNAME%\Desktop\ShareIt

这显然不是意图。 xcopy在最后但在行之前应将文件复制到初始当前目录中的子目录。

我建议使用此批处理代码:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
%SystemRoot%\System32\xcopy.exe Code\Release "%USERPROFILE%\Desktop\ShareIt\" /C /Q /R /S /Y >nul
pushd "%USERPROFILE%\Desktop\ShareIt"
call "Trabalho AEDA.exe"
popd
%SystemRoot%\System32\xcopy.exe "%USERPROFILE%\Desktop\ShareIt\FICHEIROS" Code\Release\FICHEIROS\ /C /Q /R /S /Y >nul
if "!CD:%USERPROFILE%\Desktop\ShareIt=!" == "%CD%" RMDIR /S /Q "%USERPROFILE%\Desktop\ShareIt"
endlocal

最后一行但在行之前很可能需要另外解释其目的是什么。

!CD:%USERPROFILE%\Desktop\ShareIt=!导致在当前目录路径字符串中搜索不区分大小写,以便在当前用户的桌面目录中出现到ShareIt目录的所有路径字符串,并用空字符串替换所有找到的事件。所以它取决于当前目录的内容。

如果当前目录为%USERPROFILE%\Desktop\ShareIt,则比较运算符==左侧的字符串将变为""。如果当前目录是%USERPROFILE%\Desktop\ShareIt的子目录,则==左侧的字符串将成为用双引号括起来的此目录的相对路径。在所有其他情况下,==左边的字符串根本没有被修改,并扩展到用双引号括起来的当前目录的路径,比如比较运算符的字符串右边。

因此 IF 条件检查当前用户的桌面目录中当前目录是不是ShareIt目录还是此目录的子目录。只有在这种情况下才能安全删除整个ShareIt目录。

要了解所有其他使用的命令及其工作方式,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • call /?
  • cd /?
  • echo /?
  • endlocal /?
  • popd /?
  • pushd /?
  • set /?
  • setlocal /?
  • xcopy /?

另请阅读Microsoft文章Using command redirection operators,了解>nul

的说明