(view source code of printany.cs as plain text)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Management;
using Microsoft.Win32;
namespace RobvanderWoude
{
class PrintAny
{
public static string progver = "3.04";
// Remember last file type, this may save lots of time searching for the associated Print(To) commands or verbs
public static string lasttype = string.Empty;
public static string lastprintcommand = string.Empty;
public static bool skipprintercheck = false;
public static bool skipverbs = false;
static int Main( string[] args )
{
try
{
#region Command Line Parsing
string filespec = string.Empty;
string printer = string.Empty;
string option = string.Empty;
if ( args.Length == 0 )
{
return ShowHelp( );
}
if ( args.Length > 4 )
{
return ShowHelp( "Too many command line arguments" );
}
foreach ( string arg in args )
{
if ( arg[0] == '/' )
{
if ( arg == "/?" )
{
return ShowHelp( );
}
else if ( arg.ToUpper( ) == "/NP" )
{
if ( skipprintercheck )
{
return ShowHelp( "Duplicate command line switch /NP" );
}
skipprintercheck = true;
}
else if ( arg.ToUpper( ) == "/NV" )
{
if ( skipverbs )
{
return ShowHelp( "Duplicate command line switch /NV" );
}
skipverbs = true;
}
else
{
return ShowHelp( "Invalid command line switch {0}", arg );
}
}
else if ( string.IsNullOrEmpty( filespec ) )
{
filespec = arg;
}
else if ( string.IsNullOrEmpty( printer ) )
{
printer = arg;
}
else
{
return ShowHelp( "Invalid command line argument \"{0}\"", arg );
}
}
if ( !string.IsNullOrWhiteSpace( printer ) && !PrinterExists( printer ) )
{
return ShowHelp( "Printer not found: \"{0}\"", printer );
}
#endregion
// Use the current directory if no directory was specified
if ( filespec.IndexOf( '\\' ) == -1 )
{
filespec = Path.Combine( Directory.GetCurrentDirectory( ), filespec );
}
// Get a list of all files in the specified directory
string[] files = Directory.GetFiles( Path.GetDirectoryName( filespec ), Path.GetFileName( filespec ) );
// Iterate through the list of all files . . .*/
foreach ( string file in files )
{
PrintFile( file, printer );
}
return 0;
}
catch ( Exception e )
{
return ShowHelp( e.Message );
}
}
public static int ExecutePrintCommand( string printcommand )
{
try
{
string command = string.Empty;
string arguments = string.Empty;
if ( printcommand.StartsWith( "\"" ) )
{
// Strip leading doublequote from command
command = printcommand.Substring( 1 );
// Arguments are everything following trailing doublequote of command
arguments = command.Substring( command.IndexOf( '"' ) + 1 );
// Strip trailing doublequote from command
command = command.Substring( 0, command.IndexOf( '"' ) );
}
else
{
// Command is first "word" of string
command = printcommand.Substring( 0, printcommand.IndexOf( ' ' ) );
// Arguments is the rest of the string
arguments = printcommand.Substring( printcommand.IndexOf( ' ' ) + 1 );
}
ProcessStartInfo prog = new ProcessStartInfo( command );
prog.Arguments = arguments;
prog.CreateNoWindow = true;
prog.UseShellExecute = true;
Process proc = new Process( );
proc.StartInfo = prog;
proc.Start( );
proc.CloseMainWindow( );
proc.Close( );
Console.WriteLine( printcommand );
return 0;
}
catch ( Exception e )
{
return ShowHelp( e.Message );
}
}
// Search the registry for the required Print(To) command
public static string GetRegPrintCommand( string file, string printer )
{
string ext = Path.GetExtension( file );
RegistryKey hkcrext = Registry.ClassesRoot.OpenSubKey( ext );
string ftype = hkcrext.GetValue( "" ).ToString( );
RegistryKey curver = Registry.ClassesRoot.OpenSubKey( ftype + "\\CurVer" );
if ( curver != null )
{
ftype = curver.GetValue( "" ).ToString( );
}
string printcmd = string.Empty;
RegistryKey hkcrprint = Registry.ClassesRoot.OpenSubKey( ftype + "\\shell\\Print\\command" );
if ( hkcrprint != null )
{
printcmd = hkcrprint.GetValue( "" ).ToString( );
}
string printtocmd = string.Empty;
RegistryKey hkcrprintto = Registry.ClassesRoot.OpenSubKey( ftype + "\\shell\\Printto\\command" );
if ( hkcrprintto != null )
{
printtocmd = hkcrprintto.GetValue( "" ).ToString( );
}
try
{
hkcrext.Close( );
curver.Close( );
hkcrprint.Close( );
hkcrprintto.Close( );
}
catch { } // If a key cannot be closed, we'll just ignore it
if ( string.IsNullOrWhiteSpace( printer ) )
{
return printcmd;
}
else
{
return printtocmd;
}
}
public static bool PrinterExists( string printer )
{
if ( skipprintercheck )
{
return true;
}
string query = String.Format( "SELECT * FROM Win32_Printer WHERE Name='{0}'", printer.Replace( @"\", @"\\" ) );
ManagementObjectSearcher searcher = new ManagementObjectSearcher( "root\\CIMV2", query );
int found = searcher.Get( ).Count;
if ( found == 1 )
{
return true;
}
else
{
return false;
}
}
// Print a single specified file to the specified (or default) printer
public static int PrintFile( string file, string printer )
{
if ( !skipverbs )
{
// First we'll try to use the Print or PrintTo Verbs, if available
bool printverb = false;
bool printtoverb = false;
ProcessStartInfo fileinfo = new ProcessStartInfo( file );
fileinfo.UseShellExecute = true;
if ( fileinfo.Verbs.Length > 0 )
{
foreach ( string verb in fileinfo.Verbs )
{
if ( verb.ToLower( ) == "print" )
{
printverb = true;
}
if ( verb.ToLower( ) == "printto" )
{
printtoverb = true;
}
}
}
if ( string.IsNullOrWhiteSpace( printer ) )
{
if ( printverb )
{
fileinfo.Verb = "Print";
Process proc = new Process( );
proc.StartInfo = fileinfo;
proc.Start( );
Console.WriteLine( "Print \"{0}\"", file );
return 0;
}
}
else
{
if ( printtoverb )
{
fileinfo.Verb = "PrintTo";
fileinfo.Arguments = printer;
Process proc = new Process( );
proc.StartInfo = fileinfo;
proc.Start( );
Console.WriteLine( "PrintTo \"{0}\", \"{1}\"", file, printer );
return 0;
}
}
}
// If the required Verb is not available, we'll try it the old-fashioned
// way by reading the Print or PrintTo command from the registry
string printcmd = GetRegPrintCommand( file, printer );
// Now we have to substitute "%1" and "%2" in the Print(To) command withe the properly escaped and trimmed parameters
if ( printcmd.IndexOf( "%1" ) == -1 )
{
return ShowHelp( "Command line printing not available for file type " + Path.GetExtension( file ) );
}
printcmd = printcmd.Replace( "%1", "\"" + file + "\"" );
printcmd = printcmd.Replace( @"""""", @"""" );
if ( printcmd.IndexOf( "%2" ) == -1 )
{
if ( !string.IsNullOrWhiteSpace( printer ) )
{
return ShowHelp( "Printer cannot be specified for file type " + Path.GetExtension( file ) );
}
}
else
{
printcmd = printcmd.Replace( "%2", "\"" + printer + "\"" );
printcmd = printcmd.Replace( @"""""", @"""" );
}
printcmd = printcmd.Replace( "\"%3\"", "" );
printcmd = printcmd.Replace( "%3", "" );
printcmd = printcmd.Replace( "\"%4\"", "" );
printcmd = printcmd.Replace( "%4", "" );
return ExecutePrintCommand( printcmd );
}
public static int ShowHelp( params string[] errmsg )
{
/*
PrintAny.exe, Version 3.04
Print files using the registered Print(To) command or verb for the file types
Usage: PrintAny.exe filespec [ printer ] [ options ]
Where: filespec the file(s) to be printed (wildcards allowed)
printer the printer to be used
Options: /NP No Printer check: skip check for printer in WMI
(may be necessary for network printers)
/NV No Verb: force the program to find the Print(To) command
in the registry (may be necessary for some combinations
of file type and printer, e.g. PDFs on network printers)
Examples: PrintAny.exe "d:\some folder\some file.pdf"
PrintAny.exe "d:\some folder\some file.pdf" "Color Printer Sales Dept"
PrintAny.exe "d:\some folder\*.pdf" "\\server\printer" /NP /NV
Notes: Use doublequotes if the file and/or printer names contain spaces.
The Print(To) verb or command is displayed for each matching file.
Not all file types have registered Print(To) commands or verbs.
Written by Rob van der Woude
http://www.robvanderwoude.com
*/
if ( 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( );
}
Console.Error.WriteLine( );
Console.Error.WriteLine( "PrintAny.exe, Version {0}", progver );
Console.Error.WriteLine( "Print files using the registered Print(To) command or verb for the file types" );
Console.Error.WriteLine( );
Console.Error.Write( "Usage: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( "PrintAny.exe filespec [ printer ] [ options ]" );
Console.ResetColor( );
Console.Error.WriteLine( );
Console.Error.Write( "Where: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "filespec" );
Console.ResetColor( );
Console.Error.WriteLine( " the file(s) to be printed (wildcards allowed)" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " printer" );
Console.ResetColor( );
Console.Error.WriteLine( " the printer to be used" );
Console.Error.WriteLine( );
Console.Error.Write( "Options: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "/NP N" );
Console.ResetColor( );
Console.Error.Write( "o " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "P" );
Console.ResetColor( );
Console.Error.WriteLine( "rinter check: skip check for printer in WMI" );
Console.Error.WriteLine( " (may be necessary for network printers)" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /NV N" );
Console.ResetColor( );
Console.Error.Write( "o " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "V" );
Console.ResetColor( );
Console.Error.WriteLine( "erb: force the program to find the Print(To) command" );
Console.Error.WriteLine( " in the registry (may be necessary for some combinations" );
Console.Error.WriteLine( " of file type and printer, e.g. PDFs on network printers)" );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Examples: PrintAny.exe \"d:\\some folder\\some file.doc\"" );
Console.Error.WriteLine( " PrintAny.exe \"d:\\some folder\\some file.pdf\" \"Color Printer Sales\"" );
Console.Error.WriteLine( " PrintAny.exe \"d:\\some folder\\*.pdf\" \"\\\\server\\printer\" /NP /NV" );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Notes: Use doublequotes if the file and/or printer names contain spaces." );
Console.Error.WriteLine( " The Print(To) verb or command is displayed for each matching file." );
Console.Error.WriteLine( " Not all file types have registered Print(To) commands or verbs." );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Written by Rob van der Woude" );
Console.Error.WriteLine( "http://www.robvanderwoude.com" );
return 1;
}
}
}
page last modified: 2024-04-16; loaded in 0.0110 seconds