PrintQueue::GetPrintCapabilitiesAsXml() does not initialize until the property DefaultPrintTicket() is invoked - c#

This sounds like an initialization problem on certain printers.
Here's the use-case:
// Get the default printer.
PrintQueue printer = LocalPrintServer.GetDefaultPrintQueue();
// Get the printer properties as XML from the system and populate the instance of PrinterProperties.
Stream printerDocmentStream = printer.GetPrintCapabilitiesAsXml();
From the XML document retrieved, the XML element PageMediaSize does not hold comprehensive list of supported page sizes for certain class of printers.
However, when XML document is retrieved after a call to the DefaultPrintTicket, the XML element PageMediaSize returns all the supported page sizes. The code is as follows:
// This call initializes the printer properties. <--------------------
PrintTicket dummyPrintTicket = printer.DefaultPrintTicket; <-----------
// Get the default printer.
PrintQueue printer = LocalPrintServer.GetDefaultPrintQueue();
// Get the printer properties as XML from the system and populate the instance of PrinterProperties.
Stream printerDocmentStream = printer.GetPrintCapabilitiesAsXml();
I am guessing that a call to DefaultPrintTicket initializes the instance of PrintQueue, there is an initialized method but it is protected.
Is this bug ? Is anyone seeing a similar behavior ?
P.S: The printer I am using is: HP Designjet T7100ps HPGL2

This is confirmed Bug. If GetPrintCapablitiesAsXml() is the first method to be called by an instance of PrintQueue, the returned XML is does not enumerate all the properties of the printer correctly.

Related

Set file name in "Microsoft Print to PDF" printer using System.Print

I want to save an IDocumentPaginatorSource, e.g. FixedDocument or XpsDocument, as a PDF by using the virtual printer "Microsoft Print to PDF":
var printServer = new System.Printing.PrintServer();
var queue = printServer.GetPrintQueue("Microsoft Print to PDF");
var writer = System.Printing.PrintQueue.CreateXpsDocumentWriter(queue);
writer.Write(Document.DocumentPaginator); // Document = IDocumentPaginatorSource
This works, but makes the printer open a file save dialog. I would like to set the file name programmatically and either suppress this dialog completely or at least set the initial file name in the dialog. Is this possible?
I know, that this can be done when using System.Drawing.Printing.PrintDocument by setting PrinterSettings.PrintFileName and PrinterSettings.PrintToFile (see 1, 2), but this is the old printing framework that does not support IDocumentPaginatorSource.
I checked all classes in the System.Printing namespace but did not find any way to set these two settings. Maybe it's possible to retrofit these seetings into the PrintTicket by extending the print schema? If so, how exactly would you do that?
I don't have a solution using the "Microsoft Print to PDF printer", but if you switched to using the Win2PDF printer driver you can set the file name programatically through the registry. To do this, see the documentation for the "PDFFileName" or "PDFDefaultFileName" registry settings.

Printdocument ignoring printer and tray settings

I have a windows service that prints pdf files once it receives a request. It uses PrintDocument, but for some printers it seems to ignore printer and tray settings I give it in my code.
Currently every printer has a few trays which are all installed as seperate queues. For some printers I can just set the PrinterName property (of PrintDocument) to the name of the queue and it works fine. However a couple of printers seem to ignore this. I also tried setting the papersource, but this seems to alway be ignored.
Here's the code used to print:
PrintDocument pd = new PrintDocument();
pd.PrinterSettings.PrinterName = printer; //printer is send to the service along with the request
pd.Print();
Again: this works for some printers, but not for all.
I also tried using Papersource like this:
pd.PrinterSettings.DefaultPageSettings.PaperSource.SourceName =
pd.PrinterSettings.PaperSources[tray - 1].SourceName; //Tray is also send with the request
and like this:
pd.PrinterSettings.DefaultPageSettings.PaperSource =
pd.PrinterSettings.PaperSources[tray - 1];
What am I doing wrong here?
EDIT: The pdf file always has content in it, so it can't be empty.
I changed my code to use PrintQueue instead (https://msdn.microsoft.com/en-us/library/system.printing.printqueue(v=vs.110).aspx). This seems to work well, since I can directly call the queues instead of the printer.

Unable to print PDF with Staple mode in C#

I am using PrintTicket object (printTicket.Stapling = Stapling.StapleTopLeft;) and using PrintQueue.Addjob method in System.printing to enable stapling option. Stapling is working fine with XPS document, but not working with PDF documents. Here is my code:
PrintTicket printTicket = printQueue.DefaultPrintTicket;
printTicket.Stapling = Stapling.StapleTopLeft;
printQueue.CurrentJobSettings.CurrentPrintTicket = printTicket;
printQueue.AddJob("TEST", "C:\\TEST.XPS", false, printTicket);
TEST.XPS is printing and stapling, but changing the file to PDF is not working.
If you look at the MDSN for that AddJob method it specifically says it for XPS documents only.
https://msdn.microsoft.com/en-us/library/jj205516%28v=vs.110%29.aspx
Inserts a new print job for an XML Paper Specification (XPS) Document
into the queue, gives it the specified name and settings, and
specifies whether or not it should be validated.

copyIntoItems() not assigning Title to the document in document library

I am trying to assign a Title to already existing document in the document library using copyIntoItems().
I am giving input as: Title,ID,FileName
The method is giving the following error:
Value does not fall within expected range
But if I provide SourceFullPath,Title,ID,FileName as the input, then it works fine. I don't want to provide <SourceFullPath>D:\test.txt</SourceFullPath> here.
Can someone suggest how I can use copyIntoItems without providing the SourceFullPath?
To assign the field information you must set at least DisplayName, Type and value to Fields parameter from CopyIntoItems method (http://msdn.microsoft.com/en-us/library/copy.fieldinformation_members%28v=office.12%29.aspx):
fieldInfo = new Sharepoint.FieldInformation();
fieldInfo.Id = Microsoft.SharePoint.SPBuiltInFieldId.Title;
fieldInfo.Value = "New title";
fieldInfo.DisplayName = "Title";
fieldInfo.Type = YetAnotherMigrationTool.Library.SP2007.Sharepoint.FieldType.Text;
fieldInfo.InternalName = "Title";
fields.Add(fieldInfo);
For a full example how to upload a document to SharePoint using CopyIntoItems method see here
Note: The absolute source URL of the document to be copied is a mandatory parameter.

how to set to default printer

How do you set PrintDocument.PrinterSettings.PrinterName to be the default printer?
I am not talking about setting the default printer in the operating system. Rather, I am talking about setting the PrintDocument object so that it prints to the default printer.
If I'm understanding correctly, you would like to be able to reset the PrinterName to the default printer (1) without recreating your PrintDocument and, (2) after you may have already set it to something else or, (3) when the default printer may have changed since the time when the PrintDocument was first created (so you can't rely on simply caching the defaults provided by the target instance after initial construction).
In this case a search for "C# get default printer name" turns up the following excellent post on stackoverflow: What's the best way to get the default printer in .NET
Building on the sample provided in top voted answer and considering that you will already have a pre-existing PrintDocument with some settings you don't want to recreate; you could create a new instance of the PrinterSettings class, for the sole purposes of copying out the default printer name.
// Create a new instance of the PrinterSettings class, which
// we will only use to fetch the default printer name
System.Drawing.Printing.PrinterSettings newSettings = new System.Drawing.Printing.PrinterSettings();
// Copy the default printer name from our newSettings instance into our
// pre-existing PrintDocument instance without recreating the
// PrintDocument or the PrintDocument's PrinterSettings classes.
existingPrintDocumentInstance.PrinterSettings.PrinterName = newSettings.PrinterName;
You can review the linked post for alternative techniques such as WMI, but I think this is the simplest and cleanest solution for you.
It is automatically initialized to the default printer. Do nothing.
GetDefaultPrinter()
{ PrinterSettings settings = new PrinterSettings();
foreach (string printer in PrinterSettings.InstalledPrinters)
{ settings.PrinterName = printer;
if (settings.IsDefaultPrinter)
return printer;
}
return string.Empty;
}
I assume you have set the default printer at the OS level. When you initiate a print from your code, it by defualt goes to Default Printer. You don't have to set it explicitly.
This happend for each print request. I mean if you have set the print to another printer and now you want to go to the default printer, just remove the explicit setting and it will again go to the default printer.
HTH
Correct me if I am wrong but you are looking to get the name of the default printer and then setting PrintDocument.PrinterSettings.PrinterName to this.
When you use PrintDocument.PrinterSettings.PrinterName this uses the default printer by default.
By default you would be landing on default printer if you do not set anything on your object. Here is the official source you were looking for: MSDN Link to PrintDocument Class
Mark the sentence written just above the example: "The following code example prints the file named C:\My Documents\MyFile.txt on the default printer."
HTH

Categories

Resources