如何让Windows批处理文件安全地更新自己

Moe*_*sko 8 batch-file

例如,我想运行一个windows批处理文件,比如upgrade.bat,它将一堆文件从源目录复制到批处理文件所在的目录.问题是,复制的其中一个文件可能是更新版本的升级.bat,以便批处理文件在其仍在运行时将覆盖自身.

这似乎导致批处理文件执行的一些不可预测的行为,所以我想避免复制仍在运行的批处理文件.理想情况下,我希望现有版本的upgrade.bat运行直到完成,然后下次运行新版本.有没有(简单)方法来实现这一目标?

Aac*_*ini 5

为此,必须满足以下要求:

  • 对于较新版本的自身的批处理文件的覆盖必须是批处理文件的最后一个命令,因此copy必须在exit /B或之后的下一个命令exit.
  • 必须先将命令加载到内存中,然后再执行它们.这可以通过将它们括在括号中来轻松完成.

那是:

@echo off
rem Do program business here...
echo Anything

rem Parse/load following commands before execute they:
(
rem Copy many files, probably a newer version of myself
xcopy /Y *.*
rem You may execute other commands here...
echo Files copied!
rem Terminate *this version* of the running Batch file
exit /B
)
Run Code Online (Sandbox Code Playgroud)


Mag*_*goo 5

@ECHO OFF
SETLOCAL
IF /i NOT "%~dp0"=="%temp%\" (
 COPY /y "%~dpnx0" "%temp%\%~nx0" >nul
 "%temp%\%~nx0"

)
ECHO Now we run the rest of the original UPGRADE.BAT
Run Code Online (Sandbox Code Playgroud)

这一系列的行upgrade.bat应该起作用.

看看我们是否正在运行副本%temp%.如果没有,则将此文件复制到temp并从那里运行它.

因此,批处理实际上从中运行,%temp%原始版本可能会被覆盖.


br *_*ujo 4

您可以使用 start 命令将副本作为最后一个操作来运行,以从另一个终端启动它。检查这个例子,特别是最后几行。

@echo off
set CUR_FILE=batman.bat
set FOUND_EQUAL="FALSE"
set FROM_DIR=c:\temp\galeria\

SETLOCAL DisableDelayedExpansion
FOR /R %FROM_DIR% %%F IN (*) DO (
  SET "p=%%F"
  SETLOCAL EnableDelayedExpansion
  SET ABC=!p:%FROM_DIR%=!

  IF NOT !ABC! == !CUR_FILE! ( 
echo copying %%F
    copy "%%F" . 
   )    
ENDLOCAL  
) 

echo trying to copy file with the same name [last operation] 
start copy "%FROM_DIR%%CUR_FILE%" .
Run Code Online (Sandbox Code Playgroud)