Microsoft Windows?打印架构
包括灵活且可扩展的?PrintCapabilities?和?PrintTicket?元素。 前一个元素逐条列出打印设备的功能,后一个指定设备应如何使用这些功能来处理特定文档序列、单个文档或单个页面。
支持打印的应用程序的典型任务序列应如下。
确定打印机的功能。
配置一个?PrintTicket,用来使用这些功能。
验证?PrintTicket。
本文介绍如何执行此操作。
在下面的简单示例中,我们仅对打印机是否支持双工(即双面打印)感兴趣。 主要步骤如下。
使用?GetPrintCapabilities?方法获取?PrintCapabilities?对象。
测试是否有你需要的功能。 在下面的示例中,我们测试?PrintCapabilities?对象的?DuplexingCapability?属性是否有以下功能:在一张纸的两面进行打印,并沿纸张的长边“翻页”。?DuplexingCapability?是集合,因此我们使用?Contains
?的?ReadOnlyCollection<T>?方法。
?备注
此步骤不是绝对必需的。 下面使用的?MergeAndValidatePrintTicket?方法将根据打印机的功能检查?PrintTicket?中的每个请求。 如果打印机不支持请求的功能,打印机驱动程序将在方法返回的?PrintTicket?中用备用请求作为替代。
如果打印机支持双工,示例代码创建要求双工的?PrintTicket。 但应用程序不指定?PrintTicket?元素中可用的每个可能的打印机设置。 那样做会在程序员和程序时间两个方面产生浪费。 相反,代码只设置双工请求,然后将此?PrintTicket?与已完全配置且验证的现有?PrintTicket?合并,在本例中为用户的默认?PrintTicket。
相应的,该示例调用?MergeAndValidatePrintTicket?方法将新的最小?PrintTicket?与用户的默认?PrintTicket?合并。 这会返回一个?ValidationResult?属性,它包含?PrintTicket?作为其属性之一。
然后,该示例测试新的?PrintTicket?请求双工。 如果是这样,该示例接下来将它设为用户的新的默认打印工单。 如果漏掉了上面的步骤 2,并且打印机不支持沿长边双工,测试会得出?false
。 (请参阅上面的说明。)
最后一个重要步骤是使用?Commit?方法将更改提交到?PrintQueue?的?UserPrintTicket?属性。
/// <summary>
/// Changes the user-default PrintTicket setting of the specified print queue.
/// </summary>
/// <param name="queue">the printer whose user-default PrintTicket setting needs to be changed</param>
static private void ChangePrintTicketSetting(PrintQueue queue)
{
//
// Obtain the printer's PrintCapabilities so we can determine whether or not
// duplexing printing is supported by the printer.
//
PrintCapabilities printcap = queue.GetPrintCapabilities();
//
// The printer's duplexing capability is returned as a read-only collection of duplexing options
// that can be supported by the printer. If the collection returned contains the duplexing
// option we want to set, it means the duplexing option we want to set is supported by the printer,
// so we can make the user-default PrintTicket setting change.
//
if (printcap.DuplexingCapability.Contains(Duplexing.TwoSidedLongEdge))
{
//
// To change the user-default PrintTicket, we can first create a delta PrintTicket with
// the new duplexing setting.
//
PrintTicket deltaTicket = new PrintTicket();
deltaTicket.Duplexing = Duplexing.TwoSidedLongEdge;
//
// Then merge the delta PrintTicket onto the printer's current user-default PrintTicket,
// and validate the merged PrintTicket to get the new PrintTicket we want to set as the
// printer's new user-default PrintTicket.
//
ValidationResult result = queue.MergeAndValidatePrintTicket(queue.UserPrintTicket, deltaTicket);
//
// The duplexing option we want to set could be constrained by other PrintTicket settings
// or device settings. We can check the validated merged PrintTicket to see whether the
// the validation process has kept the duplexing option we want to set unchanged.
//
if (result.ValidatedPrintTicket.Duplexing == Duplexing.TwoSidedLongEdge)
{
//
// Set the printer's user-default PrintTicket and commit the set operation.
//
queue.UserPrintTicket = result.ValidatedPrintTicket;
queue.Commit();
Console.WriteLine("PrintTicket new duplexing setting is set on '{0}'.", queue.FullName);
}
else
{
//
// The duplexing option we want to set has been changed by the validation process
// when it was resolving setting constraints.
//
Console.WriteLine("PrintTicket new duplexing setting is constrained on '{0}'.", queue.FullName);
}
}
else
{
//
// If the printer doesn't support the duplexing option we want to set, skip it.
//
Console.WriteLine("PrintTicket new duplexing setting is not supported on '{0}'.", queue.FullName);
}
}
这样,你就能快速地测试此示例,下面显示了该示例的其余部分。 创建项目和命名空间,然后将本文中的两个代码片段粘贴到命名空间块中。
/// <summary>
/// Displays the correct command line syntax to run this sample program.
/// </summary>
static private void DisplayUsage()
{
Console.WriteLine();
Console.WriteLine("Usage #1: printticket.exe -l \"<printer_name>\"");
Console.WriteLine(" Run program on the specified local printer");
Console.WriteLine();
Console.WriteLine(" Quotation marks may be omitted if there are no spaces in printer_name.");
Console.WriteLine();
Console.WriteLine("Usage #2: printticket.exe -r \"\\\\<server_name>\\<printer_name>\"");
Console.WriteLine(" Run program on the specified network printer");
Console.WriteLine();
Console.WriteLine(" Quotation marks may be omitted if there are no spaces in server_name or printer_name.");
Console.WriteLine();
Console.WriteLine("Usage #3: printticket.exe -a");
Console.WriteLine(" Run program on all installed printers");
Console.WriteLine();
}
[STAThread]
static public void Main(string[] args)
{
try
{
if ((args.Length == 1) && (args[0] == "-a"))
{
//
// Change PrintTicket setting for all local and network printer connections.
//
LocalPrintServer server = new LocalPrintServer();
EnumeratedPrintQueueTypes[] queue_types = {EnumeratedPrintQueueTypes.Local,
EnumeratedPrintQueueTypes.Connections};
//
// Enumerate through all the printers.
//
foreach (PrintQueue queue in server.GetPrintQueues(queue_types))
{
//
// Change the PrintTicket setting queue by queue.
//
ChangePrintTicketSetting(queue);
}
}//end if -a
else if ((args.Length == 2) && (args[0] == "-l"))
{
//
// Change PrintTicket setting only for the specified local printer.
//
LocalPrintServer server = new LocalPrintServer();
PrintQueue queue = new PrintQueue(server, args[1]);
ChangePrintTicketSetting(queue);
}//end if -l
else if ((args.Length == 2) && (args[0] == "-r"))
{
//
// Change PrintTicket setting only for the specified remote printer.
//
String serverName = args[1].Remove(args[1].LastIndexOf(@"\"));
String printerName = args[1].Remove(0, args[1].LastIndexOf(@"\")+1);
PrintServer ps = new PrintServer(serverName);
PrintQueue queue = new PrintQueue(ps, printerName);
ChangePrintTicketSetting(queue);
}//end if -r
else
{
//
// Unrecognized command line.
// Show user the correct command line syntax to run this sample program.
//
DisplayUsage();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
//
// Show inner exception information if it's provided.
//
if (e.InnerException != null)
{
Console.WriteLine("--- Inner Exception ---");
Console.WriteLine(e.InnerException.Message);
Console.WriteLine(e.InnerException.StackTrace);
}
}
finally
{
Console.WriteLine("Press Return to continue...");
Console.ReadLine();
}
}//end Main