My batch-file program always crashes at the same point. What always happens before it crashes is this:
ping -n 6 127.0.0.1 1>nul: 2>nul:
-n cant be processed syntactically at this point.
if ping -n 1 127.0.0.1|find "(0" >nul && goto Loop
And then the window closes.
Could maybe someone help me fix the problem?
This is the whole script:
#setlocal enableextensions enabledelayedexpansion
:Loop
set ipaddr=127.0.0.1
ping -n 6 %ipaddr% >nul: 2>nul:
if ping -n 1 %ipaddr%|find "(0%" >nul && goto Loop
echo Connection lost
start "" http://www.google.com
else if ping -n 1 %ipaddr%|find "(100%" >nul && goto Loop
echo Connection OK
taskkill /FI "WINDOWTITLE eq google*" goto Loop
endlocal
Here is an advanced Version with two blocks of code that are executed dependent of whether Connection is ok or lost.
#setlocal enableextensions enabledelayedexpansion
set ipaddr=127.0.0.1
:Loop
ping -n 6 %ipaddr% >nul: 2>nul:
ping -n 1 %ipaddr%|find "(0%" >nul && (
echo Connection OK
taskkill /FI "WINDOWTITLE eq google*"
) || (
echo Connection lost
tasklist /v /fi "Windowtitle eq google*" || start "" http://www.google.com
)
goto :Loop
This is the "conventional way" with %errorlevel% and if- else (same logic, the above is just a shorter way of doing it):
#setlocal enableextensions enabledelayedexpansion
set ipaddr=127.0.0.1
:Loop
ping -n 6 %ipaddr% >nul: 2>nul:
ping -n 1 %ipaddr%|find "(0%" >nul
if %errorlevel%==0 (
echo Connection OK
taskkill /FI "WINDOWTITLE eq google*"
) else (
echo Connection lost
tasklist /v /fi "Windowtitle eq google*" || start "" http://www.google.com
)
goto :Loop
I took set ipaddr... out of the Loop. No Need to do it again and again.
(just wondering, if Google would be reachable, if the Connection got lost...)
EDIT to reflect the last comment. A bit enhanced, so any action only happens, if the connection status changes. Delete the "log" function if you don't need it, or redirect them to a file, if you like.
#echo off
setlocal enabledelayedexpansion
set ipaddr=127.0.0.1
set "status=undefined"
:Loop
ping -n 2 %ipaddr% >nul: 2>nul:
ping -n 1 %ipaddr%|find "(0%" >nul && (
set oldstatus=!status!
set status=online
if !status! neq !oldstatus! (
echo %date% %time% Connection switched from !oldstatus! to !status!
taskkill /FI "WINDOWTITLE eq google*" >nul 2>&1
)
) || (
set oldstatus=!status!
set status=offline
if !status! neq !oldstatus! (
echo %date% %time% Connection switched from !oldstatus! to !status!
start "" http://www.google.com
)
)
goto :Loop
Related
I am using this batch to automatically restart some program, they are running very well, but sometimes the batch exit, which causes process_1 and process_2 also exit. It seems that everything is normal, but the batch itself crashes. Why ?
#echo off
cd %~dp0
set process_1=process_1.exe
set process_2=process_2.exe
set interval=10
:check_service
tasklist > task_tmp.txt
findstr %process1% task_tmp.txt> NUL
if ErrorLevel 1 (
timeout /t 1 /nobreak > NUL
goto start_1
)
findstr %process2% task_tmp.txt> NUL
if ErrorLevel 1 (
timeout /t 1 /nobreak > NUL
goto start_2
)
timeout /t %interval% /nobreak > NUL
goto check_service
:start_1
start /b "" %process_1%
echo %date% %time% %process_1% " down, up it" >> start_note.txt
goto check_service
:start_2
start /b "" %process_2%
echo %date% %time% %process_2% " down, up it" >> start_note.txt
goto check_service
You can maybe simplify like this:
#echo off
Set "MyProcess1=process_1.exe"
Set "MyProcess2=process_2.exe"
:check
%SystemRoot%\System32\tasklist.exe /NH | %SystemRoot%\System32\find.exe /i "%MyProcess1%">nul || echo starting %MyProcess1% && start "process 1" "%MyProcess1%"
%SystemRoot%\System32\tasklist.exe /NH | %SystemRoot%\System32\find.exe /i "%MyProcess2%">nul || echo starting %MyProcess2% && start "Process 2" "%MyProcess2%"
%SystemRoot%\System32\timeout.exe /t 10 /nobreak >nul
goto check
Full qualified file names are used for the commands tasklist, find and timeout to make this batch file independent on the values of the local environment variables PATH and PATHEXT and to avoid that the Windows command processor has to search for these three executables.
You can shorten your code like this:
#echo off
pushd "%~dp0"
:chkservice
tasklist | find /I "Process_1.exe" >nul 2>&1
if errorlevel 1 (
start Process_1.exe
echo %date% %time% Process_1.exe Down up, it >>startnote.txt
)
tasklist | find /I "Process_2.exe" >nul 2>&1
if errorlevel 1 (
start Process_2.exe
echo %date% %time% Process_2.exe Down up, it >>startnote.txt
)
timeout /t 10 /nobreak >nul 2>&1
goto chkservice
I have a batch file that create another batch file.
I need to add inside the echo a random function to have numbers from 1 to 6.
My batch code (works perfectly)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::: Batch Code :::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#echo off
(for /f "usebackq delims=" %%a in ("D:\Program files\Openvpn\openvpn_configuration_list_for_clicks.csv") do (
echo :::: Start Of The Command Block ::::
echo/
echo MOVE /Y "D:\Program files\Openvpn\config_to_check\%%~NXa" "D:\Program files\Openvpn\config\"
echo START "" "C:\Program Files\OpenVPN\bin\openvpn-gui.exe" --connect %%~NXa
echo PING -n 30 localhost ^>NUL 2^>^&1
echo PING -n 5 www.wikipedia.org^|FIND /I "TTL"^>NUL
echo IF NOT "%%ERRORLEVEL%%"=="1" ^(
echo rundll32 user32.dll,MessageBeep 0x00000010L
echo start "" "D:\Program files\Firefox Esr\FirefoxPortable.exe"
echo TIMEOUT /T 60 /NOBREAK ^>NUL
echo goto search_%%a
echo ^)
echo :search_%%a
echo tasklist /FI "IMAGENAME eq firefox.exe" 2^>NUL ^| find /I /N "firefox.exe"^>NUL
echo if "%%ERRORLEVEL%%"=="0" ^(
echo TIMEOUT /T 60 /NOBREAK ^>NUL
echo goto search_%%a
echo ^)
echo if "%%ERRORLEVEL%%"=="1" ^(goto continue_%%a^)
echo :continue_%%a
echo taskkill.exe /F /IM openvpn.exe
echo taskkill.exe /F /IM openvpn-gui.exe
echo MOVE /Y "D:\Program files\Openvpn\config\%%~NXa" "D:\Program files\Openvpn\config_to_check\"
echo/
echo :::: End Of The Command Block ::::
echo/
echo/
echo/
)) > "D:\Program files\Openvpn\final.bat"
(echo exit) >> "D:\Program files\Openvpn\final.bat"
openvpn_configuration_list_for_clicks.csv (list of vpn)
vpn1.ovpn
vpn2.ovpn
vpn4.ovpn
vpn8.ovpn
output final.bat without random function (works perfectly)
:::: Start Of The Command Block ::::
MOVE /Y "D:\Program Files\Openvpn\config_to_check\vpn1.ovpn" "D:\Program Files\Openvpn\config\"
START "" "C:\Program Files\OpenVPN\bin\openvpn-gui.exe" --connect vpn1.ovpn
PING -n 30 localhost >NUL 2>&1
PING -n 5 www.wikipedia.org|FIND /I "TTL">NUL
IF NOT "%ERRORLEVEL%"=="1" (
rundll32 user32.dll,MessageBeep 0x00000010L
start "" "D:\Program Files\Firefox Esr\FirefoxPortable.exe"
TIMEOUT /T 60 /NOBREAK >NUL
goto search_vpn1.ovpn
)
:search_vpn1.ovpn
tasklist /FI "IMAGENAME eq firefox.exe" 2>NUL | find /I /N "firefox.exe">NUL
if "%ERRORLEVEL%"=="0" (
TIMEOUT /T 60 /NOBREAK >NUL
goto search_vpn1.ovpn
)
if "%ERRORLEVEL%"=="1" (goto continue_vpn1.ovpn)
:continue_vpn1.ovpn
taskkill.exe /F /IM openvpn.exe
taskkill.exe /F /IM openvpn-gui.exe
MOVE /Y "D:\Program Files\Openvpn\config\vpn1.ovpn" "D:\Program Files\Openvpn\config_to_check\"
:::: End Of The Command Block ::::
I need a solution to have a random number from 1 to 6 in path inside echo
"D:\Program Files\Firefox Esr 2\FirefoxPortable.exe"
or
"D:\Program Files\Firefox Esr 5\FirefoxPortable.exe"
or
"D:\Program Files\Firefox Esr 6\FirefoxPortable.exe"
The code without a random function works very well and generates output correctly, I need to insert a random function inside the code that does not send the output generation into error.
The random function need to calculate for every loop to have a new random number for every loop
Let me step through my comment with some examples.
Your initial code was escaping opening parentheses unnecessarily and should have looked more like this:
Echo :::: Start Of The Command Block ::::
Echo/
Echo Ping -n 30 localhost ^>Nul 2^>^&1
Echo Ping -n 5 www.facebook.com^|Find /I "TTL"^>Nul
Echo If Not "%%ErrorLevel%%"=="1" (
Echo Rundll32 User32.dll,MessageBeep 0x00000010L
Echo Set /A num=(%%RANDOM%% %%%% 6^^^) + 1
Echo Start "" "D:\Program Files\Firefox Portable %%num%%\FirefoxPortable.exe"
Echo Timeout 60 /NoBreak ^>Nul
Echo ^)
Echo/
Echo :search
However, you are setting a variable and trying to use it within the same If block, this can be fixed in a number of ways:
Use a pseudo Call statement:
Echo :::: Start Of The Command Block ::::
Echo/
Echo Ping -n 30 localhost ^>Nul 2^>^&1
Echo Ping -n 5 www.facebook.com^|Find /I "TTL"^>Nul
Echo If Not "%%ErrorLevel%%"=="1" (
Echo Rundll32 User32.dll,MessageBeep 0x00000010L
Echo Set /A num=(%%RANDOM%% %%%% 6^^^) + 1
Echo Call Start "" "D:\Program Files\Firefox Portable %%%%num%%%%\FirefoxPortable.exe"
Echo Timeout 60 /NoBreak ^>Nul
Echo ^)
Echo/
Echo :search
Enable delayed expansion: (this example assumes that delayed expansion isn't already enabled in the script doing the Echoing)
Echo :::: Start Of The Command Block ::::
Echo/
Echo Ping -n 30 localhost ^>Nul 2^>^&1
Echo Ping -n 5 www.facebook.com^|Find /I "TTL"^>Nul
Echo If Not "%%ErrorLevel%%"=="1" (
Echo Rundll32 User32.dll,MessageBeep 0x00000010L
Echo Set /A num=(%%RANDOM%% %%%% 6^^^) + 1
Echo SetLocal EnableDelayedExpansion
Echo Start "" "D:\Program Files\Firefox Portable !num!\FirefoxPortable.exe"
Echo EndLocal
Echo Timeout 60 /NoBreak ^>Nul
Echo ^)
Echo/
Echo :search
Enable delayed expansion: (this example assumes that delayed expansion is already enabled in the script doing the Echoing)
Echo :::: Start Of The Command Block ::::
Echo/
Echo Ping -n 30 localhost ^>Nul 2^>^&1
Echo Ping -n 5 www.facebook.com^|Find /I "TTL"^>Nul
Echo If Not "%%ErrorLevel%%"=="1" (
Echo Rundll32 User32.dll,MessageBeep 0x00000010L
Echo Set /A num=(%%RANDOM%% %%%% 6^^^) + 1
Echo SetLocal EnableDelayedExpansion
Echo Start "" "D:\Program Files\Firefox Portable ^!num^!\FirefoxPortable.exe"
Echo EndLocal
Echo Timeout 60 /NoBreak ^>Nul
Echo ^)
Echo/
Echo :search
Restructure the code in order not to have an unnecessary If block (preferred):
Echo :::: Start Of The Command Block ::::
Echo/
Echo Ping -n 30 localhost ^>Nul 2^>^&1
Echo Ping -n 5 www.facebook.com^|Find /I "TTL"^>Nul
Echo If "%%ErrorLevel%%"=="1" GoTo search
Echo Rundll32 User32.dll,MessageBeep 0x00000010L
Echo Set /A num=(%%RANDOM%% %%%% 6^) + 1
Echo Start "" "D:\Program Files\Firefox Portable %%num%%\FirefoxPortable.exe"
Echo Timeout 60 /NoBreak ^>Nul
Echo/
Echo :search
All of the above examples assume that the code shown is inside a parenthesised block, similar to (code above)>"another.bat" or >"another.cmd" (code above)
[Edit /]
Here's some code to incorporate the additional stuff you've now posted. I have utilised methd 4. from above to remove the unnecessary If blocks. It should also incorporate the randomisation function you require, which is the same as previously posted and compatible with your batch file.
#Echo Off
(For /F "UseBackQ Delims=" %%A In (
"D:\Program Files\OpenVPN\openvpn_configuration_list_for_clicks.csv") Do (
Echo #Move /Y "D:\Program Files\OpenVPN\config_to_check\%%~nxA" "D:\Program Files\OpenVPN\config"
Echo #Start "" "C:\Program Files\OpenVPN\bin\OpenVPN-GUI.exe" --connect %%~nxA
Echo #Timeout 30 /NoBreak^>Nul 2^>^&1
Echo #Ping -n 5 www.wikipedia.org^|Find /I "TTL"^>Nul^|^|GoTo search_%%A
Echo #Rundll32 User32.dll,MessageBeep 0x00000010L
Echo #Set "num="
Echo #Set /A num=(%%RANDOM%% %%%% 6^) + 1
Echo #Start "" "D:\Program Files\Firefox ESR %%num%%\FirefoxPortable.exe"
Echo #Timeout 60 /NoBreak^>Nul
Echo/
Echo :search_%%A
Echo #TaskList^|Find /I "Firefox.exe"^>Nul^|^|GoTo continue_%%A
Echo #Timeout 60 /NoBreak^>Nul
Echo #GoTo search_%%A
Echo/
Echo :continue_%%A
Echo #TaskKill /F /IM OpenVPN.exe 2^>Nul
Echo #TaskKill /F /IM OpenVPN-GUI.exe 2^>Nul
Echo #Move /Y "D:\Program Files\OpenVPN\config\%%~nxA" "D:\Program Files\OpenVPN\config_to_check"
Echo/))>"final.bat"
Echo #Exit /B>>"D:\Program Files\OpenVPN\final.bat"
I'm trying to create a batch file where it would detect ping anomalies. I want it to ping to an IP infinitely (-t) until I close it where it would write down whenever ms > 100 ms and the time stamp as well. I'm thinking somewhere along the lines of sub string variables but I don't know how to wrap my head around it.
:Loop
time /t >> textfile.txt
ping -n 1 127.0.0.1 | findstr /c:"Minimum" >> textfile.txt
timeout /t 5
Goto Loop
Or perhaps this suits your needs
ping /t > textfile.txt
or
:loop
wmic /append:"textfile.txt" path win32_pingstatus where "address='127.0.0.1' and responsetime > 100" get responsetime,timestamprecord
goto loop
I've been looking for an answer to this same question for while. bgalea's answer gave me the pieces I needed to write my own. Here's what I came up with:
:: usage: badpings.bat [ip adress | hostname] [ping time threshhold]
#echo off
if "%1"=="" (
set pingdest=yahoo.com
) else (
set pingdest=%1
)
if "%2"=="" (
set /a limit=100
) else (
set /a limit=%2
)
echo Pinging %pingdest%.
echo Logging replies over %limit%ms.
echo Press Ctrl+C to end.
:Loop
for /f "usebackq tokens=1-6" %%a in (`ping -n 1 %pingdest% ^| findstr "Request Reply request"`) do (
set var=%%a %%b %%c %%d %%e %%f
set pingtimestr=%%e
)
if "%pingtimestr%"=="find" (
echo Ping request could not find host %pingdest%. Please check the name and try again.
goto End
)
if "%pingtimestr%"=="host" (
set /a pingtime=%limit%+1
)
if "%pingtimestr:~0,4%"=="time" (
set /a pingtime=%pingtimestr:~5,-2%
)
if %pingtime% GTR %limit% (
echo [%time%] %var%>>badpings.log
echo [%time%] %var%)
timeout /t 1 /nobreak >nul
Goto Loop
:End
It works on Windows 10. I haven't tested it on other OS versions.
I have a little problem with the next code
#Echo off
Title STARTING
cls
echo.
echo Checking running services...
echo.
timeout /t 2 /nobreak >NUL
tasklist /fi "imagename eq cmd.exe" /v | find /I /N "DATABASESERVER" >NUL
if "%ERRORLEVEL%"=="1" (
cls
echo.
echo Database is not running, now will start!
echo.
start database.bat
echo Database is running!
echo.
timeout /t 4 /nobreak >NUL
)
tasklist /fi "imagename eq cmd.exe" /v | find /i /n "ARMASERVER" >NUL
if "%errorlevel%"=="1" (
for /F "tokens=1-4 delims=:.," %%a in ("%time%") do (
set /A "ora=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
)
echo %ora%
pause
cls
echo.
echo Server is not running, now will start!
echo.
start arma.bat
title EPOCHSERVER
timeout /t 39 /nobreak >NUL
)
The problem is that "echo %ora%" it give me the result "Echo off" instead the value of time in seconds
What is the problem?
Thank you in advance!
You need to enable delayed expansion:
tasklist /fi "imagename eq cmd.exe" /v | find /i /n "ARMASERVER" >NUL
if "%errorlevel%"=="1" (
for /F "tokens=1-4 delims=:.," %%a in ("%time%") do (
set /A "ora=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
)
echo percent inside ^(^)=%ora%
setlocal enabledelayedexpansion
echo exclamation=!ora!
endlocal
)
echo percent outside ^(^)=%ora%
Output:
==>D:\bat\SO\30834591.bat
percent inside ()=
exclamation=214860
percent outside ()=214860
==>
%ora% is empty at that point, which means that the command being executed is just echo, which returns the state of echo.
Are you sure that the quotation marks on the set line should be there?
Someone with better batch skills will speak up; I don't want to risk misleading you with my half-educated guesses.
In the meantime, I recommend that you play with that line directly on the commandline until you get the results you expect. Remember to de-double the % characters outside of the batch script.
I am currently trying to ping a list of hostnames, preferably one at a time, and then use nslookup on that hostname. If the hostname in nslookup matches up with the hostname first used, then I would like to use the IP to check against another file (called home.txt) that would contain the location.
What I have so far:
#Echo Off
If '%1'=='' GOTO Syntax
Echo Running Script and Saving Results to Results.CSV
Echo Script Run %date% %time% >> Results.csv
For /F %%i in (%1) do Call :StartPing %%i
Goto :eof
:StartPing
PING %1 -n 1 | FIND /i "TTL" > nul && goto Success
PING %1 -n 1 | FIND /i "timed" > nul && goto Timedout
PING %1 -n 1 -w 400 | FIND /i "TTL" > nul || goto ErrorMsg
:Success
for /F "tokens=3" %%a in ('ping %1 ^| find /i "TTL"') do set Address=%%a
for /F "tokens=2" %%a in ('ping -a %Address::=% ^| find /i "pinging"') do set HostName=%%a
set IPAddress=%Address::=%
echo %1, %IPAddress%,%Hostname%
echo %1, %IPAddress%,%Hostname% >> Results.csv
NSLOOKUP %IPAddress% | FIND /i "Name" = "%Hostname%" goto home
:home
echo %IPAddress% home.txt
Goto :EOF
:Timedout
Echo %1, Request timed out.
Echo %1, Request timed out. >> Results.csv
:ErrorMsg
Echo %1, Ping request could not find host.
Echo %1, Ping request could not find host. >> Results.csv
goto :eof
:Syntax
echo . . .
goto :eof
An example of what home.txt might contain:
10.102.6.43 = 2J
IE, just a bunch of IP ranges mapped to office locations.
Ideally, the script should then make a popup box showing the location of the IP address, or just echo it on-screen.
Any ideas?
Made some changes and tested a few things, here is what i have so far.
#echo Off
#cls
if '%1'=='' GOTO Syntax
echo Running Script and Saving Results to Results.CSV
echo Script Run %date% %time% >> Results.csv
for /F %%i in (%1) do Call :StartPing %%i
goto :EOF
:StartPing
PING %1 -n 1| FIND /i "TTL" > nul && goto Success
PING %1 -n 1| FIND /i "timed" > nul && goto Timedout
PING %1 -n 1 -w 400 | FIND /i "TTL" > nul || goto ErrorMsg
:Success
for /F "tokens=3" %%a in ('ping %1 ^| find /i "TTL"') do set Address=%%a
for /F "tokens=2" %%a in ('ping -a %Address::=% ^| find /i "pinging"') do set HostName=%%a
set IPAddress=%Address::=%
for /f "tokens=2" %%b in ('nslookup %IPAddress%^|find /i "Name"') do set fqdn=%%b
echo %1, %IPAddress%,%Hostname%
echo %1, %IPAddress%,%Hostname% >> Results.csv
goto :EOF
:Timedout
Echo %1, Request timed out.
Echo %1, Request timed out. >> Results.csv
:ErrorMsg
Echo %1, Ping request could not find host.
Echo %1, Ping request could not find host. >> Results.csv
goto :EOF
:Syntax
echo . . .
goto :EOF
:EOF
echo this is the END OF FILE
pause
Every time I run hh.bat host.txt, everything runs fine until it hits the nslookup part, then it creates between 1500 and 3000 processes in windows task manager. without the NSLOOKUP part hh.bat works fine.
I had the nslookup part in a separate script called nslookup.bat which worked fine for a little while, and now it does not want to work. create that amount of processes everytime...
testing in a Hyper-V environment with 3 windows 7 pcs and a DC.