// Author : Rob van der Woude // Date : 2011-04-01 #undef DEBUG using System; using System.Management; namespace RobvanderWoude { public class CommandLinePrintingControl { public static int Main( string[] args ) { try { bool ActionSet = false; bool ActFlush = false; bool ActList = false; bool ActPause = false; bool ActResume = false; bool DoAct = true; string Action = ""; bool OptionSet = false; bool Quiet = false; bool PrinterSet = false; bool UseAllPrn = false; bool UseDefault = false; string Printer = ""; UInt32 Status = 0; UInt32 Counter = 0; #region command line parsing if ( args.Length == 0 ) { throw new Exception( "" ); } if ( args.Length > 3 ) { throw new Exception( "Too many command line arguments" ); } foreach ( string arg in args ) { switch ( arg.ToUpper( ) ) { case "/?": case "-H": case "/HELP": case "-HELP": case "--HELP": throw new Exception( string.Empty ); case "/A": case "/ALL": if ( PrinterSet ) { if ( ActList ) { throw new Exception( "Do not specify printer(s) whith /List switch" ); } else { throw new Exception( "Multiple printer arguments not allowed" ); } } UseAllPrn = true; UseDefault = false; PrinterSet = true; break; case "/D": case "/DEFAULT": if ( PrinterSet ) { if ( ActList ) { throw new Exception( "Do not specify printer(s) whith /List switch" ); } else { throw new Exception( "Multiple printer arguments not allowed" ); } } UseDefault = true; UseAllPrn = false; PrinterSet = true; break; case "/F": case "/FLUSH": if ( ActionSet ) { throw new Exception( "Multiple action arguments not allowed" ); } Action = "CancelAllJobs"; ActionSet = true; ActFlush = true; break; case "/L": case "/LIST": if ( ActList ) { throw new Exception( "Duplicate /List arguments not allowed" ); } if ( ActionSet ) { throw new Exception( "Do not combine /List with other action arguments" ); } if ( PrinterSet ) { throw new Exception( "Do not specify printer(s) whith /List switch" ); } UseAllPrn = true; UseDefault = false; PrinterSet = true; Action = "List"; ActList = true; ActionSet = true; break; case "/P": case "/PAUSE": if ( ActionSet ) { throw new Exception( "Multiple action arguments not allowed" ); } Action = "Pause"; ActPause = true; ActionSet = true; break; case "/Q": case "/QUIET": if ( OptionSet ) { throw new Exception( "Multiple option arguments not allowed" ); } if ( ActList ) { throw new Exception( "Do not combine /List and /Quiet switches, it would return empty result" ); } Quiet = true; OptionSet = true; break; case "/R": case "/RESUME": if ( ActionSet ) { throw new Exception( "Multiple action arguments not allowed" ); } Action = "Resume"; ActResume = true; ActionSet = true; break; case "/V": case "/VERBOSE": if ( OptionSet ) { throw new Exception( "Multiple option arguments not allowed" ); } Quiet = false; OptionSet = true; break; default: if ( arg.Contains( "/" ) ) { throw new Exception( "Invalid command line argument: " + arg ); } else { if ( PrinterSet ) { if ( ActList ) { throw new Exception( "Do not specify printer(s) whit /List argument" ); } else { throw new Exception( "Multiple printer arguments not allowed" ); } } Printer = arg; UseAllPrn = false; UseDefault = false; PrinterSet = true; } break; } } if ( !PrinterSet ) { throw new Exception( "Printer not specified - specify name or use /All or /Default" ); } if ( !ActionSet ) { throw new Exception( "No action specified - use /List, /Pause, /Resume or /Flush" ); } if (!OptionSet && args.Length == 3) { throw new Exception( "Invalid command line argument(s)" ); } // For debugging command line parsing #if DEBUG Console.WriteLine( "--Command line debugging info:" ); Console.WriteLine( ); if ( UseDefault ) { Console.WriteLine( " Printer : Default" ); } else if ( UseAllPrn ) { Console.WriteLine( " Printer : All" ); } else { Console.WriteLine( " Printer : {0}", Printer ); } if ( ActFlush ) { Console.WriteLine( " Action : Flush printjobs" ); } if ( ActPause ) { Console.WriteLine( " Action : Pause printing" ); } if ( ActResume ) { Console.WriteLine( " Action : Resume printing" ); } if ( ActList ) { Console.WriteLine( " Action : List printers" ); } if ( Quiet ) { Console.WriteLine( " Display : Quiet" ); } else { Console.WriteLine( " Display : Verbose" ); } Console.WriteLine( ); Console.WriteLine( "--End of debugging info." ); Console.WriteLine( ); #endif #endregion command line parsing // Connect to WMI printer object string Query1; string Query2; string Query3; if ( UseDefault ) { Query1 = "SELECT * FROM Win32_Printer WHERE Default='TRUE'"; } else if ( UseAllPrn ) { Query1 = "SELECT * FROM Win32_Printer"; } else { Query1 = "SELECT * FROM Win32_Printer WHERE DeviceID='" + Printer + "'"; } ManagementObjectSearcher Searcher1 = new ManagementObjectSearcher( "root\\CIMV2", Query1 ); foreach ( ManagementObject queryObj in Searcher1.Get( ) ) { Counter += 1; Printer = (string)queryObj["DeviceID"]; Status = Convert.ToUInt32( queryObj["ExtendedPrinterStatus"] ); Query2 = "SELECT * FROM Win32_PrintJob WHERE Name LIKE '" + Printer + ", %'"; ManagementObjectSearcher Searcher2 = new ManagementObjectSearcher( "root\\CIMV2", Query2 ); UInt32 jobs = Convert.ToUInt32( Searcher2.Get( ).Count ); if ( ( jobs > 0 && ActFlush ) || ( ActPause && Status != 8 ) || ( ActResume && Status != 2 ) ) { DoAct = true; } else { DoAct = false; } if ( !Quiet ) { Console.WriteLine( "Printer : {0}", Printer ); Console.WriteLine( "Printjobs : {0}", jobs ); Console.WriteLine( "Status : {0}", (WMIPrinterStatus)Status ); if ( DoAct ) { if ( ActFlush ) { Console.WriteLine( "Flush printjobs . . ." ); } else { Console.WriteLine( Action + " printing . . ." ); } } Console.WriteLine( ); } if ( DoAct ) { WMIActionResult result = (WMIActionResult)Convert.ToUInt32( queryObj.InvokeMethod( Action, null ) ); if ( !Quiet ) { if ( ActFlush ) { jobs = Convert.ToUInt32( Searcher2.Get( ).Count ); Console.WriteLine( "Printjobs : {0}", jobs ); } else { Query3 = "SELECT * FROM Win32_Printer WHERE Name LIKE '" + Printer + ", %'"; ManagementObjectSearcher searcher3 = new ManagementObjectSearcher( "root\\CIMV2", Query3 ); foreach ( ManagementObject queryObj2 in Searcher1.Get( ) ) { Status = Convert.ToUInt32( queryObj2["ExtendedPrinterStatus"] ); Console.WriteLine( "Status : {0}", (WMIPrinterStatus)Status ); } } Console.WriteLine( ); } } } if ( Counter == 0 ) { throw new Exception( "No matching printer found, use /List for a list of valid printer names" ); } return 0; } catch ( Exception e ) { /* Printing.exe, Version 2.25 for Windows XP or later Pause or resume printing, or flush all queued printjobs on the specified printer(s), or list all printers, their status and number of printjobs Usage: Printing.exe printer action [ option ] or: Printing.exe /List Where: "printer" is either /All, /Default or a printer name "action" is either /Pause, /Resume or /Flush "option" is either /Quiet or /Verbose (default) Notes: Use doublequotes if the printer name contains spaces. Do not specify printer(s) nor use /Quiet with /List switch. Switches may be abbreviated, e.g. /D instead of /Default. This program may work on Windows 2000 except /Default switch. Credits: PrinterInfo source code by Bas van der Woude. Written by Rob van der Woude http://www.robvanderwoude.com */ if ( e.Message != string.Empty ) { Console.Error.WriteLine( ); Console.ForegroundColor = ConsoleColor.Red; Console.Error.Write( "ERROR: " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.WriteLine( e.Message ); Console.ResetColor( ); } Console.Error.WriteLine( ); Console.Error.WriteLine( "Printing.exe, Version 2.25 for Windows XP or later" ); Console.Error.WriteLine( "Pause or resume printing, or flush all queued printjobs on the specified" ); Console.Error.WriteLine( "printer(s), or list all printers, their status and number of printjobs" ); Console.Error.WriteLine(); Console.Error.Write( "Usage: " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.WriteLine( "Printing.exe printer action [ option ]" ); Console.ResetColor( ); Console.Error.Write( " or: " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( "Printing.exe /L" ); Console.ResetColor( ); Console.Error.WriteLine( "ist" ); Console.Error.WriteLine( ); Console.Error.Write( "Where: " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( "\"printer\"" ); Console.ResetColor( ); Console.Error.Write( " is either " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( "/A" ); Console.ResetColor( ); Console.Error.Write( "ll, " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( "/D" ); Console.ResetColor( ); Console.Error.WriteLine( "efault or a printer name" ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( " \"action\"" ); Console.ResetColor( ); Console.Error.Write( " is either " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( "/P" ); Console.ResetColor( ); Console.Error.Write( "ause, " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( "/R" ); Console.ResetColor( ); Console.Error.Write( "esume or " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( "/F" ); Console.ResetColor( ); Console.Error.WriteLine( "lush" ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( " \"option\"" ); Console.ResetColor( ); Console.Error.Write( " is either " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( "/Q" ); Console.ResetColor( ); Console.Error.Write( "uiet or " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( "/V" ); Console.ResetColor( ); Console.Error.WriteLine( "erbose (default)" ); Console.Error.WriteLine( ); Console.Error.WriteLine( "Notes: Use doublequotes if the printer name contains spaces." ); Console.Error.Write( " Do not specify printer(s) nor use " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( "/Q" ); Console.ResetColor( ); Console.Error.Write( "uiet with " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( "/L" ); Console.ResetColor( ); Console.Error.WriteLine( "ist switch." ); Console.Error.Write( " Switches may be abbreviated, e.g. " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( "/D" ); Console.ResetColor( ); Console.Error.Write( " instead of " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( "/D" ); Console.ResetColor( ); Console.Error.WriteLine( "efault." ); Console.Error.Write( " This program " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( "may" ); Console.ResetColor( ); Console.Error.Write( " work on Windows 2000 except " ); Console.ForegroundColor = ConsoleColor.White; Console.Error.Write( "/D" ); Console.ResetColor( ); Console.Error.WriteLine( "efault switch." ); Console.Error.WriteLine( ); Console.Error.WriteLine( "Credits: PrinterInfo source code by Bas van der Woude." ); Console.Error.WriteLine( ); Console.Error.WriteLine( "Written by Rob van der Woude"); Console.Error.WriteLine( "http://www.robvanderwoude.com"); return 1; } } } }