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

时间:2013-06-19 00:58:06

标签: batch-file

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

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

7 个答案:

答案 0 :(得分:5)

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

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

那是:

@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
)

答案 1 :(得分: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

upgrade.bat开头的这一行序列应该有用。

查看我们是否正在使用%temp%中的副本运行。如果没有,则将此文件复制到temp&从那里开始。

因此,批次实际上从%temp%开始运行,原始版本可能会被覆盖。

答案 2 :(得分:3)

您可以使用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%" .

答案 3 :(得分:3)

@echo off
cmd /c copy "C:\somepath\upgrade.bat" "%0" & %0

这将启动一个新的cmd进程并用“C:\ somepath \ upgrade.bat”替换当前批处理文件并重新启动批处理文件

答案 4 :(得分:2)

是否可以选择使用版本后缀标记每个新版本的批处理文件,并使用第二个批处理文件作为启动器?

例如,假设您是有效负载批处理文件 upgrade.bat ,后续版本将命名为upgrade_001.bat,upgrade_002.bat,upgrade_003.bat ..或upgrade_201305122134(后缀为yyyymmddHHMM),新的批处理文件 launcher.bat 将通过查找具有最高后缀的文件并执行它来查找最新的批处理升级文件

答案 5 :(得分:2)

if NOT "%1"=="RUN" (
copy "%~0" temp_update.cmd
temp_update.cmd RUN
)

只需将其放在cmd文件的顶部 任何名称都可以用于临时文件。

答案 6 :(得分:0)

将批处理文件复制到updateNow.bat,然后运行updateNow.bat: 所以update.bat的内容是:

if %0 == update (
  copy update.bat updateNow.bat
  updateNow.bat
) else (
  copy newUpdate.bat update.bat
)