Pipe doesn't work after reg query? - batch-file

i'm trying to check if there is a java installation on the machine with a batch file,and install java if necessary. However, the pipe doesnt work, and i get the reg query's result on the screen. Here is the code:
#ECHO OFF
cls
:checkjava
reg query "HKLM\Software\JavaSoft\Java Runtime Environment" | find "ERROR" > NUL
if %errorlevel% == 0
...

reg query "HKLM\Software\JavaSoft\Java Runtime Environment" 2>&1 | find "ERROR" > NUL
the error message is printed in error stream so you need to redirect it in the &1.
Here's more info : http://www.robvanderwoude.com/redirection.php

try this:
reg query "HKLM\Software\JavaSoft\Java Runtime Environment" >nul 2>&1 && goto:OK || goto:fail
:OK
echo reg key found
pause
goto:eof
:fail
echo ERROR key not found!
pause
goto:eof

Error messages are sent to Standard Error and to Standard Output hence you need to redirect Standard Error to Standard Output before running find on the output.
reg query "HKLM\Software\JavaSoft\Java Runtime Environment" 2>&1 | find "ERROR" > nul
Another thing is that reg query itself returns 0 or 1 on success or failure
Return Code: (Except for REG COMPARE)
0 - Successful
1 - Failed
So you may not have to use find at all.
reg query "HKLM\Software\JavaSoft\Java Runtime Environment" > nul 2> nul
if %errorlevel% == 0 goto success
echo "Not found"
goto end
:success
echo "Found"
:end
I am just printing Found/Not found - but you can take whatever action you want.

Related

CMD check if registry key exist

I have multiple registry keys called
O365BusinessRetail - en-us
O365BusinessRetail - de-de
... and so on for many languages
I want to check if the registry keys exist or not. But this command will not work "Registry key could not be found"
reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\O365BusinessRetail*"
IF %ERRORLEVEL% == 1 exit 1
If %ERRORLEVEL% == 0 exit 0
I also tried
reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall" /v ? | findstr /C "O365BusinessRetail*"
IF %ERRORLEVEL% == 1 exit 1
If %ERRORLEVEL% == 0 exit 0
However with Powershell it works but I can't use it because Powershell is blocked on our side
if (Test-Path -Path registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\O365BusinessRetail*) {
exit 1 # same as: Write-Output 1
}
else {
exit 0 # same as: Write-Output 0
}
What is the best way to do that in CMD?
Thanks
Your submitted code should look like this:
#SystemRoot%\System32\reg.exe Query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" /F "O365BusinessRetail*" /K 1>NUL 2>&1
#Exit %Errorlevel%
If one or more subkeys beginning with the string O365BusinessRetail exist, the script will exit with the 0 error code. If none exist, it will exit with a 1 error code.
Please also note that it is possible that the applications are registered under another uninstall key branch or root key.

Proper error return code?

I have a small problem with my batch file, here is my code:
Java -jar ****name.jar -commands****
So incase the user does have java installed it should give proper error code and if it has java installed and the java does not find the file its trying to run it should give proper error code and so on.
If "%Errorlevel%" NEQ "0" (
For /F "Tokens=*" %%C In ('Net Helpmsg %Errorlevel%') Do (
Echo Error Level: [Return Code #%Errorlevel% - %%C]
)
)
I was hoping it would get me correct error codes but it doesn't. Like for example if the user does not have java installed it would say something like this "java is not recognized.." and it should give an correct error code beneath it but unfortunately, it doesn't.
Here is what i have tried:
Removed the quotation around Errorlevel so its does not treat it like a string.
I was hoping anyone could point out my mistake?
The error numbers used by net helpmsg and ErrorLevel are totally different things; net helpmsg only understands error numbers returned by the net command.
What you are trying to accomplish is the following, I think (take a look at the explanatory remarks):
rem /* Test whether `java` is installed and can be found: */
rem // simply try to run the `java` executable:
java -version 2> nul
if ErrorLevel 1 echo ErrorLevel is set to %ErrorLevel% [9009 if not found, 0 otherwise].
rem // or use the `where` command to find the `java` executable:
where java > nul 2> nul
if ErrorLevel 1 echo ErrorLevel is set to %ErrorLevel% [1 if not found, 0 otherwise].
if ErrorLevel 1 goto :EOF
rem /* Thest whether the Java script `name.jar` exists: */
rem // simply try to run the Java script:
java name.jar -commands 2> nul
if ErrorLevel 1 echo ErrorLevel is set to %ErrorLevel% [1 if not found, or, if the script exists, its `ErrorLevel`].
rem // or use the `where` command to find the `java` executable:
where name.jar > nul 2> nul
if ErrorLevel 1 echo ErrorLevel is set to %ErrorLevel% [1 if not found, 0 otherwise].
rem /* (the `> nul` suffix suppresses output messages,
rem the `2> nul` suffix suppresses error messages) */
rem /* To capture the error message returned by any command, do this: */
for /F delims^=^ eol^= %%E in ('
command 2^>^&1 ^> nul
') do (
echo This is the error message: "%%E"
)
Since the question post has been updated and clarified, the following does not cover the problem. The true solution can be found above. I keep the former answer here for reference.
This is for the case you want to extract the error number returned by the net command, which is specific to this command and has got nothing to to with the ErrorLevel:
The error number of the net command and the ErrorLevel are totally different things.
Supposing you try to execute net view, it might fail with this error message, for instance:
System error 6118 has occurred.
The list of servers for this workgroup is not currently available
The resulting ErrorLevel is 2 though.
So executing net helpmsg %ErrorLevel% does not make any sense.
In contrast, net helpmsg 6118 does, which returns the following string:
The list of servers for this workgroup is not currently available
To capture the error number of the net command, use a for /F loop and take the line of the first iteration only by an if defined condition (using command net view in this example):
set "ERRNUM=" & set "ERRTXT="
for /F "delims=" %%M in ('2^>^&1 ^> nul net view') do (
rem Note that the `token` option is language-dependent:
for /F "tokens=3" %%N in ("%%M") do (
if not defined ERRNUM set "ERRNUM=%%N"
)
set "ERRTXT=%%M"
)
This would capture the error number 6118 of the above example and store it in variable ERRNUM. The last line of the error output (that I consider as the error message) is stored in variable ERRTXT.
To retrieve the error message later from a given error number stored in ERRNUM, you could use this:
set /A "ERRNUM+=0"
if %ERRNUM% NEQ 0 (
for /F "delims=" %%M in ('net helpmsg %ERRNUM%') do (
set "ERRTXT=%%M"
)
)
Side Note: Yes, I would remove the quotes if %ErrorLevel% NEQ 0 to do a numeric comparison.

How to search a text file in batch for a specific symbol and alter the script depending on the result

I need to create a command that allows me to insert a check of a text file for a very specific symbol (’) and I am having trouble. It is a single quotation mark and it occasionally is found on some folders that need to be zipped and when my batch zipper encounters the folder with the symbol in it's name, it just starts having a lot of problems and creates weird files. I am not going into a lot of detail, but I just need a way to (in plain terms) check if a text file contains the symbol (’) and if it does, send the script to an error line (just something to indicate the symbol was found, like "echo error found"). And if not, then just send it to the rest of the script...
Like FINDSTR "’" dirlist.txt
if found goto err else goto resume
I know that is very incorrect but you get the idea.
Here is what I have so far and I still have made no progress getting it to work:
findstr /i /c:"’" C:\ACFZ\FORZIP\dirlist.txt >2
if %errorlevel% EQU 0 (goto LABEL0) else (goto LABEL1)
:LABEL0
msg %username& "An invalid symbol has been found. Remove any single quotation marks (’) from the folder names and try again. If unsure, simply remove anything that looks like an apostrophe."
pause
goto ERROR
:LABEL1
echo No errors found, continuing
pause
goto ZIPSTART
:ERROR
echo an error was found, exiting...
pause
goto EXIT
It always ends up saying no errors, even though the file has the symbol in it.
Here is the text file I need to search (dirlist)
2082708 Amboy Bank
2082712 Cavender’s
2082736 Elizabeth Board of Education
2082763 Tri-Valley Developmental Services LLC
2082773 Vector Management
OK, so I finally got it working right... Thanks to Harvey, I used the method of outputting any results to a separate file, and then checking that file for contents. Which actually works great, because if it finds an issue, it will show you the full name of the problem folder(s) so you can easily fix it.
Here is the snippet of the working part:
findstr "'" C:\ACFZ\FORZIP\dirlist.txt > error.txt
findstr "." error.txt >nul
IF %ERRORLEVEL% EQU 0 GOTO POPUP
IF %ERRORLEVEL% EQU 1 GOTO ALLCLEAR
and here it is with a bit more detail:
CD C:\ACFZ\FORZIP
DIR /AD /B /ON >dirlist.txt
Echo Checking for errors in folder names...
ping -n 3 localhost >nul
REM that is not an apostrophe!
findstr "'" C:\ACFZ\FORZIP\dirlist.txt > error.txt
findstr "." error.txt >nul
IF %ERRORLEVEL% EQU 0 GOTO POPUP
IF %ERRORLEVEL% EQU 1 GOTO ALLCLEAR
REM Errorlevel 0= Something found, 1= nothing found
:POPUP
color cf
msg %username% "An invalid symbol has been found. Remove any single quotation marks (’) from the folder names and try again. If unsure, simply remove anything that looks like an apostrophe."
goto ERROR
:ALLCLEAR
echo No errors found, continuing...
ping -n 3 localhost >nul
ping -n 3 localhost >nul
goto ZIPSTART
:ERROR
echo An error was found in the following folder name(s) below:^
findstr "." error.txt
echo.
Echo Remove any symbols from the above folder name(s)
echo within your completed folder and try again.
Echo This program will now exit.
pause
goto EXIT
:ZIPSTART
REM Zip contents of each directory
for /f "tokens=*" %%a in (dirlist.txt) do (
CD "%%a"
wzzip "C:\ACFZ\ZIPPED\%%a.zip"
CD..
)
Glad I was able to fix this. I guess WinZip goes really crazy from that quotation mark. The reason I needed this was I wrote this batch script (there is more to it than what I have above, as this was the part I needed to work on) to automate the zipping and backup process at my work, so that the folders for the month's jobs are zipped up and then copied onto the server for archive. It was a pain to manually do it, so with this I can just do it all in one step.
Oh and yeah the errorlevel issue was I did not have it entered correctly. I did not space them over to the right.
Thanks to all who helped.
%error_level% indicates the status of the execution which always successful (0) unless you pass in wrong arguments (e.g. try run findstr without argument or with a wrong file name).
In your case, you need to examine the output (messages printed on the screen) of findstr. One approach is to rely on the fact that nothing is printed on the screen if findstr finds no string matched the search. For example:
set found=""
findstr "'" C:\ACFZ\FORZIP\dirlist.txt > findresult.txt
call:CheckEmptyFile findresult.txt found
if "%found%" EQU "FOUND" (
echo An invalid symbol has been found
) else (
echo No errors found, continuing
)
REM your execution goes here
REM Clean up
del findresult.txt
goto :eof
:CheckEmptyFile
if %~z1 == 0 (
set "%~2=NOTFOUND"
) else (
set "%~2=FOUND"
)
goto :eof
(Reference: Windows BAT : test if a specific file is empty)

Check if registry key + value exists and if so, log it

I want to check if a certain registry key exists and if so, check its value as well
if it equals 0 (for example), then write to log: not found
if it equals 1 (for example), then write to log: found
should I stick to reg query and if structure or is there an easier method?
How do I check if a key is present in the windows registry
This can be done using reg query key:
This command will set %errorlevel%.
errorlevel=0 means the key exists.
errorlevel=1 means the key does not exist.
Example batch file
#echo off
Set mykey="HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"^
^ "HKCU\Software\Microsoft\Windows\CurrentVersion\Run"^
^ "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"^
^ "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices"^
^ "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServices"^
^ "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options"^
^ "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"^
^ "HKEY_LOCAL_MACHINE\SOFTWARE\Hackoo"
Set LogFile=logkey.txt
If Exist %LogFile% Del %LogFile%
For %%K in (%mykey%) Do Call :Check_Key %%K %LogFile%
Start "" %LogFile%
Exit /b
:Check_Key
reg QUERY %1 >nul 2>&1
(
if %errorlevel% equ 0 ( echo %1 ===^> Found && reg QUERY %1
) else ( echo %1 ===^> Not found
)
) >>%2 2>&1
Further reading
reg - Read, Set or Delete registry keys and values, save and restore from a .REG file.
An A-Z Index of the Windows CMD command line is an excellent reference for all things Windows cmd line related.
Unfortunately, I haven't found a proper way to check if the value is actually correct. You can use a FOR loop and tokens= to locate the value and compare but what happens when the REG QUERY returns more tokens than you're expecting? Using FIND fails in both a simple REG QUERY | FIND and in the FOR loop because it always returns the wrong %ERRORLEVEL% beyond one level. Even with DelayedExpansion, it seems it will eventually fail.

Conditional execution (IF, ELSE) NOT WORKING

I want to write a batch script statement where:
FINDSTR has to check for a string AND IF found then just print out FAILED and end the program
IF NOT FOUND then go check/look for another string AND IF FOUND then print out SUCCEEDED and close the program, IF NOT FOUND then print out the error message again.
Any ideas?
Here is what I did:
ECHO Checking the log file for errors...
FINDSTR /C:"Open failed" some_Log.txt && (ECHO Deployment FAILED.
cscript //nologo success_mail.vbs
pause) || FINDSTR "RC (return code) = 0" && (ECHO Deployment was successful.
cscript //nologo fail_mail.vbs
pause)
I don't know why it is not working. Any help would be appreciated.
Here is what i my latest one looks like:
ECHO Checking the log file for errors...
FINDSTR /C:"Open failed" some_Log.txt some_Log.txt && (
ECHO Deployment FAILED.
cscript //nologo fail_mail.vbs
GOTO offshore ) || (
FINDSTR /C:"RC (return code) = 0" some_Log.txt && (
ECHO Deployment was successful.
cscript //nologo success_mail.vbs
GOTO offshore)
)
And, it is not working. Do you see any errors? Thanks in advance.
I see a couple of potential problems.
Your %workDir% or %filenm% could contain spaces or special characters. To be safe you should enclose them in quotes if you haven't already done so in the values.
You must be careful when using both && and || operators. If the command(s) after the && fail, then it can cause the script to fall into the || section, even though the original command before the && succeeded. I'm worried about your CSCRIPT command to send mail. Even if it succeeds today, perhaps it could fail in the future and your logic could be impacted.
I'm guessing that the 2nd search string is supposed to be a phrase and not 5 different searches. Remember that search strings are delimited by space unless the /C option is used.
Your 2nd FINDSTR is hanging because you have neglected to provide a file as input, so it is waiting for data on stdin.
I would structure your code like so
ECHO Checking the log file for errors...
set "file=%workDir%\%filenm%_DEV_Log.txt"
set "search1=Error: Open failed because: No such file or directory"
set "search2=RC (return code) = 0"
set "err="
FINDSTR /C:"%search1%" "%file%" && (set err=1) || (
FINDSTR /C:"%search2%" "%file%" || set err=1
)
if defined err (
ECHO Deployment FAILED.
cscript //nologo success_mail.vbs "%filenm%_ddl_DEV.sql" "%file%"
pause
) else (
ECHO Deployment was successful.
cscript //nologo fail_mail.vbs "%filenm%_ddl_DEV.sql" "%file%"
pause
)

Resources