I have developed a batch script which checks for the version of the software installed on a machine and based on the version it picks up the correct version patch and installs it (runs) on the machine.
However i am facing an issue where when i check for a particular string in a file path and if the file doesnt exist then it should go to else but in my case it is still continuing with ERRORLEVEL 1 option. Please have a look at the command below:
sfk find "%PATH%\Env\Met\Env.xml" "<Version>806</Version>"
Pause
ECHO %ERRORLEVEL%
Pause
IF ERRORLEVEL 1 (GOTO CHECK_RFA_v8.6) ELSE GOTO CHECK_MET_v8.6
Its possible that some clients based on their subscription may have restricted access to the market and hence few markets could be missing in the software. Here in this case as one of the market is missing, the file Env.xml doesnt exist in the path and so i want it to go to else (CHECK_MET_v8.6) rather than proceed with errorlevel 1 (CHECK_RFA_8.6).
What i dont understand is why is it going to CHECK_RFA_v8.6 if the errorlevel is not 1. I have added ECHO %ERRORLEVEL% to check what is it returning and it is 9.
Output:
Where is software installed?
error: no such file or dir: C:\AR\Env\Met\Env.xml
1 errors occurred.
Press any key to continue . . .
9
Press any key to continue . . .
CHECKING RFA v8.6
Can somebody please explain why would it continue with ERRORLEVEL 1 option if the returned error code is 9? and how can i handle it?
If you read the description of if command (available via if /?), you will realize that if errorlevel number command will execute the command when the errorlevel is greater or equal than the number. If you want to execute the command when the number is precisely a certain value, use this form:
IF %ERRORLEVEL% EQU 1 (GOTO CHECK_RFA_v8.6) ELSE GOTO CHECK_MET_v8.6
Related
I am trying to understand why the first line of my batch file fails to execute. My code is as follows:
if exist reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion" goto OptionOne
exit
:OptionOne
some code
goto:eof
It never goes to the OptionOne subroutine. Instead, it just exits.
I do have a solution to this problem written differently (so I don't want examples to make it work) but I want to understand why this one line fails to execute.
Is the syntax improper? Google says it is correct.
Poorly designed code? I know this registry key exists so this is not the case.
Is it something with the return value and its correct syntax, but needs to be further written out on the else statements?
The code you have doesn't work because if exist is used only to check if folders or files exist. Its syntax is:
if exist "C:\foldername\" (do something) else (optionally do something else)
for folders and:
if exist "C:\filename" (do something) else (optionally do something else)
for files.
My suggested solution (as mentioned in comments) is the following:
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion" >nul 2>&1
if %errorlevel% EQU 0 (goto :OptionOne) else (echo Registry key not found. & pause>nul & exit /b 1)
:OptionOne
some code
goto :eof
which checks if the command returned errorlevel different than equal to 1 or bigger (the registry key exists) or 1 or bigger (it doesn't exist).
REG QUERY only returns 0 for success or 1 for failure. Note that no results is still a successful query operation and will return 0.
Ref: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/reg-query
And as commentors noted, IF EXIST is only for files and folders, not for commands.
Just launch reg query and check %errorlevel%, as you can see here:
Prompt>reg query "HKCU\..." (put something which exists)
<some successful answers>
Prompt>echo %errorlevel%
0
Prompt>reg query "blabla"
ERROR: Invalid key name.
Type "REG QUERY /?" for usage.
Prompt>echo %errorlevel%
1
You can check %errorlevel% in your batch script.
Trying my hands on windows batch files, in the below code that I found by searching in www.
#ECHO OFF
REM Call this with two arguments, and it will add them.
SET a=%1+%2
IF %ERRORLEVEL%==0 (goto errors-0) ELSE (goto errors-1)
REM Instead of using goto with the variable, this uses an IF-ELSE structure
:errors-0
REM This is if it was successful
ECHO %a%
goto exit
:errors-1
REM this is if it had an error:
ECHO Errors occurred.
goto exit
REM GUESS WHAT, THIS REM WILL NEVER EVER BE READ! IT WILL BE SKIPPED OVER BY THE GOTOS
:exit
ECHO.
ECHO press any key to exit.
PAUSE>nul
The code is suppose to take 2 arguments, add them and echo the result.
But this won't execute with success on my Windows 8.1 machine. Below is what I get:
C:\ProjectDoc>add3.bat
Errors occurred.
press any key to exit.
So, U added an echo for the ERRORLEVEL to see its value after executing the command SET. Below is the output:
C:\ProjectDoc>add3.bat 2 3
9009
Errors occurred.
press any key to exit.
C:\ProjectDoc>
So, is this errorlevel in Windows equal to the $? of Linux. Should it be returning 0 for every successful execution of a command or is it different? Reading some docs relates it to the Linux $? but it isn't clearly working as $? in Linux.
Yes, to be precise, %errorlevel% is analogous to $? in Bash shell.
In your batch file, SET a=%1+%2 is not doing what you expect it to do. It just sets the value of the variable a to the string "2+3" assuming you ran the file with arguments 2 3. If you want to do arithmetic you need to use the /A option: set /a a=%1+%2.
The SET command (and many other built-in commands) only set the ERRORLEVEL if there has actually been an error. If it was successful, the ERRORLEVEL will retain its previous value. I think this is what you're witnessing in your question.
By contrast, when a command runs an executable file, when the process completes it always sets the ERRORLEVEL.
As well as checking the ERRORLEVEL variable for specific values, it is idiomatic (for historical reasons) to check the errorlevel using the following expression
IF ERRORLEVEL 1 ECHO Hello
This will run the given command if ERRORLEVEL is 1 or above - in other words, if any error has occurred.
I'm writing a batch script to install an exe and a successful installation returns 0 and other codes mean different reasons.
I know I can print those error code(s) by echo %errorlevel%
Can I print the description related to the code instead? If so, how?
i.e. print 'successful' for code 0, etc.
Add below lines to print a message using error codes
if %errorlevel% equ 0 echo Successful
if %errorlevel% NEQ 0 echo Not Successful
Because errorlevel 0 indicates that return values of last executed command is successful,other return values have their own meaning
You can use || to act on failure, for simplicities sake this should do fine.
if %errorlevel% equ 0 echo Installed! || echo Install failed...
And && to activate on success.
del file.ext && echo File deleted.
The reason I don't provide a per errorlevel basis is that there can be up to 255 of them, something that would take an exceedingly high amount of time, and is further hindered by the tendency of programs not publically showing or ever documenting what each and every errorlevel means.
Something good to keep in mind is the difference between %errorlevel% and errorlevel. here
I'm pretty new to this forum so i first want to thank you for providing me with solutions even before i became a member :).
So I have this code:
for %%a in ("%PBpath%") do (
move "network location 1 files" "network location 2" >NUL
if ERRORLEVEL 0 (echo Diagram %%~na.pdf was successfuly archived) else ( echo Diagram %%~na.pdf was not archived )
ECHO.%errorlevel%
)
The problem is that I can't get the errorlevel different than 0. Even when the files that are to be copied are missing from location, i still get the successfuly archived message echoed. I searched the forum for similar questions, but i couldn't make it work for some reason.
Is there something different between the copy and the ping command (the ping command returns the correct exit code in the errorlevel), because i can't get it with either copy or move...
Thanks!
Andrew
The strange thing about the IF ERRORLEVEL statement is that it doesn't act like you expect- it returns TRUE if the errorlevel is equal to OR GREATER THAN the number specified.
A failure in MOVE sets errorlevel to 1 (I just checked) which is greater than 0. Therefore the first clause in the IF statement will always be used. The easiest way to fix your script is to reverse the conditions in the IF statement:
if ERRORLEVEL 1 (echo file was not archived) else (echo file was successfully archived)
Just use %ERRORLEVEL% variable instead of ERRORLEVEL function
If one wants to use the ERRORLEVEL function, Superbob's answer address' this (though I would recommend the form if NOT ERRORLEVEL 1 (echo file was successfully archived) else (echo file was not archived) instead).
But if one wants to use the %ERRORLEVEL% variable method instead, Delayed Expansion needs to be turned on. The OP's code above, with the recommended changes, is below:
setlocal enabledelayedexpansion
for %%a in ("%PBpath%") do (
move "network location 1 files" "network location 2" >NUL
if !ERRORLEVEL! equ 0 (
echo Diagram %%~na.pdf was successfully archived
) else (
echo Diagram %%~na.pdf was not archived)
)
I am creating a bat file that does some basic functions for server builds. The script is made to be somewhat interactive. This allows us to use on script for Production, Dev, or QA. The area of the script that fails is below
echo Enter User-defined Information about this Server:
echo Environment:
echo 1. PROD
echo 2. QA
echo 3. Dev
echo Choose one:
CHOICE /C 123
if errorlevel 1 (set ENVIRONMENTNAME=PROD & set ENVNAME=Production)
if errorlevel 2 (set ENVIRONMENTNAME=QA & set ENVNAME=Acceptance)
if errorlevel 3 (set ENVIRONMENTNAME=Dev & set ENVNAME=Development)
Once I am prompted to "Choose One:" I choose either of the options then get the error:
: was unexpected at this time.
Remove the #echo off or echo off commands from the top of the script (or add echo on), and use the resulting output to debug which line causes the offending error.
For optimization purposes, put your if errorlevel commands in descending order. The if errorlevel command triggers when the ERRORLEVEL is the specified number or higher.
I realise this is a rather belated answer, but I've just experienced exactly the same error message, although it was a "set /p" that was causing the problem for me. The line was originally:
set /p Option=Do you want to go ahead and load the data? ([Y]/N):
and the solution I found was to put double quotes around the prompt text, so:
set /p Option="Do you want to go ahead and load the data? ([Y]/N): "
Don't know if that will help anyone or not, but it solved the problem for me :-)