views:

196

answers:

3

I want to continuously ping a server and see a message box when ever it responds i.e. server is currently down. I want to do it through batch file.

I can show a message box as said here http://stackoverflow.com/questions/774175/how-can-i-open-a-message-box-in-a-windows-batch-file/774253#774253

and can ping continuously by

ping <servername> -t

But how do I check if it responded or not?

+1  A: 

The following checklink.cmd program is a good place to start. It relies on the fact that you can do a single-shot ping and that, if successful, the output will contain the line:

Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),

By extracting tokens 5 and 7 and checking they're respectively "Received" and "1,", you can detect the success.

@setlocal enableextensions enabledelayedexpansion
@echo off
set ipaddr=%1
:loop
set state=down
for /f "tokens=5,7" %%a in ('ping -n 1 !ipaddr!') do (
    if "x%%a"=="xReceived" if "x%%b"=="x1," set state=up
)
echo.Link is !state!
ping -n 6 127.0.0.1 >nul: 2>nul:
goto :loop
endlocal

Call it with the name (or IP address) you want to test:

checklink 127.0.0.1
checklink localhost
checklink nosuchaddress

To only notify you when the state changes, you can use:

@setlocal enableextensions enabledelayedexpansion
@echo off
set ipaddr=%1
set oldstate=neither
:loop
set state=down
for /f "tokens=5,7" %%a in ('ping -n 1 !ipaddr!') do (
    if "x%%a"=="xReceived" if "x%%b"=="x1," set state=up
)
if not !state!==!oldstate! (
    echo.Link is !state!
    set oldstate=!state!
)
ping -n 2 127.0.0.1 >nul: 2>nul:
goto :loop
endlocal

However, as Gabe points out in a comment, you can just use ERRORLEVEL so the equivalent of that second script above becomes:

@setlocal enableextensions enabledelayedexpansion
@echo off
set ipaddr=%1
set oldstate=neither
:loop
set state=up
ping -n 1 !ipaddr! >nul: 2>nul:
if not !errorlevel!==0 set state=down
if not !state!==!oldstate! (
    echo.Link is !state!
    set oldstate=!state!
)
ping -n 2 127.0.0.1 >nul: 2>nul:
goto :loop
endlocal
paxdiablo
Thank you v much @paxdiablo! Can you please help me modify this so that I can only see a message box poping when the server gets up?The command for showing message box is `msg "%username%" Link is up` and this command works for me on Windows 7.
Ismail
That's a lot of work you do instead of just checking `%ERRORLEVEL%`!
Gabe
That's a good point, @Gabe, I've incorporated that into the script.
paxdiablo
For some reason I don't know, the solution with @Gabe's suggession is showing message every time. @paxdiablo's 2nd solution works after one initial status message.
Ismail
Sorry, Ismael, that was my fault (_not_ Gabe's) putting in debugging code (`set oldstate=x!state!`). It should work without the `x` in there.
paxdiablo
Note that the pseudo-variable `%errorlevel%` isn't reliable as you can easily set its value from the outside (overshadowing its usual meaning). You probably want to use `if errorlevel 1` instead of `if !errorlevel!==0`. And I shouldn't need to point this out, but parsing language-dependent strings is always an icky option for automation :-)
Joey
A: 

You can ping without "-t" and check the exit code of the ping. It reports failure when there is no answer.

Rotsor
We programmers can read and understand code faster than English language ;). Just joking.
Ismail
+1  A: 

The question was to see if ping responded which this script does.

However this will not work if you get the Host Unreachable message as this returns ERRORLEVEL 0 and passes the check for Received = 1 used in this script, returning Link is UP from the script. Host Unreachable occurs when ping was delivered to target notwork but remote host cannot be found.

If I recall the correct way to check if ping was successful is to look for the string 'TTL' using Find.

@echo off
cls
set ip=%1
ping -n 1 %ip% | find "TTL"
if not errorlevel 1 set error=win
if errorlevel 1 set error=fail
cls
echo Result: %error%

This wont work with IPv6 networks because ping will not list TTL when receiving reply from IPv6 address.

Lukasz
Thanks very much :)
Ismail