Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for printscreen.cs

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Drawing.Imaging;
  6. using System.IO;
  7. using System.Runtime.InteropServices;
  8. using System.Text;
  9. using System.Windows.Forms;
  10.  
  11. namespace RobvanderWoude
  12. {
  13. 	class PrintScreen
  14. 	{
  15. 		static string progver = "1.02";
  16.  
  17.  
  18. 		static int Main( string[] args )
  19. 		{
  20. 			try
  21. 			{
  22. 				string outputfile = String.Empty;
  23. 				bool overwrite = false;
  24. 				bool savetext = false;
  25. 				bool trimoutput = false;
  26. 				bool typeset = false;
  27. 				ImageFormat type = null;
  28.  
  29. 				#region Command Line parsing
  30.  
  31. 				if ( args.Length == 0 || args.Length > 3 )
  32. 				{
  33. 					return ErrorMessage( );
  34. 				}
  35.  
  36. 				foreach ( string arg in args )
  37. 				{
  38. 					switch ( arg.ToUpper( ).Substring( 0, 2 ) )
  39. 					{
  40. 						case "/?":
  41. 							return ErrorMessage( );
  42. 						case "/C":
  43. 							if ( trimoutput )
  44. 							{
  45. 								return ErrorMessage( "Duplicate command line switch /C" );
  46. 							}
  47. 							trimoutput = true;
  48. 							break;
  49. 						case "/O":
  50. 							if ( overwrite )
  51. 							{
  52. 								return ErrorMessage( "Duplicate command line switch /O" );
  53. 							}
  54. 							overwrite = true;
  55. 							break;
  56. 						case "/T":
  57. 							if ( typeset )
  58. 							{
  59. 								return ErrorMessage( "Duplicate command line switch /T" );
  60. 							}
  61. 							switch ( arg.ToUpper( ).Substring( 3 ) )
  62. 							{
  63. 								case "BMP":
  64. 									type = ImageFormat.Bmp;
  65. 									break;
  66. 								case "GIF":
  67. 									type = ImageFormat.Gif;
  68. 									break;
  69. 								case "JPG":
  70. 								case "JPEG":
  71. 									type = ImageFormat.Jpeg;
  72. 									break;
  73. 								case "PNG":
  74. 									type = ImageFormat.Png;
  75. 									break;
  76. 								case "TIF":
  77. 								case "TIFF":
  78. 									type = ImageFormat.Tiff;
  79. 									break;
  80. 								case "TXT":
  81. 								case "TEXT":
  82. 									savetext = true;
  83. 									break;
  84. 								default:
  85. 									return ErrorMessage( "Invalid file format \"{0}\"", arg.Substring( 3 ) );
  86. 							}
  87. 							typeset = true;
  88. 							break;
  89. 						default:
  90. 							if ( arg[0] == '/' )
  91. 							{
  92. 								return ErrorMessage( "Invalid command line switch \"{0}\"", arg );
  93. 							}
  94. 							else
  95. 							{
  96. 								if ( !String.IsNullOrEmpty( outputfile ) )
  97. 								{
  98. 									return ErrorMessage( "Duplicate output file name arguments:\n\t\"{0}\"\n\t\"{1}\"", outputfile, Path.GetFullPath( arg ) );
  99. 								}
  100. 								try
  101. 								{
  102. 									outputfile = Path.GetFullPath( arg );
  103. 								}
  104. 								catch ( Exception )
  105. 								{
  106. 									return ErrorMessage( "Invalid output file \"{0}\"", arg );
  107. 								}
  108. 							}
  109. 							break;
  110. 					}
  111. 				}
  112.  
  113. 				if ( String.IsNullOrEmpty( outputfile ) )
  114. 				{
  115. 					return ErrorMessage( "No output file specified." );
  116. 				}
  117.  
  118. 				// Check if directory exists
  119. 				if ( !Directory.Exists( Directory.GetParent( outputfile ).FullName ) )
  120. 				{
  121. 					return ErrorMessage( "Invalid path for output file \"{0}\"", outputfile );
  122. 				}
  123.  
  124. 				// Check if file exists, and if so, if it can be overwritten
  125. 				if ( File.Exists( outputfile ) )
  126. 				{
  127. 					if ( overwrite )
  128. 					{
  129. 						File.Delete( outputfile );
  130. 					}
  131. 					else
  132. 					{
  133. 						return ErrorMessage( "Output file exists.\n\tUse /O to overwrite existing files." );
  134. 					}
  135. 				}
  136.  
  137. 				if ( type == null && savetext == false )
  138. 				{
  139. 					string ext = Path.GetExtension( outputfile ).ToUpper( );
  140. 					switch ( ext )
  141. 					{
  142. 						case "":
  143. 							return ErrorMessage( "No extension for output file.\n\tUse /T to specify the output file type.", outputfile );
  144. 						case ".BMP":
  145. 							type = ImageFormat.Bmp;
  146. 							break;
  147. 						case ".GIF":
  148. 							type = ImageFormat.Gif;
  149. 							break;
  150. 						case ".JPG":
  151. 						case ".JPEG":
  152. 							type = ImageFormat.Jpeg;
  153. 							break;
  154. 						case ".PNG":
  155. 							type = ImageFormat.Png;
  156. 							break;
  157. 						case ".TIF":
  158. 						case ".TIFF":
  159. 							type = ImageFormat.Tiff;
  160. 							break;
  161. 						case ".TXT":
  162. 							savetext = true;
  163. 							break;
  164. 						default:
  165. 							return ErrorMessage( "Unrecognized extension \"{0}\" for output file.\n\tUse /T to specify the output file type.", ext );
  166. 					}
  167. 				}
  168.  
  169. 				#endregion Command Line parsing
  170.  
  171. 				if ( savetext )
  172. 				{
  173. 					// Based on code by Simon Mourier (http://www.softfluent.com/)
  174. 					// http://stackoverflow.com/questions/12355378/read-from-location-on-console-c-sharp
  175. 					string readtext = string.Empty;
  176. 					for ( short i = 0; i < (short) Console.BufferHeight; i++ )
  177. 					{
  178. 						foreach ( string line in ConsoleReader.ReadFromBuffer( 0, i, (short) Console.BufferWidth, 1 ) )
  179. 						{
  180. 							if ( trimoutput )
  181. 							{
  182. 								// Trim whitespace from the end of the line, based on a suggestion by Daniel Saul Dominguez
  183. 								readtext += line.TrimEnd( "\t ".ToCharArray( ) ) + "\n";
  184. 							}
  185. 							else
  186. 							{
  187. 								readtext += line + "\n";
  188. 							}
  189. 						}
  190. 					}
  191. 					readtext = readtext.TrimEnd( " \n\r\t".ToCharArray( ) );
  192. 					StreamWriter file = new StreamWriter( outputfile );
  193. 					file.Write( readtext );
  194. 					file.Close( );
  195. 				}
  196. 				else
  197. 				{
  198. 					// Based on code by Ali Hamdar (http://alihamdar.com/)
  199. 					// http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/79efecc4-fa6d-4078-afe4-bb1379bb968b
  200. 					// Default values for full screen
  201. 					int width = Screen.PrimaryScreen.Bounds.Width;
  202. 					int height = Screen.PrimaryScreen.Bounds.Height;
  203. 					int top = 0;
  204. 					int left = 0;
  205. 					Bitmap printscreen = new Bitmap( width, height );
  206. 					Graphics graphics = Graphics.FromImage( printscreen as Image );
  207. 					graphics.CopyFromScreen( top, left, 0, 0, printscreen.Size );
  208. 					printscreen.Save( outputfile, type );
  209. 				}
  210. 				return 0;
  211. 			}
  212. 			catch ( Exception e )
  213. 			{
  214. 				return ErrorMessage( e.Message );
  215. 			}
  216. 		}
  217.  
  218.  
  219. 		#region Error Handling
  220.  
  221. 		public static int ErrorMessage( params string[] errmsg )
  222. 		{
  223. 			/*
  224. 			PrintScreen,  Version 1.01
  225. 			Save a screenshot as image or save the current console buffer as text
  226.  
  227. 			Usage:   PRINTSCREEN  outputfile  [ options ]
  228.  
  229. 			Where:   outputfile   is the file to save the screenshot or text to
  230. 			Options: /C           trim lines (text only)
  231. 			         /O           overwrites an existing file
  232. 			         /T:type      specifies the file type: BMP, GIF, JPG, PNG, TIF or TXT
  233. 			                      (required only if outputfile extension is different)
  234.  
  235. 			Credits: Code to read console buffer by Simon Mourier http://www.softfluent.com
  236. 			         Code for graphic screenshot by Ali Hamdar    http://alihamdar.com
  237.  
  238. 			Written by Rob van der Woude
  239. 			http://www.robvanderwoude.com
  240. 			*/
  241.  
  242. 			if ( errmsg.Length > 0 )
  243. 			{
  244. 				List<string> errargs = new List<string>( errmsg );
  245. 				errargs.RemoveAt( 0 );
  246. 				Console.Error.WriteLine( );
  247. 				Console.ForegroundColor = ConsoleColor.Red;
  248. 				Console.Error.Write( "ERROR:\t" );
  249. 				Console.ForegroundColor = ConsoleColor.White;
  250. 				Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) );
  251. 				Console.ResetColor( );
  252. 			}
  253.  
  254. 			Console.Error.WriteLine( );
  255.  
  256. 			Console.Error.WriteLine( "PrintScreen,  Version {0}", progver );
  257.  
  258. 			Console.Error.WriteLine( "Save a screenshot as image or save the current console buffer as text" );
  259.  
  260. 			Console.Error.WriteLine( );
  261.  
  262. 			Console.Error.Write( "Usage:   " );
  263. 			Console.ForegroundColor = ConsoleColor.White;
  264. 			Console.Error.WriteLine( "PRINTSCREEN  outputfile  [ options ]" );
  265. 			Console.ResetColor( );
  266. 			Console.Error.WriteLine( );
  267.  
  268. 			Console.Error.Write( "Where:   " );
  269. 			Console.ForegroundColor = ConsoleColor.White;
  270. 			Console.Error.Write( "outputfile" );
  271. 			Console.ResetColor( );
  272. 			Console.Error.WriteLine( "   is the file to save the screenshot or text to" );
  273.  
  274. 			Console.Error.Write( "Options: " );
  275. 			Console.ForegroundColor = ConsoleColor.White;
  276. 			Console.Error.Write( "/C" );
  277. 			Console.ResetColor( );
  278. 			Console.Error.WriteLine( "           trim lines (text only)" );
  279.  
  280. 			Console.ForegroundColor = ConsoleColor.White;
  281. 			Console.Error.Write( "         /O" );
  282. 			Console.ResetColor( );
  283. 			Console.Error.WriteLine( "           overwrites an existing file" );
  284.  
  285. 			Console.ForegroundColor = ConsoleColor.White;
  286. 			Console.Error.Write( "         /T:type" );
  287. 			Console.ResetColor( );
  288. 			Console.Error.Write( "      specifies the file type: " );
  289. 			Console.ForegroundColor = ConsoleColor.White;
  290. 			Console.Error.Write( "BMP" );
  291. 			Console.ResetColor( );
  292. 			Console.Error.Write( ", " );
  293. 			Console.ForegroundColor = ConsoleColor.White;
  294. 			Console.Error.Write( "GIF" );
  295. 			Console.ResetColor( );
  296. 			Console.Error.Write( ", " );
  297. 			Console.ForegroundColor = ConsoleColor.White;
  298. 			Console.Error.Write( "JPG" );
  299. 			Console.ResetColor( );
  300. 			Console.Error.Write( ", " );
  301. 			Console.ForegroundColor = ConsoleColor.White;
  302. 			Console.Error.Write( "PNG" );
  303. 			Console.ResetColor( );
  304. 			Console.Error.Write( ", " );
  305. 			Console.ForegroundColor = ConsoleColor.White;
  306. 			Console.Error.Write( "TIF" );
  307. 			Console.ResetColor( );
  308. 			Console.Error.Write( " or " );
  309. 			Console.ForegroundColor = ConsoleColor.White;
  310. 			Console.Error.WriteLine( "TXT" );
  311. 			Console.ResetColor( );
  312.  
  313. 			Console.Error.Write( "                      (required only if " );
  314. 			Console.ForegroundColor = ConsoleColor.White;
  315. 			Console.Error.Write( "outputfile" );
  316. 			Console.ResetColor( );
  317. 			Console.Error.WriteLine( " extension is different)" );
  318.  
  319. 			Console.Error.WriteLine( );
  320.  
  321. 			Console.Error.Write( "Credits: Code to read console buffer by Simon Mourier " );
  322. 			Console.ForegroundColor = ConsoleColor.DarkGray;
  323. 			Console.Error.WriteLine( "http://www.softfluent.com" );
  324. 			Console.ResetColor( );
  325.  
  326. 			Console.Error.Write( "         Code for graphic screenshot by Ali Hamdar    " );
  327. 			Console.ForegroundColor = ConsoleColor.DarkGray;
  328. 			Console.Error.WriteLine( "http://alihamdar.com" );
  329. 			Console.ResetColor( );
  330.  
  331. 			Console.Error.WriteLine( );
  332.  
  333. 			Console.Error.WriteLine( "Written by Rob van der Woude" );
  334.  
  335. 			Console.Error.WriteLine( "http://www.robvanderwoude.com" );
  336. 			return 1;
  337. 		}
  338.  
  339. 		#endregion Error Handling
  340.  
  341. 	}
  342.  
  343. 	#region Read From Console Buffer
  344.  
  345. 	// ConsoleReader by Simon Mourier (http://www.softfluent.com/)
  346. 	// http://stackoverflow.com/questions/12355378/read-from-location-on-console-c-sharp
  347. 	public class ConsoleReader
  348. 	{
  349. 		public static IEnumerable<string> ReadFromBuffer( short x, short y, short width, short height )
  350. 		{
  351. 			IntPtr buffer = Marshal.AllocHGlobal( width * height * Marshal.SizeOf( typeof( CHAR_INFO ) ) );
  352. 			if ( buffer == null )
  353. 				throw new OutOfMemoryException( );
  354.  
  355. 			try
  356. 			{
  357. 				COORD coord = new COORD( );
  358. 				SMALL_RECT rc = new SMALL_RECT( );
  359. 				rc.Left = x;
  360. 				rc.Top = y;
  361. 				rc.Right = (short) ( x + width - 1 );
  362. 				rc.Bottom = (short) ( y + height - 1 );
  363.  
  364. 				COORD size = new COORD( );
  365. 				size.X = width;
  366. 				size.Y = height;
  367.  
  368. 				const int STD_OUTPUT_HANDLE = -11;
  369. 				if ( !ReadConsoleOutput( GetStdHandle( STD_OUTPUT_HANDLE ), buffer, size, coord, ref rc ) )
  370. 				{
  371. 					// 'Not enough storage is available to process this command' may be raised for buffer size > 64K (see ReadConsoleOutput doc.)
  372. 					throw new Win32Exception( Marshal.GetLastWin32Error( ) );
  373. 				}
  374.  
  375. 				IntPtr ptr = buffer;
  376. 				for ( int h = 0; h < height; h++ )
  377. 				{
  378. 					StringBuilder sb = new StringBuilder( );
  379. 					for ( int w = 0; w < width; w++ )
  380. 					{
  381. 						CHAR_INFO ci = (CHAR_INFO) Marshal.PtrToStructure( ptr, typeof( CHAR_INFO ) );
  382. 						char[] chars = Console.OutputEncoding.GetChars( ci.charData );
  383. 						sb.Append( chars[0] );
  384. 						ptr += Marshal.SizeOf( typeof( CHAR_INFO ) );
  385. 					}
  386. 					yield return sb.ToString( );
  387. 				}
  388. 			}
  389. 			finally
  390. 			{
  391. 				Marshal.FreeHGlobal( buffer );
  392. 			}
  393. 		}
  394.  
  395. 		[StructLayout( LayoutKind.Sequential )]
  396. 		private struct CHAR_INFO
  397. 		{
  398. 			[MarshalAs( UnmanagedType.ByValArray, SizeConst = 2 )]
  399. 			public byte[] charData;
  400. 			public short attributes;
  401. 		}
  402.  
  403. 		[StructLayout( LayoutKind.Sequential )]
  404. 		private struct COORD
  405. 		{
  406. 			public short X;
  407. 			public short Y;
  408. 		}
  409.  
  410. 		[StructLayout( LayoutKind.Sequential )]
  411. 		private struct SMALL_RECT
  412. 		{
  413. 			public short Left;
  414. 			public short Top;
  415. 			public short Right;
  416. 			public short Bottom;
  417. 		}
  418.  
  419. 		[StructLayout( LayoutKind.Sequential )]
  420. 		private struct CONSOLE_SCREEN_BUFFER_INFO
  421. 		{
  422. 			public COORD dwSize;
  423. 			public COORD dwCursorPosition;
  424. 			public short wAttributes;
  425. 			public SMALL_RECT srWindow;
  426. 			public COORD dwMaximumWindowSize;
  427. 		}
  428.  
  429. 		[DllImport( "kernel32.dll", SetLastError = true )]
  430. 		private static extern bool ReadConsoleOutput( IntPtr hConsoleOutput, IntPtr lpBuffer, COORD dwBufferSize, COORD dwBufferCoord, ref SMALL_RECT lpReadRegion );
  431.  
  432. 		[DllImport( "kernel32.dll", SetLastError = true )]
  433. 		private static extern IntPtr GetStdHandle( int nStdHandle );
  434.  
  435. 	}
  436.  
  437. 	#endregion Read From Console Buffer
  438. }

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