2010-06-04 11 views
5

PrintCapabilities printCapabilites = SelectedPrinter.GetPrintCapabilities(); IEnumerable pagesizeList = printCapabilites.PageMediaSizeCapability;GetPrintCapabilities gibt nicht alle Seitengrößen zurück

Der obige Code listet nicht alle Seitengrößen auf, die der Druckertreiber unterstützt, und das ist mein Problem.

Als Beispiel, wenn Sie den Microsoft XPS Druckertreiber verwenden, werden Sie feststellen, dass pagesizeList (oben) einige Seitengrößen fehlen. "Letter Small" ist eine der fehlenden Seitengrößen (MS Word wird diese Seitengröße jedoch erfolgreich auflisten).

Als schnell Kontrolle abgeladen ich die Druckerfunktionen, wie unten XML:

long gpCLen = _selectedPrinter.GetPrintCapabilitiesAsXml().Length; 
FileStream fs = File.OpenWrite(@"c:\test.txt"); 
MemoryStream ms = _selectedPrinter.GetPrintCapabilitiesAsXml(); 
byte[] b = new byte[gpCLen]; 
ms.Read(b, 0, (int)gpCLen); 
fs.Write(b, 0, (int)gpCLen); 
fs.Close(); 

Der PageMediaSize Knoten in der XML-Datei in der Tat alle Seitengrößen produziert hat, und die fehlenden.

Angezeigte Seiten scheinen ihren Anfang psk haben:

<psf:Option name="psk:ISOA4" constrained="psk:None"> 

aber nicht angezeigten Seiten zu haben scheinen:

<psf:Option name="ns0000:LETTERSMALL" constrained="psk:None"> 

nicht angezeigten Epson Druckertreiber Seiten sind ähnlich:

<psf:Option name="epns200:IndexCard5x8" constrained="psk:None"> 

Grundsätzlich wird eine Seite mit dem Namen 'psk' PageMediaSizeCapability angezeigt, aber wenn es hergestellt wird benutzerdefiniert, zB epns200, ns0000, wird nicht aufgelistet. Irgendwelche Ideen, warum und wie bitte? Die Knoten/Seiten sind da aber PageMediaSizeCapability gefällt mir nicht!

Vielen Dank im Voraus

EDIT:

Als MS Zustand ‚Ein PrintCapabilities Objekt ist ein einfach zu arbeits mit Darstellung einer bestimmten Art von XML-Dokument eines PrintCapabilities Dokument namens‘ Aber das Dokument hat mehr Informationen als das Objekt Full description

Antwort

3

Sie haben die Papiernamen speichern, die Sie von PrintCapabilities xml lesen, und die Verwendung es ein Printticket xml erstellen (Printticket einen Konstruktor hat, die einen XML-Stream akzeptiert), und Dann benutze das PrintTicket. Hier ist ein Beispiel von Printticket XML (ns0000: User0000000257 ist hte Namen einer benutzerdefinierten Papiergröße, die ich erstellt):

<psf:PrintTicket xmlns:psf="http://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      xmlns:psk="http://schemas.microsoft.com/windows/2003/08/printing/printschemakeywords" 
      xmlns:ns0000="http://schemas.microsoft.com/windows/printing/oemdriverpt/Samsung_CLP-310 Series/5.1.2600.2180/" version="1"> 
    <psf:Feature name="psk:PageMediaSize"> 
    <psf:Option name="ns0000:User0000000257"></psf:Option> 
    </psf:Feature> 
</psf:PrintTicket> 
+0

+1: das funktioniert und sollte als Antwort akzeptiert werden. –

1

Auch wenn dies war ein älterer Thread, war es hilfreich, in deutete uns in die richtige Richtung, wenn Wir mussten benutzerdefinierte Eigenschaften lesen und aktualisieren.

Der folgende Code wurde aus diesem Thema angepasst: XPS-Druck, Fachauswahl und InputBinCapability (InputBin) = Problem: http://www.windows-tech.info/14/29c7cf575646cb39.php. Die Antwort von Jo0815 unten hatte das meiste von dem, was Sie unten sehen, besonders die XPath-Ausdrücke, die uns in die richtige Richtung wiesen.

Aktualisieren Sie außerdem das PrintQueue.UserPrintTicket mit Ihren Änderungen, NICHT das DefaultPrintTicket.

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Printing; 
using System.Text; 
using System.Windows; 
using System.Xml; 

// Adapted 
// From: XPS Printing, Tray selection and InputBinCapability (InputBin) = Problem 
// Link: http://www.windows-tech.info/14/29c7cf575646cb39.php - last answer at bottom by Jo0815 

namespace WpfApplication1 
{ 
    public static class WpfPrinterUtilities 
    { 
     #region GetPrintQueues 

     /// <summary> 
     /// Gets a dictionary of print queues where Key = print queue name 
     /// and Value = the print queue object. 
     /// </summary> 
     /// <param name="printQueueTypes">EnumeratedPrintQueueTypes params array of the types of print queues being requested.</param> 
     /// <returns>Dictionary of requested print queues where Key = print queue name and Value = the print queue object itself.</returns> 
     public static Dictionary<string, PrintQueue> GetPrintQueues(params EnumeratedPrintQueueTypes[] printQueueTypes) 
     { 
      var server = new PrintServer(); 
      return server.GetPrintQueues(printQueueTypes).ToDictionary(pq => pq.ShareName != null ? pq.ShareName : pq.Name); 
     } 

     #endregion 

     #region GetInputBins 

     /// <summary> 
     /// Reads print queue configuration xml to retrieve the current list of input bins. 
     /// </summary> 
     /// <param name="printQueue">The print queue to query.</param> 
     /// <returns></returns> 
     public static Dictionary<string, string> GetInputBins(PrintQueue printQueue) 
     { 
      Dictionary<string, string> inputBins = new Dictionary<string, string>(); 

      // Get the print queue PrintCapabilities. 
      XmlDocument xmlDoc = null; 
      using (MemoryStream stream = printQueue.GetPrintCapabilitiesAsXml()) 
      { 
       // Read the JobInputBins out of the PrintCapabilities. 
       xmlDoc = new XmlDocument(); 
       xmlDoc.Load(stream); 
      } 

      // Create NamespaceManager and add PrintSchemaFrameWork-Namespace (should be on DocumentElement of the PrintTicket). 
      // Prefix: psf NameSpace: xmlDoc.DocumentElement.NamespaceURI = "http://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" 
      XmlNamespaceManager manager = new XmlNamespaceManager(xmlDoc.NameTable); 
      manager.AddNamespace(xmlDoc.DocumentElement.Prefix, xmlDoc.DocumentElement.NamespaceURI); 

      // Select all job input bins. 
      XmlNodeList nodeList = xmlDoc.SelectNodes("//psf:Feature[@name='psk:JobInputBin']/psf:Option/psf:Property", manager); 

      // Load the Dictionary with the bin values and names. The names will be used to modify the print ticket if necessary. 
      foreach (XmlNode node in nodeList) 
      { 
       inputBins.Add(node.LastChild.InnerText, node.ParentNode.Attributes[0].Value); 
      } 

      return inputBins; 
     } 

     #endregion 

     #region ModifyPrintTicket 

     /// <summary> 
     /// Modifes a print ticket xml after updating a feature value. 
     /// 
     /// Sample usage: 
     /// Get Dictionary with Inputbins by calling the other method 
     /// and get "value" for the desired inputbin you'd like to use... 
     /// ... 
     /// desiredTray is then something like "NS0000:SurpriseOption7" for example. 
     /// defaultPrintTicket is the (Default)PrintTicket you want to modify from the PrintQueue for example 
     /// PrintTicket myPrintTicket = WpfPrinterUtils.ModifyPrintTicket(defaultPrintTicket, "psk:JobInputBin", desiredTray); 
     /// </summary> 
     /// <param name="ticket"></param> 
     /// <param name="featureName"></param> 
     /// <param name="newValue"></param> 
     /// <param name="printQueueName">Optional - If provided, a file is created with the print ticket xml. Useful for debugging.</param> 
     /// <param name="folder">Optional - If provided, the path for a file is created with the print ticket xml. Defaults to c:\. Useful for debugging.</param> 
     /// <param name="displayMessage">Optional - True to display a dialog with changes. Defaults to false. Useful for debugging.</param> 
     /// <returns></returns> 
     public static PrintTicket ModifyPrintTicket(PrintTicket ticket, string featureName, string newValue, string printQueueName = null, string folder = null, bool displayMessage = false) 
     { 
      if (ticket == null) 
      { 
       throw new ArgumentNullException("ticket"); 
      } 

      // Read Xml of the PrintTicket xml. 
      XmlDocument xmlDoc = new XmlDocument(); 
      xmlDoc.Load(ticket.GetXmlStream()); 

      // Create NamespaceManager and add PrintSchemaFrameWork-Namespace hinzufugen (should be on DocumentElement of the PrintTicket). 
      // Prefix: psf NameSpace: xmlDoc.DocumentElement.NamespaceURI = "http://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" 
      XmlNamespaceManager manager = new XmlNamespaceManager(xmlDoc.NameTable); 
      manager.AddNamespace(xmlDoc.DocumentElement.Prefix, xmlDoc.DocumentElement.NamespaceURI); 

      // Search node with desired feature we're looking for and set newValue for it 
      string xpath = string.Format("//psf:Feature[@name='{0}']/psf:Option", featureName); 
      XmlNode node = xmlDoc.SelectSingleNode(xpath, manager); 
      if (node != null) 
      { 
       if (node.Attributes["name"].Value != newValue) 
       { 
        if (displayMessage) 
        { 
         System.Windows.MessageBox.Show(string.Format("OldValue: {0}, NewValue: {1}", node.Attributes["name"].Value, newValue), "Input Bin"); 
        } 
        node.Attributes["name"].Value = newValue; 
       } 
      } 

      // Create a new PrintTicket out of the XML. 
      PrintTicket modifiedPrintTicket = null; 
      using (MemoryStream stream = new MemoryStream()) 
      { 
       xmlDoc.Save(stream); 
       stream.Position = 0; 
       modifiedPrintTicket = new PrintTicket(stream); 
      } 

      // For testing purpose save the print ticket to a file. 
      if (!string.IsNullOrWhiteSpace(printQueueName)) 
      { 
       if (string.IsNullOrWhiteSpace(folder)) 
       { 
        folder = "c:\\"; 
       } 
       // Colons are not valid in a file name. 
       newValue = newValue.Replace(':', ';'); 
       printQueueName = string.Format("{0} PrintTicket {1}.xml", Path.Combine(folder, printQueueName), newValue); 
       if (File.Exists(printQueueName)) 
       { 
        File.Delete(printQueueName); 
       } 
       if (!Directory.Exists(Path.GetDirectoryName(printQueueName))) 
       { 
        Directory.CreateDirectory(Path.GetDirectoryName(printQueueName)); 
       } 
       using (FileStream stream = new FileStream(printQueueName, FileMode.CreateNew, FileAccess.ReadWrite)) 
       { 
        modifiedPrintTicket.GetXmlStream().WriteTo(stream); 
       } 
      } 

      return modifiedPrintTicket; 
     } 

     #endregion 
    } 
} 
Verwandte Themen