(view source code of countdown.cs as plain text)
using System;
using System.Collections.Generic;
using System.Threading;
using System.Text.RegularExpressions;
namespace RobvanderWoude{ class CountDown {static readonly string progver = "2.01";
static int Main( string[] args )
{string prefix = string.Empty;
string suffix = string.Empty;
bool returnremaining = false;
int seconds = 0;
#region Parse Command Lineif ( args.Length == 0 )
{return ShowHelp( );
}foreach ( string arg in args )
{if ( arg == "/?" )
{return ShowHelp( );
}else if ( arg.ToUpper( ) == "/R" )
{if ( returnremaining )
{return ShowHelp( "Duplicate command line switch /R" );
}returnremaining = true;
}else if ( int.TryParse( arg, out int test ) )
{if ( seconds == 0 )
{seconds = test;
} else {return ShowHelp( "Duplicate timeout argument" );
} }else if ( string.IsNullOrWhiteSpace( prefix ) )
{prefix = arg;
}else if ( string.IsNullOrWhiteSpace( suffix ) )
{suffix = arg;
} else {return ShowHelp( "Invalid or too many command line arguments", arg );
} } // Enable single command line argument for prefix seconds suffixif ( seconds == 0 && !string.IsNullOrWhiteSpace( prefix ) && string.IsNullOrWhiteSpace( suffix ) )
{string pattern = @"^([^\d]*)(\d+)(.*)$";
Regex regex = new Regex( pattern );
if ( regex.IsMatch( prefix ) )
{MatchCollection matches = regex.Matches( prefix );
if ( matches.Count == 1 )
{if ( matches[0].Groups.Count == 4 )
{if ( int.TryParse( matches[0].Groups[2].ToString( ), out seconds ) )
{prefix = matches[0].Groups[1].ToString( );
suffix = matches[0].Groups[3].ToString( );
} } } } }if ( seconds < 1 || seconds > 86400 )
{return ShowHelp( "Specified timeout ({0}) outside allowed range", seconds.ToString( ) );
} #endregion Parse Command Line // Temporarily change console propertiesConsole.CursorVisible = false;
Console.TreatControlCAsInput = true;
// Determine the string length for number of digitsint counterlength = seconds.ToString( ).Length;
// Determine the prefix string lengthint prefixlength = prefix.Length;
// Determine the suffix string lengthint suffixlength = suffix.Length;
// Display optional messageConsole.Write( prefix );
// Clear space on screen for countdown counter valueConsole.Write( new String( ' ', counterlength + suffixlength ) );
// Start countdownint countdown = seconds;
while ( !Console.KeyAvailable && countdown > 0 )
{ // Wipe previous countdown counter value from screenConsole.Write( new String( '\b', counterlength + suffixlength ) );
Console.Write( new String( ' ', counterlength + suffixlength ) );
Console.Write( new String( '\b', counterlength + suffixlength ) );
Console.Write( "{0," + counterlength + "}", countdown );
Console.Write( suffix );
countdown -= 1; // decrement countdown counter
Thread.Sleep( 1000 ); // wait 1 second
} // Wipe entire countdown counter line from screenConsole.Write( new String( '\b', counterlength + suffixlength + prefixlength ) );
Console.Write( new String( ' ', counterlength + suffixlength + prefixlength ) );
Console.Write( new String( '\b', counterlength + suffixlength + prefixlength ) );
// Restore console propertiesConsole.CursorVisible = true;
Console.TreatControlCAsInput = false;
// If a key is pressed to interrupt countdown, remove it from keyboard bufferif ( countdown > 0 && Console.KeyAvailable )
{Console.ReadKey( true );
} // Return code depends on command line switch and on countdown completionif ( returnremaining )
{return countdown; // remaining number of seconds (requires /R)
}else if ( countdown == 0 )
{return 0; // countdown completed
} else {return 2; // countdown interrupted (not with /R)
} }static int ShowHelp( params string[] errmsg )
{ #region Help Text /* CountDown, Version 2.01 Count down for the specified number of seconds or until a key is pressed Usage: COUNTDOWN [ prefix ] seconds [ suffix ] [ /R ] or: COUNTDOWN "prefix seconds suffix" [ /R ] Where: prefix optional prefix message for the counter, e.g. "Waiting " seconds delay in seconds (1 .. 86400 = 1 second .. 24 hours) suffix optional suffix message for the counter, e.g. " seconds" /R return code equals the number of Remaining seconds (default: return code 0 = OK, 1 = errors, 2 = key pressed) Note: COUNTDOWN "Wait " 20 " seconds" is equal to COUNTDOWN "Wait 20 seconds" In the latter notation the first number on the command line will be used for seconds, any following number will be included in suffix. Written by Rob van der Woude https://www.robvanderwoude.com */ #endregion Help Text #region Error Messageif ( errmsg.Length > 0 )
{List<string> errargs = new List<string>( errmsg );
errargs.RemoveAt( 0 );
Console.Error.WriteLine( );
Console.ForegroundColor = ConsoleColor.Red;
Console.Error.Write( "ERROR:\t" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) );
Console.ResetColor( );
} #endregion Error Message #region Display Help TextConsole.Error.WriteLine( );
Console.Error.WriteLine( "CountDown, Version {0}", progver );
Console.Error.WriteLine( "Count down for the specified number of seconds or until a key is pressed" );
Console.Error.WriteLine( );
Console.Error.Write( "Usage: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( "COUNTDOWN [ prefix ] seconds [ suffix ] [ /R ]" );
Console.ResetColor( );
Console.Error.WriteLine( );
Console.Error.Write( " or: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( "COUNTDOWN \"prefix seconds suffix\" [ /R ]" );
Console.ResetColor( );
Console.Error.WriteLine( );
Console.Error.Write( "Where: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "prefix " );
Console.ResetColor( );
Console.Error.WriteLine( "optional prefix message for the counter, e.g. \"Waiting \"" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " seconds " );
Console.ResetColor( );
Console.Error.WriteLine( "delay in seconds (1 .. 86400 = 1 second .. 24 hours)" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " suffix " );
Console.ResetColor( );
Console.Error.WriteLine( "optional suffix message for the counter, e.g. \" seconds\"" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /R" );
Console.ResetColor( );
Console.Error.Write( " return code equals the number of " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "R" );
Console.ResetColor( );
Console.Error.WriteLine( "emaining seconds" );
Console.Error.WriteLine( " (default: return code 0 = OK, 1 = errors, 2 = key pressed)" );
Console.Error.WriteLine( );
Console.Error.Write( "Note: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "COUNTDOWN \"Wait \" 20 \" seconds\" " );
Console.ResetColor( );
Console.Error.Write( "is equal to " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( "COUNTDOWN \"Wait 20 seconds\"" );
Console.ResetColor( );
Console.Error.WriteLine( " In the latter notation the first number on the command line will be" );
Console.Error.Write( " used for " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "seconds" );
Console.ResetColor( );
Console.Error.Write( ", any following number will be included in " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "suffix" );
Console.ResetColor( );
Console.Error.WriteLine( "." );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Written by Rob van der Woude" );
Console.Error.WriteLine( "https://www.robvanderwoude.com" );
#endregion Display Help Textreturn 1;
} }}page last modified: 2025-10-11; loaded in 0.0081 seconds