Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for secondchoice.cs

(view source code of secondchoice.cs as plain text)

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text.RegularExpressions;
  4. using System.Threading;
  5. using System.Timers;
  6.  
  7.  
  8. namespace RobvanderWoude
  9. {
  10. 	class SecondChoice
  11. 	{
  12. 		static string progver = "1.02";
  13.  
  14.  
  15. 		#region Global Variables
  16.  
  17. 		static bool cancel = false;
  18. 		static int rc = 0;
  19. 		static string choices = "YN";
  20. 		static string defaultchoice = String.Empty;
  21.  
  22. 		#endregion Global Variables
  23.  
  24.  
  25. 		static int Main( string[] args )
  26. 		{
  27. 			#region Capture Control+Break
  28.  
  29. 			// Code to gracefully exit on Ctrl+Break by Alois Kraus
  30. 			// http://www.codeproject.com/Articles/16164/Managed-Application-Shutdown
  31. 			//
  32. 			// Note that this will NOT prevent passing on the Ctrl+Break to the hosting process, the
  33. 			// only purpose for this code is to make this program exit wit errorlevel 0 on Ctrl+Break
  34. 			Console.CancelKeyPress += delegate( object sender, ConsoleCancelEventArgs e )
  35. 			{
  36. 				if ( e.SpecialKey == ConsoleSpecialKey.ControlBreak )
  37. 				{
  38. 					e.Cancel = true;
  39. 					new Thread( delegate( )
  40. 					{
  41. 						Environment.Exit( 0 );
  42. 					} ).Start( );
  43. 				}
  44. 			};
  45.  
  46. 			#endregion Capture Control+Break
  47.  
  48.  
  49. 			#region Local variables
  50.  
  51. 			bool casesensitive = false;
  52. 			bool hidechoices = false;
  53. 			bool usedefault = false;
  54. 			bool usetimeout = false;
  55. 			bool waitingforchoices = false;
  56. 			bool waitingfordefault = false;
  57. 			bool waitingformessage = false;
  58. 			bool waitingfortimeout = false;
  59. 			string message = String.Empty;
  60. 			int timeout = -1;
  61.  
  62. 			#endregion Local variables
  63.  
  64.  
  65. 			#region Command Line Parsing
  66.  
  67. 			foreach ( string arg in args )
  68. 			{
  69. 				if ( arg == "/?" )
  70. 				{
  71. 					return ShowHelp( );
  72. 				}
  73. 			}
  74.  
  75. 			if ( args.Length > 10 )
  76. 			{
  77. 				return ShowHelp( "Too many command line arguments" );
  78. 			}
  79.  
  80. 			foreach ( string arg in args )
  81. 			{
  82. 				switch ( arg.ToUpper( ) )
  83. 				{
  84. 					// Check for command line switches separates by spaces
  85. 					case "/C":
  86. 						if ( choices.ToUpper( ) != "YN" || waitingforchoices )
  87. 						{
  88. 							return ShowHelp( "Duplicate command line switch /C" );
  89. 						}
  90. 						if ( waitingfordefault )
  91. 						{
  92. 							return ShowHelp( "/D is used, but no default choice is specified" );
  93. 						}
  94. 						if ( waitingformessage )
  95. 						{
  96. 							return ShowHelp( "/M is used, but no message is specified" );
  97. 						}
  98. 						if ( waitingfortimeout )
  99. 						{
  100. 							return ShowHelp( "/T is used, but no timeout is specified" );
  101. 						}
  102. 						waitingforchoices = true;
  103. 						break;
  104. 					case "/CS":
  105. 						if ( casesensitive )
  106. 						{
  107. 							return ShowHelp( "Duplicate command line switch /CS" );
  108. 						}
  109. 						casesensitive = true;
  110. 						break;
  111. 					case "/D":
  112. 						if ( usedefault || waitingfordefault )
  113. 						{
  114. 							return ShowHelp( "Duplicate command line switch /D" );
  115. 						}
  116. 						if ( waitingforchoices )
  117. 						{
  118. 							return ShowHelp( "/C is used, but no choices are specified" );
  119. 						}
  120. 						if ( waitingformessage )
  121. 						{
  122. 							return ShowHelp( "/M is used, but no message is specified" );
  123. 						}
  124. 						if ( waitingfortimeout )
  125. 						{
  126. 							return ShowHelp( "/T is used, but no timeout is specified" );
  127. 						}
  128. 						usedefault = true;
  129. 						waitingfordefault = true;
  130. 						break;
  131. 					case "/M":
  132. 						if ( waitingformessage )
  133. 						{
  134. 							return ShowHelp( "Duplicate command line switch /D" );
  135. 						}
  136. 						if ( waitingforchoices )
  137. 						{
  138. 							return ShowHelp( "/C is used, but no choices are specified" );
  139. 						}
  140. 						if ( waitingfordefault )
  141. 						{
  142. 							return ShowHelp( "/D is used, but no default choice is specified" );
  143. 						}
  144. 						if ( waitingfortimeout )
  145. 						{
  146. 							return ShowHelp( "/T is used, but no timeout is specified" );
  147. 						}
  148. 						waitingformessage = true;
  149. 						break;
  150. 					case "/N":
  151. 						if ( hidechoices )
  152. 						{
  153. 							return ShowHelp( "Duplicate command line switch /N" );
  154. 						}
  155. 						hidechoices = true;
  156. 						break;
  157. 					case "/T":
  158. 						if ( usetimeout || waitingfortimeout )
  159. 						{
  160. 							return ShowHelp( "Duplicate command line switch /T" );
  161. 						}
  162. 						if ( waitingforchoices )
  163. 						{
  164. 							return ShowHelp( "/C is used, but no choices are specified" );
  165. 						}
  166. 						if ( waitingfordefault )
  167. 						{
  168. 							return ShowHelp( "/D is used, but no default choice is specified" );
  169. 						}
  170. 						if ( waitingformessage )
  171. 						{
  172. 							return ShowHelp( "/M is used, but no message is specified" );
  173. 						}
  174. 						usetimeout = true;
  175. 						waitingfortimeout = true;
  176. 						break;
  177. 					default:
  178. 						// Check for values belonging to a previous switch
  179. 						if ( waitingforchoices )
  180. 						{
  181. 							choices = arg;
  182. 							waitingforchoices = false;
  183. 						}
  184. 						else if ( waitingfordefault )
  185. 						{
  186. 							defaultchoice = arg;
  187. 							waitingfordefault = false;
  188. 						}
  189. 						else if ( waitingformessage )
  190. 						{
  191. 							message = arg;
  192. 							waitingformessage = false;
  193. 						}
  194. 						else if ( waitingfortimeout )
  195. 						{
  196. 							try
  197. 							{
  198. 								timeout = Convert.ToInt32( arg );
  199. 								waitingfortimeout = false;
  200. 							}
  201. 							catch ( Exception )
  202. 							{
  203. 								return ShowHelp( "Invalid timeout value \"{0}\"", arg );
  204. 							}
  205. 						}
  206. 						else
  207. 						{
  208. 							// Check for arguments with values immediately appended, with colon or equal sign as separator
  209. 							if ( arg.Length > 3 && arg[0] == '/' && "CDMNTcdmnt".IndexOf( arg[1] ) != -1 && ( arg[2] == ':' || arg[2] == '=' ) )
  210. 							{
  211. 								switch ( arg.ToUpper( ).Substring( 0, 2 ) )
  212. 								{
  213. 									case "/C":
  214. 										if ( choices.ToUpper( ) != "YN" || waitingforchoices )
  215. 										{
  216. 											return ShowHelp( "Duplicate command line switch /C" );
  217. 										}
  218. 										choices = arg.Substring( 3 );
  219. 										break;
  220. 									case "/D":
  221. 										if ( usedefault || waitingfordefault )
  222. 										{
  223. 											return ShowHelp( "Duplicate command line switch /D" );
  224. 										}
  225. 										usedefault = true;
  226. 										defaultchoice = arg.Substring( 3 );
  227. 										break;
  228. 									case "/M":
  229. 										if ( waitingformessage )
  230. 										{
  231. 											return ShowHelp( "Duplicate command line switch /D" );
  232. 										}
  233. 										message = arg.Substring( 3 );
  234. 										break;
  235. 									case "/T":
  236. 										if ( usetimeout || waitingfortimeout )
  237. 										{
  238. 											return ShowHelp( "Duplicate command line switch /T" );
  239. 										}
  240. 										try
  241. 										{
  242. 											usetimeout = true;
  243. 											timeout = Convert.ToInt32( arg.Substring( 3 ) );
  244. 										}
  245. 										catch ( Exception )
  246. 										{
  247. 											return ShowHelp( "Invalid timeout value \"{0}\"", arg );
  248. 										}
  249. 										break;
  250. 								}
  251. 							}
  252. 							else
  253. 							{
  254. 								return ShowHelp( "Invalid command line argument \"{0}\"", arg );
  255. 							}
  256. 						}
  257. 						break;
  258. 				}
  259. 			}
  260.  
  261. 			#endregion Command Line Parsing
  262.  
  263.  
  264. 			#region Command Line Validation
  265.  
  266. 			// Timeout requires a default value
  267. 			if ( usetimeout && !usedefault )
  268. 			{
  269. 				return ShowHelp( "If timeout is specified, default value must be specified too" );
  270. 			}
  271.  
  272. 			// If a default is specified, it must be a single character, found in the list of choices
  273. 			if ( usedefault && ( defaultchoice.Length != 1 || choices.IndexOfAny( defaultchoice.ToCharArray( ) ) == -1 ) )
  274. 			{
  275. 				return ShowHelp( "Default specified by /D must be a single character\n\tfrom the list of choices specified by /C" );
  276. 			}
  277.  
  278. 			// Less than 1 choice is useless
  279. 			if ( choices.Length < 2 )
  280. 			{
  281. 				return ShowHelp( "Specify at least 2 choices" );
  282. 			}
  283.  
  284. 			// Check for duplicates in list of choices
  285. 			Regex regex;
  286. 			string pattern = @"([\w ]).*\1";
  287. 			if ( casesensitive )
  288. 			{
  289. 				regex = new Regex( pattern );
  290. 			}
  291. 			else
  292. 			{
  293. 				regex = new Regex( pattern, RegexOptions.IgnoreCase );
  294. 			}
  295. 			if ( regex.IsMatch( choices ) )
  296. 			{
  297. 				return ShowHelp( "All choices specified by /C must be unique" );
  298. 			}
  299. 			if ( !casesensitive )
  300. 			{
  301. 				if ( usedefault )
  302. 				{
  303. 					// Show the list of choices in lower case, with the default choice in upper case
  304. 					choices = choices.ToLower( ).Replace( defaultchoice.ToLower( ), defaultchoice.ToUpper( ) );
  305. 				}
  306. 				else
  307. 				{
  308. 					// Show the list of choices in upper case
  309. 					choices = choices.ToUpper( );
  310. 				}
  311. 			}
  312.  
  313. 			if ( usetimeout && timeout > 0 )
  314. 			{
  315. 				// Check if specified timeout is in accepted range
  316. 				if ( timeout < 0 || timeout > 86400 )
  317. 				{
  318. 					return ShowHelp( "Timeout must be in range 0..86400 seconds (0..24h)" );
  319. 				}
  320. 				System.Timers.Timer timer = new System.Timers.Timer( );
  321. 				timer.Elapsed += new ElapsedEventHandler( timer_Elapsed );
  322. 				timer.Interval = timeout * 1000;
  323. 				timer.Start( );
  324. 			}
  325.  
  326. 			#endregion Command Line Validation
  327.  
  328.  
  329. 			#region Show Prompt
  330.  
  331. 			string prompt = String.Empty;
  332. 			if ( hidechoices )
  333. 			{
  334. 				if ( !String.IsNullOrWhiteSpace( message ) )
  335. 				{
  336. 					prompt = String.Format( "{0}: ", message );
  337. 				}
  338. 			}
  339. 			else
  340. 			{
  341. 				prompt = String.Format( "{0} [{1}]: ", message, choices ).TrimStart( );
  342. 			}
  343.  
  344. 			#endregion Show Prompt
  345.  
  346.  
  347. 			#region Handle Response
  348.  
  349. 			Console.Write( prompt );
  350.  
  351. 			// If timeout is zero, return default immediately
  352. 			if ( usetimeout && timeout == 0 )
  353. 			{
  354. 				Console.WriteLine( defaultchoice );
  355. 				rc = choices.IndexOf( defaultchoice[0] ) + 1;
  356. 				return rc;
  357. 			}
  358.  
  359. 			// Tell console to capture Ctrl+C as input
  360. 			Console.TreatControlCAsInput = true;
  361. 			// Wait for response
  362. 			ConsoleKeyInfo response;
  363. 			while ( !cancel )
  364. 			{
  365. 				response = Console.ReadKey( true );
  366. 				string key = response.KeyChar.ToString( );
  367. 				bool ctrlkey = ( ( ( response.Modifiers & ConsoleModifiers.Control ) != 0 ) && ( ( response.Modifiers & ConsoleModifiers.Alt ) == 0 ) && ( ( response.Modifiers & ConsoleModifiers.Shift ) == 0 ) );
  368. 				bool shiftkey = ( ( ( response.Modifiers & ConsoleModifiers.Shift ) != 0 ) && ( ( response.Modifiers & ConsoleModifiers.Alt ) == 0 ) && ( ( response.Modifiers & ConsoleModifiers.Control ) == 0 ) );
  369. 				bool nomodifiers = ( response.Modifiers == 0 );
  370. 				bool escapekey = ( ( response.Key == ConsoleKey.Escape ) && nomodifiers );
  371. 				bool enterkey = ( ( response.Key == ConsoleKey.Enter ) && nomodifiers );
  372. 				// Ctrl+C
  373. 				if ( ctrlkey && ( key == ( (char) 3 ).ToString( ) ) )
  374. 				{
  375. 					rc = 0;
  376. 					cancel = true;
  377. 					break;
  378. 				}
  379. 				// Escape
  380. 				if ( escapekey )
  381. 				{
  382. 					rc = 0;
  383. 					cancel = true;
  384. 					break;
  385. 				}
  386. 				// Case sensitive?
  387. 				if ( shiftkey || !casesensitive )
  388. 				{
  389. 					key = key.ToUpper( );
  390. 				}
  391. 				// Default on Enter
  392. 				if ( enterkey && usedefault )
  393. 				{
  394. 					rc = choices.IndexOf( defaultchoice[0] ) + 1;
  395. 					if ( rc > 0 )
  396. 					{
  397. 						Console.WriteLine( defaultchoice );
  398. 						break;
  399. 					}
  400. 				}
  401. 				// Check if valid key pressed
  402. 				rc = choices.IndexOf( key[0] ) + 1;
  403. 				if ( rc > 0 )
  404. 				{
  405. 					Console.WriteLine( key );
  406. 					break;
  407. 				}
  408. 			}
  409.  
  410. 			#endregion Handle Response
  411.  
  412.  
  413. 			return rc;
  414. 		}
  415.  
  416.  
  417. 		static int ShowHelp( params string[] errmsg )
  418. 		{
  419. 			#region Help Text
  420.  
  421. 			/*
  422. 			SecondChoice.exe,  Version 1.02
  423. 			Alternative to Windows' native CHOICE command.
  424. 			Like CHOICE, SecondChoice allows users to select one item from
  425. 			a list of choices and returns the index of the selected choice.
  426. 			Unlike CHOICE, SecondChoice also returns the default value on
  427. 			pressing the Enter key (besides after timeout expiration).
  428. 			And unlike CHOICE, SecondChoice accepts a space in the list of
  429. 			choices if that list is in doublequotes.
  430.  
  431. 			Usage:     SECONDCHOICE  [ options ]
  432.  
  433. 			Options:   /C choices    Specifies the list of Choices to be created.
  434.                                      Default list is "YN".
  435. 			           /CS           Enables Case-Sensitive choices to be selected.
  436. 			                         By default, the utility is case-insensitive.
  437. 			           /D default    Specifies the Default choice after the timeout
  438. 			                         expires or after pressing Enter.
  439. 			                         The default character must be in the list of
  440. 			                         choices specified by /C option.
  441. 			           /M message    Specifies the Message to be displayed before
  442. 			                         the prompt. If not specified, the utility
  443. 			                         displays only a prompt.
  444. 			           /N            Hides the list of choices in the prompt.
  445. 			                         The message before the prompt is displayed
  446. 			                         and the choices are still enabled.
  447. 			           /T timeout    The number of seconds to pause before a default
  448. 			                         choice is made. Acceptable values are from 0 to
  449. 			                         86400 (24 hours). If 0 is specified, there will
  450. 			                         be no pause and the default choice is selected.
  451.  
  452. 			 Notes:    The ERRORLEVEL environment variable is set to the index of the
  453. 			           key that was selected from the set of choices. The first choice
  454. 			           listed returns a value of 1, the second a value of 2, and so on.
  455. 			           Invalid choices are ignored.
  456. 			           If SecondChoice detects an error, it returns ERRORLEVEL 255, if the
  457. 			           user presses ESC, CTRL+C or CTRL+BREAK, the ERRORLEVEL will be 0.
  458. 			           Pressing CTRL+BREAK will also be passed on to the hosting process.
  459. 			           Besides spaces between switches and values, colons or equal signs
  460. 			           are accepted too, e.g. /C choices or /C:choices or /C=choices are
  461. 			           all accepted.
  462. 			           SecondChoice also accepts a space as a valid choice; make sure you
  463. 			           place the list of choices in doublequotes if you want to use a space
  464. 			           in the list of choices, e.g. /C " ABC" or /C:" ABC" or /C=" ABC".
  465.  
  466. 			Examples:  SECONDCHOICE /C YNC /M "Press Y for Yes, N for No or C for Cancel."
  467. 			           SECONDCHOICE /T=10 /C=YNC /D=C /M="Y=yes, N=no, C or timeout=cancel"
  468. 			           SECONDCHOICE /C YN /N /D Y /M "Press Enter or Y for Yes, or N for No"
  469. 			           SECONDCHOICE /C:AB /M:"Select A for option 1 and B for option 2."
  470. 			           SECONDCHOICE /C 12 /N /M "Select 1 for option 1 and 2 for option 2."
  471.  
  472. 			Credits:   Code to gracefully exit on Ctrl+Break by Alois Kraus
  473. 			           http://codeproject.com/Articles/16164/Managed-Application-Shutdown
  474.  
  475. 			Written by Rob van der Woude
  476. 			http://www.robvanderwoude.com
  477. 			*/
  478.  
  479. 			if ( errmsg.Length > 0 )
  480. 			{
  481. 				List<string> errargs = new List<string>( errmsg );
  482. 				errargs.RemoveAt( 0 );
  483. 				Console.Error.WriteLine( );
  484. 				Console.ForegroundColor = ConsoleColor.Red;
  485. 				Console.Error.Write( "ERROR:\t" );
  486. 				Console.ForegroundColor = ConsoleColor.White;
  487. 				Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) );
  488. 				Console.ResetColor( );
  489. 			}
  490.  
  491. 			Console.Error.WriteLine( );
  492.  
  493. 			Console.Error.WriteLine( "SecondChoice.exe,  Version {0}", progver );
  494.  
  495. 			Console.Error.WriteLine( "Alternative to Windows' native CHOICE command." );
  496.  
  497. 			Console.Error.WriteLine( "Like CHOICE, SecondChoice allows users to select one item from" );
  498.  
  499. 			Console.Error.WriteLine( "a list of choices and returns the index of the selected choice." );
  500.  
  501. 			Console.Error.WriteLine( "Unlike CHOICE, SecondChoice also returns the default value on" );
  502.  
  503. 			Console.Error.WriteLine( "pressing the Enter key (besides after timeout expiration)." );
  504.  
  505. 			Console.Error.WriteLine( "And unlike CHOICE, SecondChoice accepts a space in the list of" );
  506.  
  507. 			Console.Error.WriteLine( "choices if that list is in doublequotes." );
  508.  
  509. 			Console.Error.WriteLine( );
  510.  
  511. 			Console.Error.Write( "Usage:     " );
  512. 			Console.ForegroundColor = ConsoleColor.White;
  513. 			Console.Error.WriteLine( "SECONDCHOICE  [ options ]" );
  514. 			Console.ResetColor( );
  515.  
  516. 			Console.Error.WriteLine( );
  517.  
  518. 			Console.Error.Write( "Options:   " );
  519. 			Console.ForegroundColor = ConsoleColor.White;
  520. 			Console.Error.Write( "/C choices" );
  521. 			Console.ResetColor( );
  522. 			Console.Error.Write( "    Specifies the list of " );
  523. 			Console.ResetColor( );
  524. 			Console.ForegroundColor = ConsoleColor.White;
  525. 			Console.Error.Write( "C" );
  526. 			Console.ResetColor( );
  527. 			Console.Error.WriteLine( "hoices to be created." );
  528.  
  529. 			Console.Error.WriteLine( "                         Default list is \"YN\"." );
  530.  
  531. 			Console.ForegroundColor = ConsoleColor.White;
  532. 			Console.Error.Write( "           /CS" );
  533. 			Console.ResetColor( );
  534. 			Console.Error.Write( "           Enables " );
  535. 			Console.ForegroundColor = ConsoleColor.White;
  536. 			Console.Error.Write( "C" );
  537. 			Console.ResetColor( );
  538. 			Console.Error.Write( "ase-" );
  539. 			Console.ForegroundColor = ConsoleColor.White;
  540. 			Console.Error.Write( "S" );
  541. 			Console.ResetColor( );
  542. 			Console.Error.WriteLine( "ensitive choices to be selected." );
  543.  
  544. 			Console.Error.WriteLine( "                         By default, the utility is case-insensitive." );
  545.  
  546. 			Console.ForegroundColor = ConsoleColor.White;
  547. 			Console.Error.Write( "           /D default" );
  548. 			Console.ResetColor( );
  549. 			Console.Error.Write( "    Specifies the " );
  550. 			Console.ForegroundColor = ConsoleColor.White;
  551. 			Console.Error.Write( "D" );
  552. 			Console.ResetColor( );
  553. 			Console.Error.WriteLine( "efault choice after the timeout" );
  554.  
  555. 			Console.Error.WriteLine( "                         expires or after pressing Enter." );
  556.  
  557. 			Console.Error.WriteLine( "                         The default character must be in the list of" );
  558.  
  559. 			Console.Error.Write( "                         choices specified by " );
  560. 			Console.ForegroundColor = ConsoleColor.White;
  561. 			Console.Error.Write( "/C" );
  562. 			Console.ResetColor( );
  563. 			Console.Error.WriteLine( " option." );
  564.  
  565. 			Console.ForegroundColor = ConsoleColor.White;
  566. 			Console.Error.Write( "           /M message" );
  567. 			Console.ResetColor( );
  568. 			Console.Error.Write( "    Specifies the " );
  569. 			Console.ForegroundColor = ConsoleColor.White;
  570. 			Console.Error.Write( "M" );
  571. 			Console.ResetColor( );
  572. 			Console.Error.WriteLine( "essage to be displayed before" );
  573.  
  574. 			Console.Error.WriteLine( "                         the prompt. If not specified, the utility" );
  575.  
  576. 			Console.Error.WriteLine( "                         displays only a prompt." );
  577.  
  578. 			Console.ForegroundColor = ConsoleColor.White;
  579. 			Console.Error.Write( "           /N" );
  580. 			Console.ResetColor( );
  581. 			Console.Error.WriteLine( "            Hides the list of choices in the prompt." );
  582.  
  583. 			Console.Error.WriteLine( "                         The message before the prompt is displayed" );
  584.  
  585. 			Console.Error.WriteLine( "                         and the choices are still enabled." );
  586.  
  587. 			Console.ForegroundColor = ConsoleColor.White;
  588. 			Console.Error.Write( "           /T timeout" );
  589. 			Console.ResetColor( );
  590. 			Console.Error.WriteLine( "    The number of seconds to pause before a default" );
  591.  
  592. 			Console.Error.WriteLine( "                         choice is made. Acceptable values are from 0 to" );
  593.  
  594. 			Console.Error.WriteLine( "                         86400 (24 hours). If 0 is specified, there will" );
  595.  
  596. 			Console.Error.WriteLine( "                         be no pause and the default choice is selected." );
  597.  
  598. 			Console.Error.WriteLine( );
  599.  
  600. 			Console.Error.WriteLine( "Notes:     The ERRORLEVEL environment variable is set to the index of the" );
  601.  
  602. 			Console.Error.WriteLine( "           key that was selected from the set of choices. The first choice" );
  603.  
  604. 			Console.Error.WriteLine( "           listed returns a value of 1, the second a value of 2, and so on." );
  605.  
  606. 			Console.Error.WriteLine( "           Invalid choices are ignored." );
  607.  
  608. 			Console.Error.WriteLine( "           If SecondChoice detects an error, it returns ERRORLEVEL 255, if the" );
  609.  
  610. 			Console.Error.WriteLine( "           user presses ESC, CTRL+C or CTRL+BREAK, the ERRORLEVEL will be 0." );
  611.  
  612. 			Console.Error.WriteLine( "           Pressing CTRL+BREAK will also be passed on to the hosting process." );
  613.  
  614. 			Console.Error.WriteLine( "           Besides spaces between switches and values, colons or equal signs" );
  615.  
  616. 			Console.Error.Write( "           are accepted too, e.g. " );
  617. 			Console.ForegroundColor = ConsoleColor.White;
  618. 			Console.Error.Write( "/C choices" );
  619. 			Console.ResetColor( );
  620. 			Console.Error.Write( " or " );
  621. 			Console.ForegroundColor = ConsoleColor.White;
  622. 			Console.Error.Write( "/C:choices" );
  623. 			Console.ResetColor( );
  624. 			Console.Error.Write( " or " );
  625. 			Console.ForegroundColor = ConsoleColor.White;
  626. 			Console.Error.Write( "/C=choices" );
  627. 			Console.ResetColor( );
  628. 			Console.Error.WriteLine( " are" );
  629.  
  630. 			Console.Error.WriteLine( "           all accepted." );
  631.  
  632. 			Console.Error.WriteLine( "           SecondChoice also accepts a space as a valid choice; make sure you" );
  633.  
  634. 			Console.Error.WriteLine( "           place the list of choices in doublequotes if you want to use a space" );
  635.  
  636. 			Console.Error.Write( "           in the list of choices, e.g. " );
  637. 			Console.ForegroundColor = ConsoleColor.White;
  638. 			Console.Error.Write( "/C \" ABC\"" );
  639. 			Console.ResetColor( );
  640. 			Console.Error.Write( " or " );
  641. 			Console.ForegroundColor = ConsoleColor.White;
  642. 			Console.Error.Write( "/C:\" ABC\"" );
  643. 			Console.ResetColor( );
  644. 			Console.Error.Write( " or " );
  645. 			Console.ForegroundColor = ConsoleColor.White;
  646. 			Console.Error.Write( "/C=\" ABC\"" );
  647. 			Console.ResetColor( );
  648. 			Console.Error.WriteLine( "." );
  649.  
  650. 			Console.Error.WriteLine( );
  651.  
  652. 			Console.Error.Write( "Examples:  " );
  653. 			Console.ForegroundColor = ConsoleColor.White;
  654. 			Console.Error.WriteLine( "SECONDCHOICE /C YNC /M \"Press Y for Yes, N for No or C for Cancel.\"" );
  655.  
  656. 			Console.Error.WriteLine( "           SECONDCHOICE /T=10 /C=YNC /D=C /M=\"Y=yes, N=no, C or timeout=cancel\"" );
  657.  
  658. 			Console.Error.WriteLine( "           SECONDCHOICE /C YN /N /D Y /M \"Press Enter or Y for Yes, or N for No\"" );
  659.  
  660. 			Console.Error.WriteLine( "           SECONDCHOICE /C:AB /M:\"Select A for option 1 and B for option 2.\"" );
  661.  
  662. 			Console.Error.WriteLine( "           SECONDCHOICE /C 12 /N /M \"Select 1 for option 1 and 2 for option 2.\"" );
  663. 			Console.ResetColor( );
  664.  
  665. 			Console.Error.WriteLine( );
  666.  
  667. 			Console.Error.WriteLine( "Credits:   Code to gracefully exit on Ctrl+Break by Alois Kraus" );
  668.  
  669. 			Console.ForegroundColor = ConsoleColor.DarkGray;
  670. 			Console.Error.WriteLine( "           http://codeproject.com/Articles/16164/Managed-Application-Shutdown" );
  671. 			Console.ResetColor( );
  672.  
  673. 			Console.Error.WriteLine( );
  674.  
  675. 			Console.Error.WriteLine( "Written by Rob van der Woude" );
  676.  
  677. 			Console.Error.WriteLine( "http://www.robvanderwoude.com" );
  678.  
  679. 			#endregion Help Text
  680.  
  681. 			return 255;
  682. 		}
  683.  
  684.  
  685. 		#region Event Handlers
  686.  
  687. 		public static void timer_Elapsed( object sender, System.EventArgs e )
  688. 		{
  689. 			Console.WriteLine( defaultchoice );
  690. 			rc = choices.IndexOf( defaultchoice ) + 1;
  691. 			Environment.Exit( rc );
  692. 		}
  693.  
  694. 		#endregion Event Handlers
  695. 	}
  696. }
  697.  

page last uploaded: 2017-08-21, 14:26