Reg Query Batch File - batch-file

To summarise what I want to achieve, I want to query 2 keys, if they exist go to end of batch file, if not install Java.
The batch file is installing Java fine, but when testing if I delete the .txt file:
IF exist %windir%\gpologs\jre_1.7.21.x86.txt goto eof ELSE goto Q1
The installer still tried to install over the top, even though one of the registry keys exists?
Here is full batch file:
IF exist %windir%\grouppolicylogs\jre_1.7.21.x86.txt goto eof ELSE goto Q1
:Q1
Reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{26A24AE4-039D-4CA4-87B4-2F86417025FF}"
if %ErrorLevel% EQU == 0 goto End ELSE goto Q2
:Q2
Reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{26A24AE4-039D-4CA4-87B4-2F83217021FF}"
if %ErrorLevel% EQU == 0 goto End ELSE goto Install
:Install
msiexec /i "\\servername\SoftwareRep\Java\Java 1.7.0_21 x86\jre1.7.0_21.msi" /qn
if %ErrorLevel% EQU 0 (
>>"\\servername\gpolog\jre_1.7.21.x86.csv" echo "%computername%","%date%","%Time%","%ErrorLevel%","Java Runtime 1.7.0_21x86 Installed"
>>"%windir%\GpoLogs\jre_1.7.21.x86.txt" echo "Java Runtime 1.7.0_21x86 Installed"
) else (
>>"\\servername\gpolog\JavaInstallErrors.csv" echo "%computername%","%date%","%Time%","%ErrorLevel%","Error trying to install Java 1.7_21x86"
)
:END
Where am I going wrong?

Use only one equals operator. Not both EQU and ==
if "%ErrorLevel%"=="0" goto End ELSE goto Q2
if "%ErrorLevel%"=="0" goto End ELSE goto Install
Scope your if statement commands
if "%ErrorLevel%"=="0" ( goto End ) ELSE ( goto Q2 )
if "%ErrorLevel%"=="0" ( goto End ) ELSE ( goto Install )
The eof needs a colon unless you have a eof label.
goto :eof
See if /?
See goto /?

Related

Multiple possible text inputs with if statements

I am trying to make a fully immersive text adventure using a batch file.
Here is my problem: I want the answers to be a text input, so that the players type in a response which dictates where they will go.
For a lot of questions I need there to be multiple possible inputs. For example when you get to an enemy there are tons of different things you could do, however I can only figure out how to get it to recognise one input.
With other words, I want system to take user input and do actions accordingly.
Here is my code for this section so far:
:forest1
echo you awake in a forest, you do not know where you are or why you are there.
echo infront of you is a small goblin like creature
:recoil1
echo What do you do?
set /p answer=
if %answer%==run (
goto run1
) else (
if %answer%==attack (
goto attack1
) else (
if %answer%==befriend(
goto befriend1
) else (
if %answer%==scream(
goto scream1
) else (
if %answer%==dance (
goto dance1
) else (
echo Nothing happened
timeout /t 1
goto forest1
)
Your way should be modified like this to work:
#echo off
rem Your code before the code you provided above ^^
:forest1
echo You awake in a forest, you do not know where you are or why you are there.
echo In front of you is a small goblin like creature
goto :recoil1
:recoil1
set /p "answer=What do you do? "
if "%answer%" == "run" (
goto :run1
) else (
if "%answer%" == "attack" (
goto :attack1
) else (
if "%answer%" == "befriend" (
goto :befriend1
) else (
if "%answer%" == "scream" (
goto :scream1
) else (
if "%answer%" == "dance" (
goto :dance1
) else (
echo Nothing happened.
timeout /t 1
goto :forest1
)
)
)
)
)
You see: this is complicated a bit; you missed lots of parenthesis!
So, use choice command with some modifications:
#echo off
rem Your code before the code you provided above ^^
:forest1
echo You awake in a forest, you do not know where you are or why you are there.
echo In front of you is a small goblin like creature
goto :recoil1
:recoil1
echo What do you do? Here is a list of options:
echo r - run away
echo a - attack the goblin
echo b - be friend with the goblin
echo s - scream
echo d - dance
echo n - do nothing
choice /C:rabsdn /N
if errorlevel 6 (
echo Nothing happened.
timeout /t 1
goto :forest1
)
if errorlevel 5 goto :dance1
if errorlevel 4 goto :scream1
if errorlevel 3 goto :befriend1
if errorlevel 2 goto :attack1
if errorlevel 1 goto :run1
which is clearer, faster and more readable, isn't it?
Note: the if with the errorlevel should be in descending order because if errorlevel n means if the errorlevel is greater than or equal to n!
Modify the options to better suit for you.
Why not try use if in the for looping to do this job?
#echo off
:forest1
cls & echo/ & if defined answer set answer=<nul
echo/ you awake in a forest, you do not know where you are or why you are there.
echo/ infront of you is a small goblin like creature
:recoil1
set /p "answer= What do you do? "
for %%i in (run attack befriend scream dance) do if /i "%answer%" == "%%i" goto :%answer%1
echo/ Nothing happened
timeout /t 1 & goto forest1
:run1
echo/ Here I'm in Label run1 & exit /b
:attack1
echo/ Here I'm in Label attack1 & exit /b
:befriend1
echo/ Here I'm in Label befriend1 & exit /b
:scream1
echo/ Here I'm in Label scream1 & exit /b
:dance1
echo/ Here I'm in Label dance1 & exit /b

Batch file, If Statement not working

The following if statement is not running. It just ends the bat file It stops the process. Why is this happening? How do I stop it?
if "%Choice%"=="si" (GOTO Case2) else (
if "%Choice%"=="s" (GOTO Case1) else (
if "%Choice%"=="ti" (GOTO Case4) else (
if "%Choice%"=="t" (GOTO Case3) else (
if "%Choice%"=="i" (GOTO Case5) else (
if "%Choice%"=="cp" (GOTO Case6) else (
if "%Choice%"=="kp" (GOTO Case7) else (
if "%Choice%"=="?" (GOTO CaseHelp) else (
if "%Choice%"=="c" (GOTO Case8) else (
if "%Choice%"=="sl" (GOTO Case9) else (
if "%Choice%"=="sf" (GOTO Case10) else (
if "%Choice%"=="fz" (GOTO Case11) else (
if "%Choice%"=="dc" (GOTO Case12) else (
if "%Choice%"=="cm" (GOTO Case12) else (
if "%Choice%"=="wh" (GOTO Case13) else (
if "%Choice%"=="vs" (GOTO Case14) else (
if "%Choice%"=="it" (GOTO Case15) else (
if "%Choice%"=="tm" (GOTO Case16) else (
if "%Choice%"=="d" (GOTO Case17) else (
if "%Choice%"=="ed" (GOTO Case18) else (
if "%Choice%"=="be" (GOTO Case19) else (
if "%Choice%"=="me" (GOTO Case20) else (
if "%Choice%"=="ap" (GOTO Case21) else (
if "%Choice%"=="pc" (GOTO Case22) else (
if "%Choice%"=="sc" (GOTO Case23) else (
if "%Choice%"=="c" (GOTO Case24) else (
if "%Choice%"=="ll" (GOTO Case25) else (
if "%Choice%"=="ij" (GOTO Case26) else (
GOTO CaseError)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
Also, is there an alternative of using an if statement as this method is uite time consuming.
Well, I see 28 opening (, but only 24 closing ), so it can't possibly work.
You don't show your complete relevant code, we can't see if you have all the required labels.
PaulF has a good point in his comment, since each IF does a GOTO, you don't need any ELSE statements.
if "%Choice%"=="si" GOTO Case2
if "%Choice%"=="s" GOTO Case1
if "%Choice%"=="ti" GOTO Case4
etc...
if "%Choice%"=="ij" GOTO Case26
goto CaseError
But let's suppose that you are not doing GOTO with each IF, but rather something else. There is no need to do a lot of indents, and you don't need so many parens. Batch does not formally have an ElseIf, but it functionally works just as well if you use ELSE IF. Look how I arrange the parens and indents - it is much easier to read and follow the code.
if "%Choice%"=="xxx" (
do something
) else if "%Choice%"=="yyy" (
do something else
) else if "%Choice%"=="zzz" (
do something different
) else (
everything else gets to here
)
Since you are performing GOTOs, there is another option. Incorporate the %Choice% value in the :label, and then you don't need any IF statement, other than to verify that the choice is valid, and take special action if it isn't.
Opion 1: Define the list of valid entries, and use find/replace to test if the choice is amongst the valid options. This is best done with delayed expansion. Note the leading and trailing space in the options list is important in this technique.
setlocal enableDelayedExpansion
set "options= si s ti t i cp kp ? c sl sf fz dc cm wh vs it tm d ed be me ap pc sc c ll ij "
set "choice="
set /p "choice=Enter your choice: "
if "!options: %choice% =!" neq "!options!" goto case_%choice%
goto case_error
:case_si
rem do something
exit /b
:case_s
rem do something else
exit /b
etc...
Option 2: Use FINDSTR to probe the batch file itself to verify the label exists. Here I am using a simplified search that will not handle all possible arrangements of valid labels. But it should be fine as long as you don't get creative with how you create your labels.
set "choice="
set /p "choice=Enter your choice: "
findstr /i /r /c:"^:case_%choice%$" /c:"^:case_%choice% " "%~f0" >nul 2>nul && goto :case_%choice%
goto :case_error
:Case_si
rem do something
exit /b
:Case_s
rem do something else
exit /b
etc...
I suggest to use the command CHOICE for this large selection between 28 options:
#echo off
:Menu
cls
echo 1 ... option 1
echo 2 ... option 2
echo and so on
echo 9 ... option 9
echo a ... option 10
echo and so on
echo r option 27
echo 0 ... help
echo/
%SystemRoot%\System32\choice.exe /C 123456789abcdefghijklmnopqr0 /N /M "Your choice: "
goto Case%ERRORLEVEL%
:Case1
echo Option 1
goto :EOF
:Case2
echo Option 2
goto :EOF
rem And so on
:Case28
cls
echo Help
echo/
pause
goto :Menu
Command CHOICE does not allow any invalid input. It waits with the used options until the user presses any key as specified after parameter /C and assigns to ERRORLEVEL the number according to index of the appropriate key/character in the list, i.e. 1 for first 1, 2 for second 2 and 28 for last key/character 0. Run in a command prompt window choice /? for help on this command.
goto Case%ERRORLEVEL% is not working if the entire menu code is within a command block starting with ( and ending with matching ) because variable reference %ERRORLEVEL% is replaced already by current value of environment variable ERRORLEVEL before the command left to ( is executed at all.
Delayed expansion must be enabled in this case and goto Case!ERRORLEVEL! must be used to get the GOTO working within a command block. Run in a command prompt set /? and read the hep output on several window pages for details about delayed expansion as well as setlocal /? used to enable delayed expansion and endlocal /? to restore previous command environment.
An alternate solution for the menu within a command block without using delayed environment variable expansion is replacing the command line goto Case%ERRORLEVEL% by
for /L %%X in (28,-1,1) do if errorlevel %%X goto Case%%X
See the Microsoft support article about Testing for a Specific Error Level in Batch Files why the decrementing FOR loop with the if errorlevel X condition executing goto CaseX works within a command block without usage of delayed expansion.
I think this is the simplest way to solve this problem:
#echo off
setlocal
set /p "Choice= Which Service? "
call :Case-%choice% 2> NUL
if errorlevel 1 goto CaseError
goto :EOF
:Case-si
echo You select "si" service
exit /B
:Case-s
echo You select "s" service
exit /B
:Case-etc
echo You select "etc" service
exit /B
:CaseError
echo Error: invalid service...
goto :EOF
When a call with a non-defined label is executed, the system automatically set ERRORLEVEL to one and continue to the next line, so you just need an if to detect such an error...
Using this method you don't need to check for each one of the options, just include the desired code below each one of the proper :Case-serviceNameHere labels and that is it!

Exit and re-enter loop in Windows batch file

I need to cycle through a list in a batch file, set a variable, exit the loop and then re-enter.
if "%scale%" == "ind" (
FOR %%A IN %inclpeople% do (
set person=%%A
goto :start
:cyclepeople
echo Done %person%
)
goto :end
)
set person=%scale%
:start
echo Starting with %person%
call %batch%\findperson
if %errorlevel% neq 0 goto :failed
call %batch%\dosomethingelse
if %errorlevel% neq 0 goto :failed
:finish
if "%scale%" == "ind" (
goto :cyclepeople
)
:end
call %footer%\success
exit /b 0
So, if scale is not "ind" (in this case it could be "all", then go to start and run commands only once. If scale equals "ind", then loop through a list of people, set person to loop variable, go to start and go back to loop until list is finished, then go to end.
Currently, this works only for the first loop and echos "Done Adam" (e.g. first person), but then goes to end.
For future reference, I will answer the question based on Stephan's comment above:
if "%scale%" == "ind" (
FOR %%A IN %inclpeople% do (
set person=%%A
call :start
echo Done %person%
)
goto :end
)
set person=%scale%
:start
echo Starting with %person%
call %batch%\findperson
if %errorlevel% neq 0 goto :failed
call %batch%\dosomethingelse
if %errorlevel% neq 0 goto :failed
:finish
if "%scale%" == "all" (goto :end)
goto :eof
:end
call %footer%\success
exit /b 0

Using GOTO inside an IF statement

if %_var%==1 (
goto :group1
) else if %_var%==2 (
goto :group2
) else (
goto :groupOthr
)
What am I doing wrong here ? I keep getting the error -
( was unexpected at this time.
Tried doing this -
if %_var%==1 (goto :group1
) else if %_var%==2 (goto :group2
) else (goto :groupOthr
)
And then I get -
(goto was unexpected at this time.
if "%_var%"=="1" (
goto :group1
) else if "%_var%"=="2" (
goto :group2
) else (
goto :groupOthr
)
Just got it right. Found the answer here - goto unexpected with blank choice
Simplify like this. And if you have your 'groupOthr' code directly below this you can remove the last goto.
if "%_var%"=="1" goto :group1
if "%_var%"=="2" goto :group2
goto :groupOthr
Also note that I quoted both sides of the comparison to avoid a problem if the variable is not defined.
This is the structure you should have been using.
if "%_var%"=="1" (
goto :group1
) else (
if "%_var%"=="2" (
goto :group2
) else (
goto :groupOthr
)
)
you dont need any brackets, they cause errors alot in if statements.
here is an example of a working if statement without brackets:
#echo off
:Main
cls
echo Press 1 or 2!
choice /c 12 /N >nul
if errorlevel 2
goto :Option2
if errorlevel 1
goto :Option1
:::::::::::::::::::::::::::
:Option2
cls
echo You pressed the number 2!
pause >nul
goto :Main
::::::::::::::::::::::::::::::::::::::
:Option1
cls
echo You pressed the number 1!
pause >nul
goto :Main
if %_var%==1 ( goto group1)
if %_var%==2 ( goto group2)
goto groupothr
put the spacebar in before goto... also try one after...
i don't see how my original answer didn't work... the following code is in one of my batch files, and it works fine:
if not defined targeturl (goto err400)
but, it also works like if not defined targeturl ( goto err400 )
also, i have a script:
#echo off
set defini=hi
if "%defini%"=="hi" (goto tyr)
echo no go.
pause
exit
:tyr
echo goto worked!
pause
exit
which also works like:
#echo off
set defini=hi
if "%defini%"=="hi" ( goto tyr)
echo no go.
pause
exit
:tyr
echo goto worked!
pause
exit
try copying the above code and saving it to trygoto.bat, and run it.
if %_var%==1 (goto group1)
if %_var%==2 (goto group2)
goto groupothr
try that! upvote if it worked!

Batch - If, ElseIf, Else

Whats wrong with this code?
IF "%language%" == "de" (
goto languageDE
) ELSE (
IF "%language%" == "en" (
goto languageEN
) ELSE (
echo Not found.
)
I'm not really good in Batch..
#echo off
title Test
echo Select a language. (de/en)
set /p language=
IF /i "%language%"=="de" goto languageDE
IF /i "%language%"=="en" goto languageEN
echo Not found.
goto commonexit
:languageDE
echo German
goto commonexit
:languageEN
echo English
goto commonexit
:commonexit
pause
The point is that batch simply continues through instructions, line by line until it reaches a goto, exit or end-of-file. It has no concept of sections to control flow.
Hence, entering de would jump to :languagede then simply continue executing instructions until the file ends, showing de then en then not found.
#echo off
set "language=de"
IF "%language%" == "de" (
goto languageDE
) ELSE (
IF "%language%" == "en" (
goto languageEN
) ELSE (
echo Not found.
)
)
:languageEN
:languageDE
echo %language%
This works , but not sure how your language variable is defined.Does it have spaces in its definition.
batchfiles perform simple string substitution with variables.
so, a simple
goto :language%language%
echo notfound
...
does this without any need for if.
Recommendation. Do not use user-added REM statements to block batch steps. Use conditional GOTO instead.
That way you can predefine and test the steps and options. The users also get much simpler changes and better confidence.
#Echo on
rem Using flags to control command execution
SET ExecuteSection1=0
SET ExecuteSection2=1
#echo off
IF %ExecuteSection1%==0 GOTO EndSection1
ECHO Section 1 Here
:EndSection1
IF %ExecuteSection2%==0 GOTO EndSection2
ECHO Section 2 Here
:EndSection2
#echo off
color 0a
set /p language=
if %language% == DE (
goto LGDE
) else (
if %language% == EN (
goto LGEN
) else (
echo N/A
)
:LGDE
(code)
:LGEN
(code)

Resources