IF/Else and Goto issues - windows

I've been struggling with trying to put together this batch script to check a process (it can be any process). count the number of instances of it are running and save the output of that count. If its not running (a count of 0) then its fine but if it is running (1 or greater) but is under say '5' in this case have it echo a statement.
every time i try to do this i either get 'else' is not recognized as an internal or external command, operable program or batch file or when the script gets to the goto :problem it seems to completely ignore the else statement.
#echo off
for /f %%g in (' tasklist /FI "IMAGENAME eq chrome.exe" ^| find /I /C "chrome.exe" ') do (
if %%g EQU 0 goto :notrunning
if %%g GTR 0 goto :problem
)
:notrunning
echo Program is not running
pause
:problem
If %%g LSS 5 ( echo problem
) else ( echo chrome is fine
)
pause

Any goto breaks the for context. Try this:
#echo off
for /f %%g in (' tasklist /FI "IMAGENAME eq chrome.exe" ^| find /I /C "chrome.exe" ') do set status=%%g
if %status% EQU 0 goto :notrunning
if %status% GTR 0 goto :problem
:notrunning
echo Program is not running
pause
:problem
If %status% LSS 5 ( echo problem
) else ( echo chrome is fine
)
pause

Try to avoid the else statement in the if command. It may not be supported in the version of windows you are using. Try to get rid of the else statement and have multiple if statements. Here, try this:
#echo off
for /f %%g in (' tasklist /FI "IMAGENAME eq chrome.exe" ^| find /I /C "chrome.exe" ') do (
if %%g EQU 0 goto :notrunning
if %%g GTR 0 goto :problem
)
:notrunning
echo Program is not running
pause
:problem
If %%g LSS 5 echo problem
If %%g GTR 4 echo chrome is fine
)
pause

%%g is out-of-scope when you reach the label :problem
you need
if %%g GTR 0 set /a somevar=%%g&goto :problem
...
:problem
If %somevar% LSS 5 ( echo problem
) else ( echo chrome is fine
)

Related

Variable not recognized in else statement in a bat file

I have the follow code:
ECHO OFF
:LOOP
set c=
setlocal ENABLEDELAYEDEXPANSION
tasklist | find /i "calc.exe" >nul 2>&1
IF %ERRORLEVEL% == 0 (
ECHO easymeetingOnCall is running
taskkill /IM calc.exe /F
set c=true
Timeout /T 10
goto LOOP
) ELSE (
IF "!c!" == "true" (
ECHO l'applicazione easymeetingOnCall è spenta.
Timeout /T 10
goto exitLoop
)
ECHO easymeetingOnCall is not running
Timeout /T 5 /Nobreak
GOTO LOOP
)
:exitLoop
My problem is that the follow condition
IF "!c!" == "true"
Into the else statement, is not recognized.
If I write echo !c! It doesn't output any result.
I set enabledelayedexpansion before, so I don't know why of this behavior.
Could you help me?
Thanks to all.
Look carefully at the following extraction from your code.
ECHO OFF
:LOOP
set c=
....
set c=true
goto :LOOP
You are explicitly telling the if statement to goto :loop where directly after you set c= which now gives it no value. Move the set c= to above to label to retain the value you've set.
I however suggest a few changes. you can get away without delayedexpansion and do actually require all the for loops. Using taskkill to explicitly search for the app is better than listing all, also already mentioned to you in a comment by #Mofi. Lastly, it is not really good practice to set single character variables, though it does not always cause issues, I would suggest using multple character variable names. I just changed your variable %c% to %_c%
#echo off & set _c=
:loop
tasklist /FI "IMAGENAME eq Calc.exe" | find /i "Calc"
goto :_%errorlevel%
:_0
ECHO easymeetingOnCall is running
taskkill /IM calc.exe /F
set _c=true
Timeout /T 10
goto loop
:_1
IF "%_c%" == "true" (
ECHO l'applicazione easymeetingOnCall è spenta.
Timeout /T 10
goto exitloop
)
ECHO easymeetingOnCall is not running
Timeout /T 5 /Nobreak
goto loop
:exitloop
Edit, as you wanted to do this with a list:
#echo off & set _c=
set "list=calc.exe StickyNot.exe wordpad.exe"
for %%a in (%list%) do call :loop %%a
goto :eof
:loop
set task=%1
tasklist /FI "IMAGENAME eq %1" | find /i "%1"
if not errorlevel 1 (
ECHO easymeetingOnCall is running %1
taskkill /IM %1 /F
set _c=true
Timeout /T 10
)
if "%_c%" == "true" (
ECHO l'applicazione easymeetingOnCall è spenta. %1
Timeout /T 10
goto exitloop
)
echo easymeetingOnCall is not running %1
Timeout /T 5 /Nobreak
goto :loop
:exitloop
Be aware, if the first process is not running, it will loop forever until it is found, then only kill it and go to the next process. If you do not want that, then change goto :loop in the last line to exit loop.

Batch file to determine websites in IE

Is there a piece of code which can be used in a batch file to determine if firstly IE is open, and if so which websites are open in the tab(s)?
I am needing to force close IE when a user locks their PC, and if a specific website is open.
Thanks in advance.
Give a try for this batch file :
#echo off
Title Checking Running Process and Get their command lines
setlocal enabledelayedexpansion
Mode 90,25 & color 0A
Set "ProcessName=iexplore.exe"
Set "String2Search=facebook"
Call :CheckRunning !ProcessName!
If /I "%flag%"=="True" (
color 0A
echo %flag%
Call :GetCommandLine !ProcessName!
echo(
Call :CheckString_in_URL "%String2Search%"
) else (
color 0C
echo %flag%
echo !ProcessName! is not running !
pause>nul & exit
)
Exit
::********************************************************************************************************
:CheckRunning <ProcessName>
Set "ProcessName=%1"
tasklist /NH /FI "imagename eq %ProcessName%" 2>nul |find /i "%ProcessName%" >nul
If not errorlevel 1 ( Set "flag=True" ) else ( Set "flag=False" )
Exit /b
::********************************************************************************************************
:GetCommandLine <ProcessName>
Set "ProcessCmd="
for /f "tokens=2 delims==" %%P in ('wmic process where caption^="%~1" get commandline /format:value ^| findstr /I "%~1" ^| find /I /V "%~nx0" 2^>nul') do (
Set "ProcessCmd=%%P"
echo !ProcessCmd!
)
Exit /b
::******************************************************************************************************
:Kill <ProcessName>
Taskkill /IM "%~1" /F>nul 2>&1
Exit /b
::******************************************************************************************************
:CheckString_in_URL <String2Search>
set "String2Search=%~1"
(
echo Set objFso = CreateObject^("Scripting.FileSystemObject"^)
echo Set colShWindows = CreateObject^("shell.application"^).Windows
echo For Each w In colShWindows
echo If objFso.GetFileName^(LCase^(w.FullName^)^) = "iexplore.exe" Then
echo WScript.Echo w.LocationURL
echo End If
echo Next
)>"%Temp%\iexplore_tabs.vbs"
setlocal EnableDelayedExpansion
for /f %%a in ('cscript //nologo "%Temp%\iexplore_tabs.vbs"') do (
set /a index+=1
set "URL[!index!]=%%a"
)
for /L %%i in (1,1,%index%) do (
echo !URL[%%i]! | find /I "%String2Search%">nul && (
echo Found this string "%String2Search%" in the URL "!URL[%%i]!"
echo(
echo Did you want to kill this process "!ProcessName!" Y/N ?
Set /p "Answer="
If /I "!Answer!"=="Y" ( Call :Kill "!ProcessName!" ) else ( exit )
) || (
echo No string like "%String2Search%" found in "!URL[%%i]!"
Timeout /T 5 /nobreak>nul
)
)
exit /b
::******************************************************************************************************
I'm grateful to aGerman that give me the idea of how to enumerate the URLs of the InternetExplorer tabs

Running a cmd .bat file with loops and conditions

Hi I am trying to run a scrapy spider using start command from a cmd batch file. I want to run the spider parallely for 10 names from a csv file which contains more than 500 names. So my thought is to basically add some conditions in the loop from 1 to 500 that checks if the 10 command windows have closed, if not then wait for them to close (they auto close after spider is finished). Once the 10 windows which had opened, are closed, open the next 10 and so on. Following is the code I have, i am pretty sure it has big syntax errors. Could you help me debug? Thanks
cd /d "C:\Users\xyz"
for /f "tokens=1,*" %%m in ('tasklist ^| find /I /C "conhost.exe"') do (set var1=%%m)
set counter=1
for /f "usebackq tokens=1 delims=," %%n in ("test.csv") do (
(START /MIN "" scrapy crawl xyz_scraper -a query="%%n" -a pages=20)
set /a counter=counter+1
for /f "tokens=1,*" %%p in ('tasklist ^| find /I /C "conhost.exe"') do (set var2=%%p)
SET /A _result=counter%%10
echo %_result%
IF _result EQU 0 (
:abcd
timeout /t 10
if var2 EQU var1 (
goto bcde
)
ELSE (
goto abcd)
)
:bcde
)
pause
EDIT: deleted the for loop one. Edited the above code based on some suggestions. I don't understand where would i use quotes for variables and where not and how to print a variables value to cmd.
The updated code below:
cd /d "C:\Users\sodhian\sodhi-scraper"
for /f "tokens=1,*" %%m in ('tasklist ^| find /I /C "conhost.exe"') do (set var1=%%m)
echo %var1%
set counter=1
for /f "usebackq tokens=1 delims=," %%n in ("test comp.csv") do (
(START /MIN "" scrapy crawl ind_scraper -a query="%%n" -a pages=20)
set /a "counter=counter+1"
echo %counter%
SET /A _result="counter%%2"
echo %_result%
IF "%_result%" EQU "0" (
:abcd
timeout /t 10
for /f "tokens=1,*" %%p in ('tasklist ^| find /I /C "conhost.exe"') do (set var2=%%p)
echo %var2%
if var2==var1 (
goto bcde
)
ELSE (
goto abcd)
)
:bcde
)
pause
Edit 2:
Based on Stephan's answer. Tried to accomplish what i mentioned in comment of the answer:
setlocal enabledelayedexpansion
set counter=0
for /f "usebackq tokens=1 delims=," %%n in ("test comp.csv") do (
set /a counter+=1
start /MIN "MySpider!counter!" scrapy crawl ind_scraper -a query="%%n" -a pages=20
for /f "tokens=1,*" %%b in ('tasklist /v ^| find /I /C "MySpider"') do (set var1=%%b)
if !var1! geq 5 call :wait
)
:wait
timeout /t 5
for /f "tokens=1,*" %%p in ('tasklist /v ^| find /I /C "MySpider"') do (set var2=%%p)
if !var2! geq 5 call :wait
goto :eof
Changed it to the following: (the /v (verbose option in tasklist was making the above slow)
setlocal enabledelayedexpansion
set counter=0
set max_scrappers=7
for /f "tokens=1,*" %%a in ('tasklist ^| find /C "conhost"') do (set var1=%%a)
for /f "usebackq tokens=1 delims=," %%n in ("test comp.csv") do (
set /a counter+=1
start /min "MySpider!counter!" scrapy crawl ind_scraper -a query="%%n" -a pages=20
for /f "tokens=1,*" %%b in ('tasklist ^| find /C "conhost"') do (set var2=%%b)
set /a var3=!var2!-!var1!
if !var3! geq !max_scrappers! call :wait
)
:wait
for /f "tokens=1,*" %%p in ('tasklist ^| find /C "conhost"') do (set var4=%%p)
set /a var5=!var4!-!var1!
if !var5! geq !max_scrappers! call :wait
goto :eof
As already noted in the comments, labels inside a code block don't work. But you can call a "function", where goto and labels are no problem:
I choosed other numbers and another command to make it work on every system (and faster). Replacing the timeout command with your spider and adapting the numbers should be no problem.
#echo off
setlocal enabledelayedexpansion
REM next line just for generating a testfile:
>"test comp.csv" (for /l %%i in (1,1,10) do echo !random:~-1!)
set counter=0
for /f "usebackq tokens=1 delims=," %%n in ("test comp.csv") do (
set /a counter+=1
start "MySpider!counter!" timeout %%n
if !counter! geq 3 call :wait
)
:wait
tasklist /v|find "MySpider">nul && goto :wait
set counter=0
goto :eof
Searching for conhost is not a good idea, because there could be other processes. Choose an unique window title instead (MySpider in my example) and look for that title (tasklist /v)

Batch file runs fine in command prompt but gives error when double-clicked

I have a batch file that accepts store numbers and sets them to an array and then iterates through the array. When I double click my batch file it gives the error:
256 was unexpected at this time.
But when I run it from the console/command prompt it runs fine.
Here is my code.
#echo off
setlocal enabledelayedexpansion
set index=0
:getstore
set /a index=index + 1
set /P store[%index%]=Enter SLC store number:
:ask
set /P answer=Do you want to enter another store number (Y/N):
if /i "%answer%" == "n" (
set length=%index%
goto next
)
if /i "%answer%" == "y" (
goto getstore
) else goto ask
:next
for /L %%i in (1,1,%length%) do (
if %store% LSS 256 (
for /L %%k in (1,1,5) do ping 192.168.!store[%%i]!.%%k -n 1 |find "TTL"
)
if %store% GTR 255 (
set /a store=%store% - 255
for /L %%k in (1,1,5) do ping 10.0.!store[%%i]!.%%k -n 1 |find "TTL"
)
)
When you double click a batch file, a new cmd instance will be executed, one instance where store has not been initialized, so the line
if %store% LSS 256 (
fails as %store% is empty.
Thanks MC ND!
Your comment got me thinking.
When I was calling store in the if statement I needed to use the !! and also the index.
This is my edited (now working) code:
:next
for /L %%i in (1,1,%length%) do (
for /f "tokens=* delims=0" %%j in ("%store[%%i]%") do set store[%%i]=%%j
if !store[%%i]! LSS 256 (
for /L %%k in (1,1,5) do ping 192.168.!store[%%i]!.%%k -n 1 |find "TTL"
)
if !store[%%i]! GTR 255 (
set /a store=%store% - 255
for /L %%k in (1,1,5) do ping 10.0.!store[%%i]!.%%k -n 1 |find "TTL"
)
)

Do a command on a file while condition is True

for %%a in (.\*.jpg) do #if %%~za gtr 245760 (
:WhileD
resize /overwrite /width:imagewidth-100 %%a %%~na.jpg
if %%~za gtr 245760 goto WhileD
)
The Code above should check all images in a folder and if it is greater than 240KB, it resizes it till its size becomes less than 240KB, and then process to the next file,
But it is not working :(
goto commands break for loops. Use routines to contain goto sub-loops.
for %%a in (.\*.jpg) do #if %%~za gtr 245760 ( call :WhileD "%%~a" ) else echo add move command here.
exit /b 0
:WhileD <File>
resize /overwrite /width:imagewidth-100 %1 %~n1.jpg
if %~z1 gtr 245760 goto WhileD
exit /b 0
Update
Added else condition.
:WhileD
for %%a in (.\*.jpg) do if %%~za gtr 245760 (
resize /overwrite /width:imagewidth-100 %%a %%~na.jpg
goto WhileD
)
This should solve the problem.
Try this
FOR %%A IN (*.jpg) DO CALL :CHECKFILE %%A %%~nA
EXIT /B 0
:CHECKFILE
FOR /F "usebackq" %%A IN ('%1') DO SET FSIZE=%%~zA
IF %FSIZE% LEQ 245760 EXIT /B 0
resize /overwrite /width:imagewidth-100 %1 %2.jpg
GOTO CHECKFILE

Resources