First batch - brave!... and also Bravo!!
Let's take the reg
command to start with. Bizarrely, reg
does not set errorlevel
to non-0
if the requested key is missing. That's why ony the version 7
part was being executed.
reg query
with a missing key produces no output but it does produce an error message, ERROR: The system was unable to find the specified registry key or value.The output string is sent to
stdoutand is the output that would be processed by the
dopart. The error string is sent to
stderr` which is normally assigned to the console.
So - first, let's force num
to be "set" to nothing
set "num="
The syntax SET "var=value"
(where value may be empty) is used to ensure that any stray trailing spaces are NOT included in the value assigned. set /a
can safely be used "quoteless".
Batch is sensitive to spaces in a SET
statement. SET FLAG = N
sets a variable named "FLAGSpace" to a value of "SpaceN" set /a
is a later implementation which ignores this rule. (just a caution)
Then we can use a tickled version of your code
for /f "tokens=3" %%a in ('reg query HKLM\Software\Wow6432Node\TeamViewer\Version7 /v ClientID 2^>nul') do (set /a num = %%a)
where the additional 2^>nul
redirects stderr
messages to nul
(ie nowhere). The caret ^
is called an escape character
and is required here because the >
is part of the reg query
not part of the for
. (the >
is thus termed "escaped")
The result will be that if the key exists, the set
will be executed and num
will be assigned a value. If the key is missing, num
will remain unchanged.
Remember, we initialised num to nothing? And we may now have set num
to something
(if the key exists?) so now we can test whether the variable has been set or not
if defined num goto print
(batch is largely case-insensitive)
So - a little excursion now into the syntax of if
. In the action part, batch has no idea of whether the string else
is some command's parameter or is the keyword ELSE
. Consequently, we need to tell it:
if somebinarycondition (
dothis_if_true
) else (
dothis_if_false
)
or
if somebinarycondition (dothis_if_true) else (dothis_if_false)
The positioning of the parentheses is critical. The first open must be on the same physical line as the if
(or do) and if an else is used then both the preceding )
and succeeding (
must occur on the same physical line as the else
and there must be a space between the else
keyword and the parentheses. This allows multiple lines to be conditionally executed. The parentheses are not required if the else
clause is missing or on the else
clause if only one command is required to be executed.
Batch simply executes instructions line-by-line until end-of-file or an exit
statement is encountered, hence
if condition (goto there) else (goto here)
:here
is simpler written
if condition goto there
:here
so the instructions following the label :here
would be executed if condition
is false.
Hence, overall,
SET "num="
for /f "tokens=3" %%a in ('reg query HKLM\Software\Wow6432Node\TeamViewer\Version7 /v ClientID 2^>nul') do (set /a num = %%a)
IF DEFINED num GOTO print
:EIGHT
for /f "tokens=3" %%a in ('reg query "HKLM\Software\Wow6432Node\TeamViewer\Version8 /v ClientID" 2^>nul') do (set /a num = %%a)
IF DEFINED num GOTO print
:NINE
for /f "tokens=3" %%a in ('reg query HKLM\Software\Wow6432Node\TeamViewer /v ClientID 2^>nul') do (set /a num = %%a)
IF DEFINED num GOTO print
echo Not found!
pause
goto :eof
:Print
echo Teamviewer ID is %num%
Unlike many languages, batch has no concept of the end of a "procedure" - it simply continues execution line-by-line until it reaches the end-of-file. Consequently, you need to goto :eof
after completing the mainline, otherwise execution will continue through the subroutine code. :EOF
is a predefined label understood by CMD
to mean end of file
. The colon is required.
for /f "tokens=3" %%a in ('reg query HKLM\Software\Wow6432Node\TeamViewer\Version7 /v ClientID') do (set /a num = %%a) if %ERRORLEVEL% EQU 0 (echo TeamViewer number is %num% ) else (echo not exists) – J Haro Dec 31 '15 at 16:46