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
Related
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.
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.
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.
Is it possible to change the orientation on the printer when using the webbrowser control? I need to change it to landscape. If I need to change the printer defaults for the printer itself that would be ok to as I would just set them back after I was done. (That's what I currently have to do with printing to a non-default printer).
I currently use this to temporarealy set the default printer, then set it back when I'm done with my print job...
private string SetDefaultPrinter(string newDefaultPrinter)
{
//Get the list of configured printers:
string strQuery = "SELECT * FROM Win32_Printer";
string currentDefault = string.Empty;
System.Management.ObjectQuery oq = new System.Management.ObjectQuery(strQuery);
System.Management.ManagementObjectSearcher query1 = new System.Management.ManagementObjectSearcher(oq);
System.Management.ManagementObjectCollection queryCollection1 = query1.Get();
System.Management.ManagementObject newDefault = null;
foreach (System.Management.ManagementObject mo in queryCollection1)
{
System.Management.PropertyDataCollection pdc = mo.Properties;
if ((bool)mo["Default"])
{
currentDefault = mo["Name"].ToString().Trim();
if (newDefaultPrinter == null || newDefaultPrinter == string.Empty)
{
//Just need to know the default name
break;
}
}
else if (mo["Name"].ToString().Trim() == newDefaultPrinter)
{
//Save this for later
newDefault = mo;
}
}
//Reset the default printer
if (newDefault != null)
{
//Execute the method
System.Management.ManagementBaseObject outParams = newDefault.InvokeMethod("SetDefaultPrinter", null, null);
}
return currentDefault;
}
Anyone know how to change the orientation?
You can do this by using IE print templates. There are not too much documentation on this, but here below is another stack-overflow post that suggests some useful links on this regards, and it actually helped me a lot:
WebBrowser print settings
The most useful part was suggesting to view the standard IE print template by navigating to the below URL inside IE:
res://ieframe.dll/preview.dlg
And also you can view a related JavaScript file by navigating to the below URL inside IE:
res://ieframe.dll/preview.js
Those two files helped me a lot to understand what is going on in the background, and by changing the "Printer.orientation" value inside the "preview.js" file, I could successfully change the orientation of the printed HTML document.
//EDIT:
I was testing it wrong. The documentation referring to this registry key is for windows CE... So the correct answer is that it is not possible, as "explained" in the documentation: http://support.microsoft.com/kb/236777
A possible workaround is to rotate the whole page through css (transform:rotate(90deg)), but the relative position keeps being the old one, so for multiple pages is just a mess.
It is incredible that something so basic can't be done...
//OLD ANSWER:
I was looking for the same and finally found that you really can't change the printer settings (page orientation, header, footer, margins...) directly with the webbrowser component, the only way to do it is changing the registry key to set the default behaviour of internet explorer.
For the page orientation it would be:
Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true).SetValue("PageOrientation", 2);
You should keep the old value and restore it after printing.
I am making one application where user will print invoices which I am displaying using Crystal Report.
The user showed me his current application made using ForPro. In that application, under Printer Options form, one can see all the printers currently installed and the user could select default printer. When the invoice is made, the user presses the print button, then there is one dialog asking for no. of copies. When it's entered, the invoice gets printed directly, without any Print Dialog Box. If the user wants to change the printer again he/she will change it in the Printer Option form.
I want to know if similar thing is possible in Crystal Report and need guidance on how to approach for it.
Take a look at the ReportDocument.PrintToPrinter SAP Docs or MSDN Docs for how to specify the PrinterName and then Print using the ReportDocument object.
If you can try and get away from how the FoxPro app UI for printer selection. Instead use the standard print dialog box to select the printer.
You should note that if you don't set the PrinterName before sending the report to the printer it will use the default on the crystal file. Not to be confused with the user's OS default printer.
Here's an example of showing the PrintDialog settings some parameters using the SetParameterValue method and then sending the report document to a printer
// Note: untested
var dialog = new PrintDialog();
Nullable<bool> print = dialog.ShowDialog();
if (print.HasValue && print.Value)
{
var rd = new ReportDocument();
rd.Load("ReportFile.rpt");
rd.SetParameter("Parameter1", "abc");
rd.SetParameter("Parameter2", "foo");
rd.PrintOptions.PrinterName = dialog.PrinterSettings.PrinterName;
rd.PrintToPrinter(1, false, 0, 0);
}
The code above no longer works as advertised which has been admitted by SAP
You need to set the report document to an ISCDReportClientDocument and then print it. This is a more robust way of making sure the print job doesn't go to the default printer. The last two lines can be replaced with this code.
CrystalDecisions.ReportAppServer.Controllers.PrintReportOptions printReportOptions = new CrystalDecisions.ReportAppServer.Controllers.PrintReportOptions();
CrystalDecisions.ReportAppServer.Controllers.PrintOutputController printOutputController = new CrystalDecisions.ReportAppServer.Controllers.PrintOutputController();
CrystalDecisions.ReportAppServer.ClientDoc.ISCDReportClientDocument rptClientDoc;
rptClientDoc = cryRtp.ReportClientDocument;
printReportOptions.PrinterName = pDialog.PrinterSettings.PrinterName;
rptClientDoc.PrintOutputController.PrintReport(printReportOptions);
Here is another good link
http://mattruma.azurewebsites.net/?p=258