我看不出%SystemRoot%\System32\robocopy.exe 无法复制当前由cmd.exe 处理的批处理文件的任何原因,而不是在诸如文本编辑器之类的应用程序中另外打开该批处理文件,以防止文件的写入访问和删除为只要它在应用程序中打开。
但是,将以下代码添加到内容未知的批处理文件中可以解决问题。
@echo off
if /I not "%~dp0" == "%TEMP%\" (
copy /Y "%~f0" "%TEMP%" >nul 2>&1
if exist "%TEMP%\%~nx0" (
set "CurrentDirectory=%CD%"
set "InitialExecution=%~dp0"
cd /D "%TEMP%"
"%TEMP%\%~nx0" %*
)
)
rem Insert here other commands to execute by the batch
rem file now running from directory of temporary files.
rem The next three commands are only for demonstration.
if defined CurrentDirectory echo Initial current directory: %CurrentDirectory%
if defined InitialExecution echo Initial execution path: %InitialExecution%
pause
set "InitialExecution="
if defined CurrentDirectory set "CurrentDirectory=" & cd /D "%CurrentDirectory%" 2>nul & (goto) 2>nul & del "%~f0"
此批处理文件首先检查它是否从临时文件目录启动。双击批处理文件不是这种情况,除了批处理文件偶然存储在用户临时文件的目录中并在该目录中双击它。如果批处理文件没有存储在临时文件的目录中,它会执行以下操作:
- 批处理文件将自身复制到临时文件目录(仅读取权限)。
- 它会验证文件复制是否真的成功,这应该总是正确的。
- 它定义了两个环境变量,当前目录的路径和初始执行路径供以后使用。
- 它将当前目录设置为临时文件目录。
这使得甚至可以删除包含批处理文件的目录,批处理文件目录也是当前目录,通常双击存储在当前用户执行的本地驱动器上的批处理文件。
- 批处理文件从临时文件目录中自行运行,并在其副本上进一步传递在初始执行时传递给批处理文件的所有参数。
执行批处理文件的 Windows 命令处理器 cmd.exe 继续对临时文件目录中的副本进行批处理文件处理,第一行 @echo off 永远不会返回到用户启动的初始批处理文件。
现在在临时文件目录中的初始批处理文件的副本上完成批处理文件处理,并且当前目录也是临时文件的目录,批处理文件中的其他命令可以在初始当前目录分别执行初始执行目录中的所有内容批处理文件,例如更新这些目录中的文件,甚至临时或永久删除这些目录。
带有命令rem 的三行注释和接下来的三行只是演示了这里可以做什么以及如何在初始执行时使用批处理文件设置的环境变量。这两个环境变量在最初存储在临时文件目录中并由用户从该目录执行的批处理文件上不存在(很可能)。
批处理文件删除环境变量InitialExecution,独立于其存在,以在批处理文件从命令提示符窗口中执行的情况下恢复初始环境。
最后,批处理文件最初未从临时文件目录执行,它还删除环境变量CurrentDirectory,如果该目录仍然存在,则将当前目录更改回初始当前目录,并从临时文件目录中删除自身。
(goto) 2>nul & del "%~f0" 用于批处理文件删除,Windows 命令处理器没有输出任何错误消息,这是我从 Dave Benham 在How to make a batch file delete itself? 上的回答中复制的
要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
-
call /? ... 解释 %~dp0、%~f0 和 %~nx0
cd /?
copy /?
del /?
echo /?
goto /?
if /?
pause /?
set /?
另请参阅有关 Using command redirection operators 的 Microsoft 文章。