2013-06-19 185 views
8

例如我想運行一個windows批處理文件,例如upgrade.bat,它將一堆文件從源目錄複製到該批處理文件所在的目錄中。問題是,其中一個複製的文件可能是較新版本的升級。蝙蝠,以便該批處理文件在其仍在運行時覆蓋自身。如何讓windows批處理文件安全地自我更新

這似乎導致批處理文件執行的一些不可預知的行爲,所以我想避免複製到仍在運行的批處理文件。理想情況下,我想讓現有版本的upgrade.bat運行直到完成,然後再運行新版本。是否有任何(簡單)的方法來實現這一點?

+2

在執行文件之前重命名文件? – Chad

+0

@Chad - 你的意思是從upgrade.bat本身重命名upgrade.bat?這是否安全並會導致可預測的行爲? –

回答

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%" . 
2

是否可以選擇使用版本後綴標記批處理文件的每個新版本並將第二個批處理文件用作啓動程序?

例如說你是有效載荷批處理文件是upgrade.bat,後續版本將被命名爲upgrade_001.bat,upgrade_002.bat,upgrade_003.bat ..或upgrade_201305122134(後綴是爲yyyymmddhhmm),新的批處理文件launcher.bat將尋求新一輪的升級文件通過尋找具有最高後綴,並執行它

+0

不是一個壞主意,我想你是用啓動器批處理文件的想法。儘管upgrade.bat在源代碼管理中,但是每次更改時都不想重命名它。 –

4

爲了做到這一點,下列要求必須滿足:

  • 對自身的新版本必須爲批處理文件中的最後一個命令的批處理文件的覆蓋,所以在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 
) 
3
@echo off 
cmd /c copy "C:\somepath\upgrade.bat" "%0" & %0 

這將啓動一個新的CMD進程,並以 「C:\ somepath \ upgrade.bat」 取代目前的批處理文件,並重新啓動批處理文件

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%運行的,原始版本可能會被覆蓋。

+0

@Peter_Wright:這看起來很有趣,但爲什麼「ECHO現在我們運行其餘的原始UPGRADE.BAT」......在文件被複制並運行後運行? –

+0

@steve運行原始文件時,目錄不是臨時目錄,因此將副本製作爲臨時文件,並執行,將執行傳輸到COPY。當COPY運行時,%0位於臨時目錄中,所以它會從副本運行原始代碼(即從ECHO開始)。現在 - 如果您的ORIGINAL在%temp%中,您可能會得到錯誤,因爲試圖將文件複製到自身。 – Magoo

+0

@Peter_Wright:一旦我找出奇怪的語法,就非常簡單和優雅。我稍微修改它,以便在運行之後將其從temp中刪除,然後退出。 –