Reputation: 327
I was wondering if I can capture error messages directly (just like an output from a successfully executed command would be) and do whatever I want with it, such as storing it in a variable, or passing it as a parameter.
Here's what I'm trying to do lately. Please check the code:
FOR /F "tokens=2 delims== " %%s IN (
'WMIC DISKDRIVE WHERE SerialNumber^="sn999" GET SerialNumber /VALUE'
) DO (
IF "%%s"=="sn999" (GOTO Label1) ELSE (GOTO Label2)
)
What I'm trying to do here is to check if a particular external hard drive is plugged-in by comparing the serial number, and from then, the code will determine which path to take. It works as intended if the desired external hard drive is plugged-in. However, if the external hard drive with the same serial number is not plugged-in, I get the following message:
No Instance(s) Available.
And as a consequence I get these issues:
My research led me to these sources:
Redirecting Error Messages from Command Prompt: STDERR/STDOUT
Both links discuss redirecting error messages. I thought I can just write few lines of code to redirect error messages to a text file, recover it and parse the contents, and finally clean it up. But I'm not sure if this is the best idea though. So, I'd appreciate any suggestion that you may have that may work with the code above. Also, I'd like to know why %ERRORLEVEL% is 0 even though I got an error message. Lastly, I'd like to know if it is possible to capture error messages without writing anything to the hard drive.
Thank you all very much!!
Upvotes: 1
Views: 147
Reputation: 38623
I see no reason to use a For
loop in this instance because a metavariable is not required.
The For
loop runs the WMIC
command in another instance of cmd.exe
unnecessarily.
@Echo Off
WMIC DiskDrive Where SerialNumber="sn999" List Instance 2>Nul|Find "I">Nul && GoTo :Label1
Echo Drive Not Found & Pause
GoTo :EOF
:Label1
Echo Drive Found & Pause
GoTo :EOF
Upvotes: 0
Reputation: 5372
Put GOTO Label2
after the loop. If GOTO Label1
is triggered, then the GOTO Label2
will be avoided as it will jump to the label.
FOR /F "tokens=2 delims== " %%s IN (
'WMIC DISKDRIVE WHERE SerialNumber^="sn999" GET SerialNumber /VALUE'
) DO (
IF "%%~s"=="sn999" GOTO Label1
)
GOTO Label2
You could also suppress the stderr message of No Instance(s) Available.
with 2^>nul
if you prefer.
Upvotes: 1
Reputation:
Using findstr
makes you able to use errorlevel
.
@echo off
for /F %%i in ('WMIC DISKDRIVE ^| findstr /I /C:"sn999"') do if %errorlevel%==0 echo Drive Found & goto :EOF
echo Drive not Found.
This basically does a search on the string and if found sets errorlevel
to 0
, if not found errorlevel
will be 1
.
If errorlevel
is 0
then it will echo
Drive Found and goto :EOF
if errorlevel
is not 1, it skips the line as the condition was not met and it will echo
Drive not Found.
If you still want to use the labels, then simply do:
@echo off
for /F %%i in ('WMIC DISKDRIVE ^| findstr /I /C:"sn999"') do if %errorlevel%==0 goto :label1
REM This will act as label2
echo Drive not found
goto :EOF
:label1
echo Drive found
goto :EOF
Note we do not have to use goto label2
as it will automatically go passed the errorlevel match and continue, only label1 is really needed then.
Upvotes: 0