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.
Related
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
I am new to using the %random% command in batch scripts and I am trying to create a batch script to randomly create a number between 0 and 3. I wrote the following but with every instance (everytime I double-click the BAT file) I get the same number '1'. This defeats the purpose. Which is based on this number copy over a selected video file so it is random.
echo off
set numb=" "
set /a numb=%random% / 10000
echo %numb% :only used for testing
pause :only used for testing
if %numb% LEQ 1 goto trailer
if %numb% EQU 2 goto dragon
if %numb% EQU 3 goto live
:dragon
echo Dragon
copy /Y "F:\Skyrim SSE\mod backup - files\Dragon flyby - BGS_Logo.bik" "D:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Video\BGS_Logo.bik"
exit
:trailer
echo Trailer
copy /Y "F:\Skyrim SSE\mod backup - files\Official Trailer-BGS_Logo.bik" "D:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Video\BGS_Logo.bik"
exit
:live
Echo Live
copy /Y "F:\Skyrim SSE\mod backup - files\Dragonborne-live-BGS_Logo.bik" "D:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Video\BGS_Logo.bik"
exit
I want to keep this as simple as possible as this really doesn't need to be complicated. Please help
Here's an example of one way to do it:
#Echo Off
Set "_s=F:\Skyrim SSE\mod backup - files"
Set "_d=D:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Video\BGS_Logo.bik"
Set/A "_r=%RANDOM%%%3"
>Nul Choice /C 012 /N /T 0 /D %_r%
If ErrorLevel 3 GoTo Dragon
If ErrorLevel 2 GoTo Trailer
If ErrorLevel 1 GoTo Live
GoTo :EOF
:Dragon
Echo(Dragon
Copy /Y "%_s%\Dragon flyby - BGS_Logo.bik" "%_d%"
GoTo EndIt
:Trailer
Echo(Trailer
Copy /Y "%_s%\Official Trailer-BGS_Logo.bik" "%_d%"
GoTo EndIt
:Live
Echo(Live
Copy /Y "%_s%\Dragonborne-live-BGS_Logo.bik" "%_d%"
:EndIt
GoTo :EOF
I used CHOICE for no real reason, I just preferred it to a series of IF's with comparison operators ,EQU, NEQ, LSS, LEQ, GTR, GEQ.
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.
I want to know if it is possible to start a batch thin in a particular goto function from another batch?
thus not just starting another batch file but also have the "mother" batch select a particular goto option with in the "child"batch?
1.bat
call 2.bat /c goto :this
call 2.bat /c call :that
.
2.bat
if "%1"=="/c" shift & shift & %2 %3
goto :eof
:this
echo This!
goto :eof
:that
echo That!
goto :eof
EDIT: My original post was closest to correct. But I've corrected my mistake(s).
I double shift to remove %1 and %2 to the left, bringing any other variables passed to the %1 and %2 positions. I then execute %2 and %3 because the effect of the shifts won't take effect until the line is finished being executed / interpreted.
Just have the parent/mother batch file and pass a parameter to the child batch file.
mom.bat
#ECHO OFF
ECHO Here we go
CALL child.bat 3
PAUSE
child.bat
#ECHO OFF
IF "%1"=="1" Goto 1
IF "%1"=="2" Goto 2
IF "%1"=="3" Goto 3
EXIT
:1
ECHO 1!
PAUSE
EXIT
:2
ECHO 2!
PAUSE
EXIT
:3
ECHO 3!
PAUSE
EXIT
This example should echo 3! as the mother batch file passes the parameter 3 to the child batch file.
Yes, but it's a hack.
Normally you would do this with a bit of help from the called batch file.
main.bat
call second.bat :theFunction
*second.bat
goto %1
...
:theFunction
The hack uses a feature-bug, you only need the same label as in the second.bat.
And it only works if you start the second.bat without call
main.bat
call :theFunction
echo back in main
exit /b
:theFunction
second.bat
echo back in the func in main, this line will never reached
exit /b This line will also never reached
When the second.bat returns , it will return to the line after the call in main.bat
In the batch file that you are calling put this at the top
if not %1=="" goto :%1
In the batch file you are using to call it put
call b.bat labelname
Obviously this is limited depending on what you are trying to do but the basic functionality works.
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?