由于历史原因,原来写的C/S程序,客户端没有自动更新的功能,需要手动的去拿U盘更新客户端程序,且又无法增加这部分功能(由于网络、客户机都不属于我们维护),才想到使用批处理来实现自动更新的功能整体框架,具体的少部分功能需要根据自己去调整。这里只列出一个自动更新程序的框架。
主要是由实现的功能如下:
1)使用Web服务器发布新程序的压缩包和更新配置文件
2)更新配置文件使用文本文件,为键/值对配置。
3)更新情况的业务流程:下载配置 → 读取新旧配置文件 → 新旧版本对比 → 下载新版本zip包 → 备份 → 解压 → 保存最新配置 → 启动客户端程序
后续优化:可以指定客户端(根据IP)进行更新,其他客户端使用本地版本程序
流程图:
保存文件为:autoUpdate.bat(请使用ANSI格式),框架具体代码如下:
@echo off ::Mode con cols=47 lines=15 Title 自动更新批处理(风险动作) cls set V_main=20220225 set Is_Debug=0 echo. echo Version:%V_main% echo. if /i %Is_Debug% GTR 0 (echo 调试模式:True) else echo 调试模式:False echo. echo. echo 正在初始化 echo. echo. ...请稍等... echo. echo. echo 本程序需要使用 【%cd%】 为工作目录。 echo. echo 所有文件操作均在工作目录,请确认是否继续?[Y/N] echo. set confim=N set /p confim=请选择 [Y/N]: if /i not "%confim%"=="y" echo,&echo 程序已退出&exit/b echo. echo. echo 本程序正在执行中,请稍候...... echo. echo. call :main exit/b rem 主程序开始 :main set newV=. set oldV=. set oldConfig=autoUpdated.txt set newConfig=. set urlPath="http://127.0.0.1/updateInfo.txt" call :Web_DownloadFile %urlPath% "" newConfig echo =newConfig =%newConfig% call :getKeyVal %newConfig% "version" newV echo =new version = %newV% if exist %oldConfig% call :getKeyVal %oldConfig% "version" oldV echo =old version = %oldV% setlocal EnableDelayedExpansion if /i not "%oldV%"=="%newV%" ( echo =正在下载新版本,并覆盖现有程序。 ping 127.1>nul call :getKeyVal %newConfig% "url" valUrl echo =new url = !valUrl! call :Web_DownloadFile !valUrl! "" newZipFile echo =newZipFile=!newZipFile! call :getTimeStamp ts echo =ts=!ts! call :mkZip_Files "%cd%" ".\Bak\!ts!_bak.zip" call :unZip_Files !newZipFile! ".\" copy "%newConfig%" "%oldConfig%" /y >nul ) setlocal DisableDelayedExpansion pause exit/b start "launch" "start.bat" exit/b rem 主程序结束 :mkZip_Files <ysPath> <zipFilePath> title Zip 文件压缩 %date:~5,2%月%date:~8,2%日 %time:~0,2%时%time:~3,2%分%time:~6,2%秒 if /i %Is_Debug% GTR 0 echo %0 if /i "%~1."=="." (echo 待压缩包文件为空。&(if /i not %3.==. (set %3=null))&exit/b) echo; echo 正在压缩: echo; set ysPath=%~1 set zipFilePath=%~2 if /i "%ysPath:~-1%"=="\" (set ysPath=%ysPath:~0,-1%) for /f "delims=" %%i in ("%ysPath%") do ( set ysFolder=%%~dpi set ysName=%%~ni set ysExtension=%%~xi ) if /i "%~2."=="." (set zipFilePath=%ysFolder%%ysName%.zip) echo 压缩路径:"%ysPath%" echo 保存路径:"%zipFilePath%" echo; set zipVBS=MkZip.vbs for %%a in (%zipVBS%) do (set localFolder=%%~dpa) if not exist %localFolder% (md %localFolder%&echo 目录 %localFolder% 已创建 ) echo Compress "%ysPath%","%zipFilePath%" >%zipVBS% echo rem 压缩文件>>%zipVBS% echo Sub Compress^(ByVal mySourceDir,ByVal myZipFile^) >>%zipVBS% echo Const vOptions = 516 >>%zipVBS% echo Dim fso >>%zipVBS% echo Set fso = CreateObject^("Scripting.FileSystemObject"^) >>%zipVBS% echo If fso.GetExtensionName^(myZipFile^) ^<^> "zip" Then >>%zipVBS% echo Exit Sub >>%zipVBS% echo ElseIf fso.FolderExists^(mySourceDir^) Then >>%zipVBS% echo FType = "Folder" >>%zipVBS% echo sourcePath = mySourceDir >>%zipVBS% echo ElseIf fso.FileExists^(mySourceDir^) Then >>%zipVBS% echo FType = "File" >>%zipVBS% echo FileName = fso.GetFileName^(mySourceDir^) >>%zipVBS% echo sourcePath = Left^(mySourceDir, Len^(mySourceDir^) - Len^(FileName^)^) >>%zipVBS% echo Else >>%zipVBS% echo Exit Sub >>%zipVBS% echo End If >>%zipVBS% echo rem 处理路径字符串标准化 >>%zipVBS% echo If left(sourcePath,1) = "." Then >>%zipVBS% echo sourcePath = Replace(wscript.ScriptFullName,wscript.ScriptName,"") ^& sourcePath >>%zipVBS% echo End If >>%zipVBS% echo sourcePath=Replace(Replace(Replace(Replace(sourcePath,"\\","\"),"//","\"),"/","\"),"\.\","\") >>%zipVBS% echo zipFile = myZipFile >>%zipVBS% echo If left(zipFile,1) = "." Then >>%zipVBS% echo zipFile = Replace(wscript.ScriptFullName,wscript.ScriptName,"") ^& zipFile >>%zipVBS% echo End If >>%zipVBS% echo zipFile=Replace(Replace(Replace(Replace(zipFile,"\\","\"),"//","\"),"/","\"),"\.\","\") >>%zipVBS% echo tagFolder = left(zipFile,InStrRev(zipFile,"\")-1) >>%zipVBS% echo. >>%zipVBS% echo Set objShell = CreateObject^("Shell.Application"^) >>%zipVBS% echo Set objTargFolder = objShell.NameSpace(tagFolder) >>%zipVBS% echo If (objTargFolder is nothing) Then >>%zipVBS% echo objShell.NameSpace(left(tagFolder,2)^&"\").NewFolder(right(tagFolder,len(tagFolder)-3)) >>%zipVBS% echo End If >>%zipVBS% echo Set f = fso.CreateTextFile^(zipFile, True^) >>%zipVBS% echo f.Write "PK" ^& Chr^(5^) ^& Chr^(6^) ^& String^(18, Chr^(0^)^) >>%zipVBS% echo f.Close >>%zipVBS% echo Set objSource = objShell.NameSpace(sourcePath) >>%zipVBS% echo Set objTarget = objShell.NameSpace^(zipFile^) >>%zipVBS% echo Select Case Ftype >>%zipVBS% echo Case "Folder" >>%zipVBS% echo Set objFolderItem = objSource.Items^(^) >>%zipVBS% echo Case "File" >>%zipVBS% echo Set objFolderItem = objSource.ParseName^(FileName^) >>%zipVBS% echo End Select >>%zipVBS% echo objTarget.CopyHere objFolderItem, vOptions >>%zipVBS% echo Do >>%zipVBS% echo WScript.Sleep 1000 >>%zipVBS% echo Loop Until objTarget.Items.Count ^> 0 >>%zipVBS% echo. >>%zipVBS% echo rem 删除压缩包中指定文件或文件夹,以下硬编码排除文件或文件夹 >>%zipVBS% echo objExcludeList= Array("MkZip.vbs","Bak","Downloads") >>%zipVBS% echo tmpFolder = left(zipFile,len(zipFile)-4) >>%zipVBS% echo Set fso = CreateObject("Scripting.FileSystemObject") >>%zipVBS% echo If not (fso.FolderExists(tmpFolder)) Then >>%zipVBS% echo Set f = fso.CreateFolder(tmpFolder) >>%zipVBS% echo End If >>%zipVBS% echo set tmpTarget = objShell.NameSpace(tmpFolder) >>%zipVBS% echo For Each tagItem In objTarget.Items >>%zipVBS% echo For Each exItem In objExcludeList >>%zipVBS% echo if tagItem = exItem then >>%zipVBS% echo tmpTarget.MoveHere tagItem,vOptions >>%zipVBS% echo end if >>%zipVBS% echo Next >>%zipVBS% echo Next >>%zipVBS% echo If (fso.FolderExists(tmpFolder)) Then >>%zipVBS% echo fso.DeleteFolder tmpFolder,true >>%zipVBS% echo End If >>%zipVBS% echo. >>%zipVBS% echo End Sub >>%zipVBS% ::cscript //nologo %zipVBS% 2>nul del /f /q %zipVBS% >nul 2>nul echo; echo 压缩完毕 echo; echo 压缩路径:"%ysPath%" echo 保存路径:"%zipFilePath%" echo; (if /i not %3.==. (set %3="%zipFilePath%"))&exit/b :unZip_Files <zipFile>,<unZipPath> title Zip 文件解压缩 %date:~5,2%月%date:~8,2%日 %time:~0,2%时%time:~3,2%分%time:~6,2%秒 if /i %Is_Debug% GTR 0 echo %0 if /i "%~1."=="." (echo 压缩包文件为空。&(if /i not %3.==. (set %3=null))&exit/b) echo; echo 正在解压缩: echo; set zipFile=%~1 set unZipPath=%~2 for /f "delims=" %%i in ("%zipFile%") do ( set zipFolder=%%~dpi set zipName=%%~ni set zipExtension=%%~xi ) if /i "%~2."=="." (set unZipPath=%zipFolder%%zipName%) echo 压缩文件:"%zipFile%" echo 释放路径:"%unZipPath%" echo; if /i not "%zipExtension%"==".zip" ( echo; echo 解压缩失败 echo; echo 文件 "%zipFile%" 不是 Zip 压缩文件 echo; (if /i not %3.==. (set %3=null))&exit/b ) set unZipVBS=UnZip.vbs for %%a in (%unZipVBS%) do (set localFolder=%%~dpa) if not exist %localFolder% (md %localFolder%&echo 目录 %localFolder% 已创建 ) echo DeCompress "%zipFile%","%unZipPath%" >%unZipVBS% echo rem 解压缩文件,压缩包路径和解压目标文件夹请使用绝对路径>>%unZipVBS% echo Sub DeCompress^(Source,Target^) >>%unZipVBS% echo Const vOptions=532 >>%unZipVBS% echo Dim ShApp,objSour,objTarg,oItem >>%unZipVBS% echo Set ShApp=CreateObject^("Shell.Application"^) >>%unZipVBS% echo zipFile = Source >>%unZipVBS% echo If left(zipFile,1) = "." Then >>%unZipVBS% echo zipFile = Replace(wscript.ScriptFullName,wscript.ScriptName,"") ^& zipFile >>%unZipVBS% echo End If >>%unZipVBS% echo zipFile=Replace(Replace(Replace(Replace(zipFile,"\\","\"),"//","\"),"/","\"),"\.\","\") >>%unZipVBS% echo tagFolder = Target >>%unZipVBS% echo If left(tagFolder,1) = "." Then >>%unZipVBS% echo tagFolder = Replace(wscript.ScriptFullName,wscript.ScriptName,"") ^& tagFolder >>%unZipVBS% echo End If >>%unZipVBS% echo tagFolder=Replace(Replace(Replace(Replace(tagFolder,"\\","\"),"//","\"),"/","\"),"\.\","\") >>%unZipVBS% echo Set objTarg=ShApp.NameSpace(tagFolder) >>%unZipVBS% echo If (objTarg is nothing) Then >>%unZipVBS% echo ShApp.NameSpace(left(tagFolder,2)^&"\").NewFolder(right(tagFolder,len(tagFolder)-3)) >>%unZipVBS% echo End If >>%unZipVBS% echo Set objSour=ShApp.NameSpace^(zipFile^) >>%unZipVBS% echo Set objTarg=ShApp.NameSpace^(tagFolder^) >>%unZipVBS% echo For Each oItem In objSour.Items >>%unZipVBS% echo objTarg.CopyHere oItem,vOptions >>%unZipVBS% echo Next >>%unZipVBS% echo Set ShApp=Nothing >>%unZipVBS% echo End Sub >>%unZipVBS% ::cscript //nologo %unZipVBS% 2>nul del /f /q %unZipVBS% >nul 2>nul echo; echo 解压缩完毕 echo; echo 压缩文件:"%zipFile%" echo 释放路径:"%unZipPath%" echo; (if /i not %3.==. (set %3="%unZipPath%"))&exit/b :getKeyVal <localConfig> <key> [ret] title 读取更新配置文件 %date:~5,2%月%date:~8,2%日 %time:~0,2%时%time:~3,2%分%time:~6,2%秒 if /i %Is_Debug% GTR 0 echo %0 set kvFile=%~1 if /i "%~1."=="." (echo 配置文件路径为空。&(if /i not %3.==. (set %3=null))&exit/b) if /i "%~2."=="." (echo 查找关键字为空。&(if /i not %3.==. (set %3=null))&exit/b) for /f %%a in (%kvFile%) do ( for /f "tokens=1,* delims=:=" %%i in ("%%a") do ( if /i %~2==%%i ((if /i not %3.==. (set %3=%%j))&exit/b) ) ) (if /i not %2.==. (set %2=""))&exit/b ::goto :eof :Web_DownloadFile <url> <saveFOlderPath> [ret] title 下载文件 %date:~5,2%月%date:~8,2%日 %time:~0,2%时%time:~3,2%分%time:~6,2%秒 if /i %Is_Debug% GTR 0 echo %0 if /i "%~1."=="." (echo 下载的URL路径为空。& goto :eof) set url=%~1 set urlFileName=%~nx1 set saveFilePath=%~2 if /i "%saveFilePath%"=="" (set saveFilePath=.\Downloads\) if /i not "%saveFilePath:~-1%"=="\" (set saveFilePath=%saveFilePath%\) set saveFilePath=%saveFilePath%%urlFileName% for %%a in ("%saveFilePath%") do (set localFolder=%%~dpa) if not exist "%localFolder%" (md "%localFolder%"&echo 目录 "%localFolder%" 已创建 ) set vbDownFile="%windir%\System32\Web_Download.vbs" set vbDownFile=Web_Download.vbs echo rem The usage is as follow (CMD):cscript //NoLogo /e:vbscript %vbDownFile% "Web download's URL" "your save file's path" >%vbDownFile% echo Set Web_Download = CreateObject("Microsoft.XMLHTTP") >>%vbDownFile% echo Web_Download.Open "GET",Wscript.Arguments.Item(0),0 >>%vbDownFile% echo Web_Download.Send() >>%vbDownFile% echo Set Web_Save = CreateObject("ADODB.Stream") >>%vbDownFile% echo Web_Save.Mode = 3 >>%vbDownFile% echo Web_Save.Type = 1 >>%vbDownFile% echo Web_Save.Open() >>%vbDownFile% echo Web_Save.Write(Web_Download.responseBody) >>%vbDownFile% echo Web_Save.SaveToFile Wscript.Arguments.Item(1),2 >>%vbDownFile% echo Web_Save.Close() >>%vbDownFile% cscript //NoLogo /e:vbscript %vbDownFile% "%url%" "%saveFilePath%" 2>nul del /f /q %vbDownFile% 2>nul (if /i not %3.==. (set %3="%saveFilePath%"))&exit/b ::goto :eof :getTimeStamp <ret> title 获取当前时间戳 if /i %Is_Debug% GTR 0 echo %0&echo %date% %time% for /f "tokens=1,2,3,4,5,6,* delims=-/\:." %%a in ("%date%-%time%") do (if /i not %1.==. (set %1=%%a%%b%%c%%d%%e%%f)&exit/b) &exit/b
=