- using System;
- using System.Media;
- using System.Net;
- using System.Threading;
- namespace RobvanderWoude
- {
- class PingSite
- {
- static bool beep = false;
- static int Main( string[] args )
- {
- try
- {
- // Default values
- bool varSpeed = false;
- bool verbose = true;
- bool changes = false;
- int interval = 0;
- int fastInt = 0;
- int slowInt = 0;
- int previous = 0;
- string expected = string.Empty;
- string url = string.Empty;
- #region Command Line Parsing
- // Custom error message
- string msgInvalid = "Invalid command line argument" + ( ( args.Length == 1 ) ? string.Empty : "(s)" );
- // No command line arguments? Display help
- if ( args.Length == 0 )
- {
- return WriteError( string.Empty );
- }
- foreach ( string arg in args )
- {
- // Check switches first
- switch ( arg.ToLower( ).Substring( 0, 2 ) )
- {
- case "/?":
- case "-?":
- case "/h":
- case "-h":
- // Display help
- return WriteError( string.Empty );
- case "--":
- if ( arg.ToLower( ) == "--help" )
- {
- // Display help
- return WriteError( string.Empty );
- }
- else
- {
- // Display error message
- return WriteError( msgInvalid );
- }
- case "/b":
- beep = true;
- break;
- case "/c":
- verbose = false;
- changes = true;
- break;
- case "/i":
- if ( arg.ToLower( ).StartsWith( "/i:" ) || arg.ToLower( ).StartsWith( "/interval:" ) )
- {
- slowInt = System.Convert.ToInt32( arg.Substring( arg.IndexOf( ":" ) + 1 ) );
- if ( slowInt < 1 )
- {
- return WriteError( "Interval must be 1 or greater" );
- }
- }
- else
- {
- return WriteError( msgInvalid );
- }
- break;
- case "/q":
- verbose = false;
- changes = false;
- break;
- case "/s":
- {
- if ( arg.IndexOf( ":" ) > 0 )
- {
- expected = arg.Substring( arg.IndexOf( ":" ) + 1 ).ToUpper( );
- }
- else
- {
- expected = "OK";
- }
- if ( expected == "OK" )
- {
- expected = "200,301,302,303,304,305,306,307";
- }
- }
- break;
- case "/v":
- varSpeed = true;
- break;
- default:
- url = arg;
- break;
- }
- }
- if ( string.IsNullOrEmpty( url ) )
- {
- return WriteError( "An URL must be specified" );
- }
- if ( slowInt < 1 && changes )
- {
- return WriteError( "To display status changes only, an interval must be specified" );
- }
- if ( slowInt > 0 && !( verbose || changes ) )
- {
- return WriteError( "/Quiet switch not allowed if an interval is specified" );
- }
- if ( varSpeed && ( string.IsNullOrEmpty( expected ) || slowInt < 1 ) )
- {
- return WriteError( "/Variable requires both /Status and /Interval" );
- }
- interval = slowInt;
- if ( slowInt >= 25 )
- {
- fastInt = slowInt / 5;
- }
- else if ( slowInt < 5 )
- {
- fastInt = slowInt;
- }
- else
- {
- fastInt = 5;
- }
- #endregion Command Line Parsing
- // Loop will be aborted if interval is less than 1
- while ( true )
- {
- HttpStatusCode status = GetResponse( url );
- string statusText = status.ToString( );
- int statusCode = (int) status;
- // Display result
- if ( ( ( previous != statusCode ) && changes ) || verbose )
- {
- ConsoleColor statusColor;
- if ( string.IsNullOrEmpty( expected ) || expected.Contains( statusCode.ToString( ) ) )
- {
- statusColor = ConsoleColor.White;
- interval = slowInt;
- }
- else
- {
- statusColor = ConsoleColor.Red;
- if ( varSpeed )
- {
- interval = fastInt;
- }
- }
- Console.Write( "[{0}]\\t", DateTime.Now );
- Console.ForegroundColor = statusColor;
- Console.Write( "{0}\\t{1}", statusCode, statusText );
- Console.ResetColor( );
- Console.WriteLine( "\\t{0}", url );
- Console.Title = "PingSite: " + statusCode.ToString( );
- // Beep on changes, if requested
- if ( beep )
- {
- bool beepNow = false;
- if ( changes )
- {
- beepNow = true;
- }
- if ( string.IsNullOrEmpty( expected ) == false )
- {
- if ( expected.Contains( statusCode.ToString( ) ) == false )
- {
- beepNow = true;
- }
- }
- if ( beepNow )
- {
- Console.Beep( );
- }
- }
- }
- // Save the last status code to compare it in the next iteration of the loop
- previous = statusCode;
- // Break the loop if interval is less than 1
- if ( interval < 1 )
- {
- if ( string.IsNullOrEmpty( expected ) )
- {
- // Return the actual status code
- return statusCode;
- }
- else
- {
- // If we were monitoring for an expected code, return either 0 (match) or 2 (no match)
- return ( ( expected.Contains( statusCode.ToString( ) ) ) ? 0 : 2 );
- }
- }
- // Wait for the specified number of seconds
- Thread.Sleep( interval * 1000 );
- }
- }
- catch ( Exception e )
- {
- return WriteError( e.Message );
- }
- }
- public static HttpStatusCode GetResponse( string url )
- {
- // Returns the HTTP Status Code for the specified URL, or 0 on errors
- try
- {
- HttpwebRequest req = (HttpWebRequest) WebRequest.Create( url );
- req.AllowAutoRedirect = false;
- HttpWebResponse resp = (HttpWebResponse) req.GetResponse( );
- HttpStatusCode stat = resp.StatusCode;
- req.Abort( );
- return stat;
- }
- catch ( WebException e )
- {
- // Handle exceptions caused by the server response, e.g. 404
- try
- {
- HttpWebResponse httpResponse = (HttpWebResponse) e.Response;
- return httpResponse.StatusCode;
- }
- // Handle the "real" exceptions
- catch
- {
- WriteError( e.Message, false );
- return 0;
- }
- }
- catch ( Exception e )
- {
- WriteError( e.Message );
- return 0;
- }
- }
- #region Error Handling
- public static int WriteError( Exception e )
- {
- return WriteError( e == null ? null : e.Message );
- }
- public static int WriteError( string errorMessage, bool showHelp = true )
- {
- /*
- PingSite, Version 1.21
- Check if a website is up and running
- Usage: PINGSITE url [ /Status[:expected] ] [ /Interval:seconds ]
- [ /Variable ] [ /Beep ] [ /Changes | /Quiet ]
- Where: url is the URL of the site or page to check (including http://)
- /Beep beep on changes or if response does not match expected
- /Changes display status changes only (requires /Interval)
- /Interval defines the optional interval in seconds between checks
- (default if not specified: terminate after 1 check)
- /Quiet no screen output, 'errorlevel' only
- /Status is either the expected numeric HTTP response code, or
- 'OK' for 200, 301..307 (default)
- /Variable shorter interval on mismatch (requires /Interval & /Status)
- Notes: If /Status was used, 'errorlevel' 0 is returned if status matches
- expected, 2 if not; otherwise the actual status code is returned as
- 'errorlevel'; in case of (command line) errors 1 is returned.
- Switches /Interval and /Quiet are mutually exclusive.
- Switches may be abbreviated, e.g. /I instead of /Interval.
- */
- if ( string.IsNullOrEmpty( errorMessage ) == false )
- {
- Console.Error.WriteLine( );
- Console.ForegroundColor = ConsoleColor.Red;
- Console.Error.Write( "ERROR: " );
- Console.ForegroundColor = ConsoleColor.White;
- Console.Error.WriteLine( errorMessage );
- Console.ResetColor( );
- if ( beep )
- {
- Console.Beep( );
- }
- }
- return 1;
- }
- }
- }
- //该片段来自于http://www.codesnippet.cn/detail/150820135167.html
来源: http://www.codesnippet.cn/detail/150820135167.html