I have a batch file that compiles a project and then runs a JS that connects to a DSP, runs the program and reads the results from the DSP's memory (more detailed info about the DSP etc. is at the end of my question).
My problem is that the compiling and JS running is run in a loop inside my batch file and sometimes, for some reason, the build is stuck, an exception in the DSP is thrown or the DSP is stuck in a condition that is preventing the batch to continue to the next step in the loop.
What I want to implement is some kind of a watchdog in my batch file that lets the current loop step last for a limited time and if that time expires, continue to the next step.
the DSP is TI6678EVM, using CodeComposer v5.3 and DSS.
The batch file's loop:
:CREATE_TEST_DIR
SET "test_dir=%cur_dir%%proj_name%"
ECHO %test_dir%
IF NOT EXIST %test_dir% GOTO INC_TESTN
ECHO ************************************************************************
ECHO Copying headers from %headers_folder_name%%test_num%
ECHO ************************************************************************
SET /a Idx=10
:CHANGE_HEADERS
REM Delete the header files from project dir
del %test_dir%\HeaderFiles\R_Main_%Idx%.h"
REM Copy test vectors header file to workspace
COPY /y "%test_dir%\%headers_folder_name%%test_num%\R_Main_%Idx%_%test_num%.h" "%test_dir%\HeaderFiles\R_Main_%Idx%.h"
SET /a Idx+=1
IF %Idx% leq 16 GOTO CHANGE_HEADERS
ECHO ************************************************************************
ECHO Building project
ECHO ************************************************************************
REM Create and build project
CALL "%eclipsec_path%" -noSplash -data "%test_dir%" -application com.ti.ccstudio.apps.projectBuild -ccs.workspace -ccs.buildType clean > "%test_dir%\p_build.log" || GOTO FAIL_BUILD
CALL "%eclipsec_path%" -noSplash -data "%test_dir%" -application com.ti.ccstudio.apps.projectBuild -ccs.workspace > "%test_dir%\p_build.log" || GOTO FAIL_BUILD
REM ECHO Project build successful
FOR /r "%test_dir%" %%a in (*.ccxml) do set CCXML_path=%%~dpnxa
IF "%CCXML_path%"=="" GOTO BAD_CCXML
ECHO Found .ccxml file %CCXML_path%
FOR /r "%test_dir%" %%a in (*.out) do set OUT_path=%%~dpnxa
IF "%OUT_path%"=="" GOTO BAD_OUT
ECHO Found .out file %OUT_path%
SET "testVecPath=%test_dir%\%headers_folder_name%%test_num%"
ECHO ************************************************************************
ECHO Runing tet
ECHO ************************************************************************
CALL "%dss_path%" "ccsRunTestVectors.js" %ccs_path% %test_dir% %CCXML_path% %OUT_path% %datetimef% %testVecPath%|| GOTO FAIL_BASIC
ECHO ************************************************************************
ECHO Test Done.
ECHO ************************************************************************
GOTO INC_TESTN
:FAIL_CREATE
ECHO Failed
:INC_TESTN
SET /a test_num+=1
REM pause
IF %test_num% gtr %TestNumEnd% GOTO DONE
GOTO CREATE_TEST_DIR
:DONE
Here is an example of what I mean, it will run the main loop, as long as the timer.cmd file is active with the title Timer. You can copy this as is and call it something like test_wait.cmd then run it, you will see that it will continue looping, echoing Still running as long as the script timer.cmd is running, which by the way this script creates for you.
You can then incorporate it into your script as you please.
#echo off
echo title Timer>timer.cmd
echo timeout 20 /NOBREAK ^>nul>>timer.cmd
echo exit>>timer.cmd
start /min timer.cmd & timeout 1 /NOBREAK>nul
:start
tasklist /FI "windowtitle eq Timer" | findstr /i "cmd.exe">nul 2>&1
if errorlevel 1 goto del timer.cmd /Q & goto :eof
echo Still running..
(timeout /t 1)>nul
goto :start
Related
i wanted to know if there is some way of doing music with batch, not just opening a mp3 file from cmd, but commands to do notes or something like that. If there really isn't how to do it, i understand.
batch can play music by creating and starting a vbs script to Leverage the internal windows media player.
Note: In all the below scripts, the variable %sounds% refers to the folder your sound scripts are located, and must be defined.
The core of playing music is the following Batch Script:
#Echo off & REM MusicPlayer.bat
Set "MusicPath=%~1" & REM Full Path for the music file
Set "vol=%~2" & REM Volume as number between 0 and 100
Set "LoopTF=%~3" & REM 'paramater 3 as 'true' or 'false' determines if the track is to be looped.
(
PUSHD %sounds%
%= Change to the directory your sound files are located =%)
::: Ensure no Conflict with the Previous Script.
IF exist PlayMusic.vbs (
DEL PlayMusic.vbs
)
::: Creates a vbs Script to launch the music (Occurs without any visual indication or prompting)
(
echo Set Sound = CreateObject("WMPlayer.OCX.7"^)
echo Sound.URL = "%MusicPath%"
echo Sound.settings.volume = %vol%
echo Sound.settings.setMode "loop", %LoopTF%
echo Sound.Controls.play
echo While Sound.playState ^<^> 1
echo WScript.Sleep 100
echo Wend
echo Sound objTS = Nothing 'Destroy the object.
)>PlayMusic.vbs
start /min PlayMusic.vbs
(
POPD
%= Return to your Previous Directory =%)
::: Exit the Launcher and return to Previous batch program.
GOTO :EOF
The above script is called with 3 parameters as Remarked.
Another Vbs can be used to Monitor the batch's status and call a batch script to stop the music when the batch is closed:
#Echo off & REM Monitor.bat
(
ECHO Set objWMIService = GetObject ("winmgmts:"^)
ECHO Set proc = objWMIService.ExecQuery("select * from Win32_Process Where Name='cmd.exe'"^)
ECHO DO while proc.count ^> 0
ECHO Set proc = objWMIService.ExecQuery("select * from Win32_Process Where Name='cmd.exe'"^)
ECHO if proc.count ^< 1 then exit do
ECHO wscript.sleep 1500
ECHO loop
ECHO Set WshShell=createobject("wscript.shell"^)
ECHO WshShell.run "%sounds%\KillMusic.bat", 0, true
)>%sounds%\MusicMonitor.vbs
start %sounds%\MusicMonitor.vbs
Goto :EOF
The above script creates a hidden vbs that fetches the number of instances of cmd.exe via the objWMIService.ExecQuery. This occurs during a loop, with the break condition being 0 open cmd.exe windows. A sleep is built into the loop to reduce the frequency of calls to the WMI service, as these are very resource intensive. When the loop break occurs, it starts the killmusic.bat program in a hidden state.
The below script "KillMusic.bat" is called either directly in your quit label or by the vbs monitor when it determines Cmd.exe is no longer running. DoMonitor is a variable that is changed in your main script prior to killmusic being called. 1 indicates the monitor should be restarted, and is used when killmusic.bat stops a currently playing song to start a new song. Monitor is a Variable containing the path to Monitor.bat
#ECHO OFF & REM KillMusic.bat
taskkill /pid WScript.exe /f /t >nul
IF exist "%sounds%\PlayMusic.vbs" (
DEL /Q "%sounds%\PlayMusic.vbs"
)
Timeout 1 > nul
IF "%DoMonitor%"=="1" GOTO reset
GOTO :EOF
:reset
CALL "%Monitor%"
GOTO :EOF
These three programs can be seen in effect here.
having an issue with a batch file which i would use in front of vagrant provisioning (merging files into an install-script to perform installation depending on user input) which looks like this:
#echo off
copy %CD%\Vagrantfile_base %CD%\Vagrantfile
echo Vagrant Provisionierung
echo 1 - nodejs
echo 2 - Nginx
echo 3 - Qt
echo 4 - Git
echo 5 - gcc
echo a - Alle vorgenannte Software
set /p choice=Mittels Zahlen durch Komma getrennt angeben, was installiert werden soll (Bspw. 1,2,3):
for %%i in (%choice%) do (
if "%%i"=="1" call :nodejs_install
if "%%i"=="2" call :nginx_install
if "%%i"=="3" call :qt_install
if "%%i"=="4" call :git_install
if "%%i"=="5" call :gcc_install
if "%%i"=="a" call :all_install
)
:nodejs_install
copy /b %CD%\software.sh+%CD%\software\nodejs_install.sh software.sh
PAUSE
goto :EOF
:nginx_install
copy /b %CD%\software.sh+%CD%\software\nginx_install.sh software.sh
PAUSE
goto :EOF
:qt_install
copy /b %CD%\software.sh+%CD%\software\qt_install.sh software.sh
PAUSE
goto :EOF
:git_install
copy /b %CD%\software.sh+%CD%\software\git_install.sh software.sh
PAUSE
goto :EOF
:gcc_install
copy /b %CD%\software.sh+%CD%\software\gcc_install.sh software.sh
PAUSE
goto :EOF
:all_install
call :nodejs_install
call :nginx_install
call :qt_install
call :git_install
call :gcc_install
PAUSE
goto :EOF
PAUSE
So when i execute the script it always calls the nodejs_install at the end even if i didnt choose it and i dunno why.
When i add an echo for the i it is empty shown.
Searching for very long but didnt found anything.
Maybe someone has an answer and/or fix for this?
Batch does not have true subroutines; if you do not protect the entry point of a subroutine with a GOTO to get around it, it will "fall through" into the routine. You need a GOTO :EOF after the ) and before the :nodejs_install.
Hello I am very new in this and I was able to run one instance of a batch file.
However, another file is being created called something.lock but the file is not been deleted by itself when I stop the batch or close it.
The new file create is the one that helps to have one instance running.
Can the new file ".lock " be deleted after I close the script with the "X" or because an user ended correctly with going to label end:
The code that I have is
:init
set "started="
2>nul (
9>"%~f0.lock" (
set "started=1"
call :start
)
)
#if defined started (
del "%~f0.lock"
) else (
cls
ECHO Only one instance is allowed
timeout /NOBREAK /T 3 >nul
cls
)
exit /b
:start
cd /d %~dp0
cls
:initial
pause >nul
You are misapplying the lock file. You are simply checking to see if the file exists, which means you must guarantee that the file is deleted upon batch termination.
There is a much better way, which you have only partially implemented. Only one process can have the file open for write access. You just need to determine if the file is already locked by another process.
Once the process with the exclusive lock terminates, the lock will be released. This is true no matter how the script terminates - even if it was the result of Ctrl-C or window closure. The file might not be deleted, but the next time the script runs, the file won't be locked, so the script will proceed nicely.
In the code below I save the current definition of stderr to an unused file handle before I redirect sterr to nul. Within the inner block I redirect stderr back to the saved definition. In this way I prevent the error message if the file is already locked, but the CALLed :start routine will still print out error messages normally.
#echo off
:init
8>&2 2>nul ( 2>&8 9>"%~f0.lock" call :start ) || (
cls
ECHO Only one instance is allowed
timeout /NOBREAK /T 3 >nul
cls
)
del "%~f0.lock" 2>nul
exit /b
:start
cd /d %~dp0
cls
del asdfasdfasdf
:initial
pause >nul
The difficulty is that your batch thread itself won't have its own PID. There's no graceful way to tell whether your batch script is running or when it has terminated. And there's no way to wake the dead, to let the script have the last word when a user red X's or Ctrl+C's. When it's over, it's over.
There are a few ways you can do what you want to do. Try them all and see which you prefer. Use dbenham's solution. His is correct. The following efforts are left here as an exercise in futility, although Solution 4 seems to work very well. In the end, it's still just a hack; whereas dbenham's redirection sleight-of-hand provides a correct implementation of lock files the way lock files are supposed to work.
...
Solution 1
One simple way is to use powershell to minimize the current window, re-launch your script with start /wait, then after completion call powershell again to restore.
#echo off
setlocal
set "lock=%temp%\~%~n0.lock"
if "%~1" neq "wrapped" (
if exist "%lock%" (
echo Only one instance is allowed.
timeout /nobreak /t 3 >NUL
exit /b
)
rem :: create lock file
>"%lock%" echo 1
rem :: minimize this console
powershell -windowstyle minimized -command ""
rem :: relaunch self with "wrapped" argument and wait for completion
start /wait "" cmd /c "%~f0" wrapped
rem :: delete lock file
del "%lock%"
rem :: restore window
powershell -windowstyle normal -command ""
goto :EOF
)
:: Main script goes here.
:loop
cls
echo Simulating script execution...
ping -n 2 0.0.0.0 >NUL
goto loop
This should be enough for casual use and should account for any cause of the batch file's termination short of taskkill /im "cmd.exe" /f or a reboot or power outage.
Solution 2
If you need a more bulletproof solution, you can get the current console window's PID and intermittently test that it still exists. start /min a helper window to watch for its parent window to die, then delete the lock file. And as long as you're creating a watcher anyway, might as well let that watcher be the lock file.
Biggest drawback to this method is that it requires to end your main script with exit to destroy the console window, whether you want it destroyed or not. There's also a second or two pause while the script figures out its parent's PID.
(Save this with a .bat extension and run it as you would any other batch script.)
#if (#a==#b) #end /* JScript multiline comment
:: begin batch portion
#echo off
setlocal
:: locker will be a batch script to act as a .lock file
set "locker=%temp%\~%~nx0"
:: If lock file already exists
if exist "%locker%" (
tasklist /v | find "cleanup helper" >NUL && (
echo Only one instance allowed.
timeout /nobreak /t 3 >NUL
exit /b
)
)
:: get PID of current cmd console window
for /f "delims=" %%I in ('cscript /nologo /e:Jscript "%~f0"') do (
set "PID=%%I"
)
:: Create and run lock bat.
>"%locker%" echo #echo off
>>"%locker%" echo setlocal
>>"%locker%" echo echo Waiting for parent script to finish...
>>"%locker%" echo :begin
>>"%locker%" echo ping -n 2 0.0.0.0^>NUL
>>"%locker%" echo tasklist /fi "PID eq %PID%" ^| find "%PID%" ^>NUL ^&^& ^(
>>"%locker%" echo goto begin
>>"%locker%" echo ^) ^|^| ^(
>>"%locker%" echo del /q "%locker%" ^&^& exit
>>"%locker%" echo ^)
:: Launch cleanup watcher to catch ^C
start /min "%~nx0 cleanup helper" "%locker%"
:: ==================
:: Rest of script
:: blah
:: blah
:: blah
:: ==================
:end
echo Press any key to close this window.
pause >NUL
exit
:: end batch portion / begin JScript
:: https://stackoverflow.com/a/27514649/1683264
:: */
var oShell = WSH.CreateObject('wscript.shell'),
johnConnor = oShell.Exec('%comspec% /k #echo;');
// returns PID of the direct child of explorer.exe
function getTopPID(PID, child) {
var proc = GetObject("winmgmts:Win32_Process=" + PID);
return (proc.name == 'explorer.exe') ? child : getTopPID(proc.ParentProcessID, PID);
}
var PID = getTopPID(johnConnor.ProcessID);
johnConnor.Terminate();
// output PID of console window
WSH.Echo(PID);
Solution 3
You can also test a lock file and see whether it's stale by setting a timestamp within the lock file, and setting that same timestamp in your console window title. Only problem with this is that the window title doesn't revert to normal if the user terminates with Ctrl+C, so you can't run the script twice without closing the cmd window. But closing the window and opening a new one for subsequent launches may not be too terrible a price to pay, as this is the simplest method described thusfar.
#echo off
setlocal
set "started=%time%"
set "lockfile=%temp%\~%~n0.lock"
if exist "%lockfile%" (
<"%lockfile%" set /P "locktime="
) else (
set "locktime=%started%"
)
tasklist /v | find "%locktime%" >NUL && (
echo Only one instance allowed.
timeout /nobreak /t 3 >NUL
exit /b
)
title %~nx0 started at %started%
>"%lockfile%" echo %started%
:: rest of script here
echo Simulating script execution...
:loop
ping -n 2 0.0.0.0 >NUL
goto loop
Solution 4
Here's a bit more polished solution, combining methods 1 and 3. It re-launches itself in the same window, then sets the window title to a unique ID. When the script exits gracefully, the lock file is deleted. Whether the script exits gracefully or forcefully, the window title reverts back to its default. And if no window exists in the task list with a title matching the unique ID, the lock file is deemed stale and is overwritten. Otherwise, the script notifies the user that only one instance is allowed and exits. This is my favorite solution.
#echo off
setlocal
if "%~1" neq "wrapped" (
cmd /c "%~f0" wrapped %*
goto :EOF
)
:: remove "wrapped" first argument
shift /1
:: generate unique ID string
>"%temp%\~%~n0.a" echo %date% %time%
>NUL certutil -encode "%temp%\~%~n0.a" "%temp%\~%~n0.b"
for /f "usebackq EOL=- delims==" %%I in ("%temp%\~%~n0.b") do set "running_id=%%I"
del "%temp%\~%~n0.a" "%temp%\~%~n0.b"
set "lockfile=%temp%\~%~n0.lock"
if exist "%lockfile%" (
<"%lockfile%" set /P "lock_id="
) else (
set "lock_id=%running_id%"
)
tasklist /v | find "%lock_id%" >NUL && (
echo Only one instance allowed.
timeout /nobreak /t 3 >NUL
exit /b
)
title %running_id%
>"%lockfile%" echo %running_id%
:: rest of script here
echo Press any key to exit gracefully, or Ctrl+C to break
pause >NUL
del "%lockfile%"
goto :EOF
Basically I have created an choice batch that every so often I can archive the contents of my boot data since I change it quite often and it works absolutely perfect, however I face the problem that every time I compile the batch from .BAT to.EXE with Advanced BAT to EXE converter the command 'bcdedit' never works and says “Not recognised as an internal or external command, operable program or batch file.”
Now the first thing I did was to make sure if I had the environment variables directed on my hard drive and it seemed fine:
Path: %SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;C:\Users\Support\DOCUME~1\MYFILE~1\Programs\SYSTEM~1\DISKEE~1\
It has all the variables needed to work perfectly plus a few external ones which is ok then I thought that maybe I should try to make it direct on my folder, by doing some research I found on another forum:
Setting or Modifying a System Wide Environment Variable In CMD.EXE
I made a separate .BAT and I called it and it seems it did create the separate variable:
C:\Users\???\Documents\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;C:\Users\Support\DOCUME~1\MYFILE~1\Programs\SYSTEM~1\DISKEE~1" /f
But It Still Didn't Work!
I read upon another form:
Syswow64 Redirection
The person solution was to use Create Process () to create a program that automatically redirects him to the folder using sysnative (System32) but I'm a total beginner at C#, CMD is my strongest area when it comes to coding.
Please please I beg of you to help me as soon as possible and if you do have an answer please state in the easiest way possible and why. Here's my script just in case:
:START
echo.
echo Call apath.bat
echo.
echo.
echo (E) - Start Process.
echo (C) - Launch Part 2 Of Process.
echo (N) - Load NoDrives Manager.
echo (D) - Display Currect Account and Computer Information
echo (X) - Exit EDIM.
echo.
echo NOTE - It will not work if not started with Admin Privillages.
echo.
:Choice
set/p Option=Please enter your option:
if '%Option%' == 'E' goto :Incognito
if '%Option%' == 'C' goto :Touch
if '%Option%' == 'N' goto :Manager
if '%Option%' == 'D' goto :Data
if '%Option%' == 'X' goto :Exit
echo.
echo.
echo Invalid Option - Please Reselect.
goto :Choice
:RetryE
Echo An Error was found!
set/p RetryE=Retry? Y/N:
if '%RetryE%' == 'Y' goto :Incognito
if '%RetryE%' == 'N' goto :Exit
:Incognito
Timeout 5
echo.
echo.
echo.
Echo Saving OriginalBCD...
bcdedit /export "Data/BCD/OriginalBCD"
IF %ERRORLEVEL% GTR 0 goto :RetryE
IF %ERRORLEVEL% LSS 0 goto :RetryE
Echo Checking presence of BCD...
IF NOT EXIST "Data/BCD/OriginalBCD" goto :RetryE
Echo Deleting Boot Entry...
bcdedit /delete {current}
IF %ERRORLEVEL% GTR 0 goto :RetryE
IF %ERRORLEVEL% LSS 0 goto :RetryE
Echo Saving EditedBCD...
bcdedit /export "Data/BCD/IncogBCD"
IF %ERRORLEVEL% GTR 0 goto :RetryE
IF %ERRORLEVEL% LSS 0 goto :RetryE
Echo Checking presence of BCD...
IF NOT EXIST "Data/BCD/IncogBCD" goto :RetryE
Echo Allowing User Control For Assigning System Reserved Partitions...
Echo -Commands-
Echo Diskpart
Echo List volume
Echo Select Volume "" (The one that has no Letter and remember number)
Echo Assign Letter=Z
Echo Select Volume "" (The one that has Letter E and remember number)
Echo Remove Letter=E (This is the new system reserved partition)
Echo Then exit Diskpart to finish Part 1.
Diskpart
Echo Ready To Restart!
Timeout 5
Shutdown /r /t 30
Goto :Start
:RetryC
set/p RetryE=Retry? Y/N:
if '%RetryC%' == 'Y' goto :Touch
if '%RetryC%' == 'N' goto :Exit
:Touch
echo.
echo.
echo.
Echo Loading NDM...
Echo NOTE - Store the password somewhere safe!!!
Start "" "Data/NDM.exe"
Echo Loading EditedBCD...
bcdedit /import "Data/BCD/IncogBCD"
IF %ERRORLEVEL% GTR 0 goto :RetryC
IF %ERRORLEVEL% LSS 0 goto :RetryC
Echo Process Complete!
Timeout 5
Echo Returning to menu...
goto :Start
:Manager
echo.
Echo NOTE - Store the password somewhere safe!!!
Start "" /WAIT "Data/ndm.exe"
Echo Returning to Menu...
goto :Start
:Data
echo.
echo.
echo.
echo Processing Data...
Systeminfo
diskpart /s "Data/discpart.txt"
Echo Returning to Menu...
goto :Start
:Exit
Exit
Thanks So Much!
bcdedit is on the path by default so unless you are reusing the PATH variable then the problem is in the batch compiler.
You can test this by using the plain batch file - and if it works then you know where the problem is.
So, how I have it done right now, is that it that it calls another bat file to update it, and then that batch file updates, and sets %ERRORLEVEL% to 1. At the start of the original program, it checks if errorlevel is 1, if yes, it goes to the main menu, but right now, it doesn't call the update file, it just goes to the menu. This is my code
Main program
IF %errorlevel% EQU 1 goto begin
call updater.bat
:begin
echo MENU
Updater
set=errorlevel 1
wget (updatelink here)
call mainprogram.bat
Right now, sometimes it works, sometimes it doesn't, which leads me to believe that some command is somehow increasing the errorlevel, but the only code before the errorlevel check is
#echo off
color 0f
cls
set currentver=v0.5.6
(check code)IF %errorlevel% EQU 1 goto begin
https://code.google.com/p/flashcart-helper/source/browse/trunk/0.6/FlashcartHelperRobocopy.bat
Here is what I have right now.
Don't play around with errorlevel. It's an internal variable. At the start of a batch, errorlevel will be 0 because all you've done is set a local variable. This will almost always ( never say never ) succeed. Also, if errorlevel is 1, and I'm reading this correctly you also seem to have an infinite loop? From what I understand of what you've said your batches are like this:
Main
#echo off
color 0f
cls
set currentver=v0.5.6
IF %errorlevel% EQU 1 goto begin
call updater.bat
:begin
echo MENU
Updater
set=errorlevel 1
wget (updatelink here)
call mainprogram.bat
As errorlevel get's overwritten each time you do anything you're asking for trouble. Change %errorlevel% to %error% and it should solve your problems. As it's a local environment variable it should also be passed between batch files. Just be careful not to use error elsewhere.
Here is a solution using Dropbox Public Folders and no wget. It uses PowerShell that in on Win7+ machines.
Update the below https://dl.dropboxusercontent.com/u/12345678/ url with your own.
It auto creates a .conf file for configuration.
Set __deploy_mode to 1 for the file on dropbox so the version file can be updated but the script not accidentally executed.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET time_start=%time%
SET time_choice_wait=20
SET script_ver=1.00
SET script_name=%~n0
SET server_url=https://dl.dropboxusercontent.com/u/12345678/
SET script_name_bat=%~dp0%script_name%.bat
SET script_name_cfg=%~dp0%script_name%.conf
SET script_name_latest_ver=%~dp0%script_name%.latest.ver
ECHO %script_name% v%script_ver%
ECHO %script_ver% > %script_name%.current.ver
IF NOT EXIST "%script_name_cfg%" CALL :SCRIPT_MISSING_CFG
FOR /f "delims=" %%x IN (%script_name%.conf) DO (SET "%%x")
IF %__deploy_mode% EQU 1 GOTO :EOF
IF %auto_update_compare% EQU 1 CALL :SCRIPT_COMPARE_VER
:SCRIPT_MAIN
REM =======================================
REM === EDIT BELOW THIS LINE ==
REM TODO Add main content
ECHO.
ECHO Waiting for content...
REM === EDIT ABOVE THIS LINE ==
REM =======================================
GOTO END
:SCRIPT_MISSING_CFG
ECHO Creating new %script_name%.conf file...
ECHO __deploy_mode=0 > "%script_name_cfg%"
ECHO repository_base_url=%server_url% >> "%script_name_cfg%"
ECHO auto_update_compare=1 >> "%script_name_cfg%"
ECHO auto_update_download=1 >> "%script_name_cfg%"
ECHO Update %script_name%.conf as needed, then save and close to continue.
ECHO Waiting for notepad to close...
NOTEPAD "%script_name_cfg%"
GOTO :EOF
:SCRIPT_COMPARE_VER
ECHO Please wait while script versions are compared...
Powershell -command "& { (New-Object Net.WebClient).DownloadFile('%server_url%%script_name%.current.ver', '%script_name_latest_ver%') }"
IF NOT EXIST "%script_name_latest_ver%" GOTO END
SET /p script_latest_ver= < "%script_name_latest_ver%"
IF %script_ver% EQU %script_latest_ver% CALL :SCRIPT_COMPARE_VER_SAME
IF %script_ver% NEQ %script_latest_ver% CALL :SCRIPT_COMPARE_VER_DIFF
GOTO :EOF
:SCRIPT_COMPARE_VER_SAME
ECHO Versions are both %script_name% v%script_ver%
GOTO :EOF
:SCRIPT_COMPARE_VER_DIFF
ECHO Current Version:%script_ver% ^| Server Version:%script_latest_ver%
IF %auto_update_download% EQU 1 GOTO SCRIPT_DOWNLOAD_SCRIPT
ECHO.
ECHO Would you like to download the latest %script_name% v%script_latest_ver%?
ECHO Defaulting to N in %time_choice_wait% seconds...
CHOICE /C YN /T %time_choice_wait% /D N
IF ERRORLEVEL 2 GOTO SCRIPT_DOWNLOAD_NOTHING
IF ERRORLEVEL 1 GOTO SCRIPT_DOWNLOAD_SCRIPT
IF ERRORLEVEL 0 GOTO SCRIPT_DOWNLOAD_NOTHING
:SCRIPT_DOWNLOAD_SCRIPT
ECHO Please wait while script downloads...
Powershell -command "& { (New-Object Net.WebClient).DownloadFile('%server_url%%script_name%.bat', '%script_name_bat%') }"
ECHO Script Updated to v%script_latest_ver%^^!
REM User must exit script. Current batch is stale.
GOTO :END
:SCRIPT_DOWNLOAD_NOTHING
GOTO :EOF
:END
SET time_end=%time%
ECHO.
ECHO Script started:%time_start%
ECHO Script ended :%time_end%
:END_AGAIN
pause
ECHO.
ECHO Please close this window
ECHO.
GOTO END_AGAIN
You can do that through these steps:
1.put two files in server,a config file, a higher version bat file which need to update; set last version num. in config file.
2.client bat should be checked update at every startup time. you can read the news version in server config file, then compared to local bat file version. if not equal, so do update, else other wise.
Do you have any problems?