How to get the printer status in WPF? - c#

Here is how I print my flowdocument:
PrintDialog pd = new PrintDialog();
LocalPrintServer local = new LocalPrintServer();
PrintQueue pq = local.DefaultPrintQueue;//GetPrintQueue("[Printer Name]"); //e.g. local.GetPrintQueue("Microsoft XPS Document Writer");
pd.PrintQueue = pq;
PrintTicket pt = pq.DefaultPrintTicket;
pt.PageMediaSize = new PageMediaSize(PageMediaSizeName.ISOA5);// or we can specify the custom size(width, height) here
pd.PrintTicket = pt;
pt.PageBorderless = PageBorderless.Borderless;
pt.PageOrientation = PageOrientation.ReversePortrait;
PrintCapabilities capabilities = pd.PrintQueue.GetPrintCapabilities(pd.PrintTicket);
double sizeWidth = capabilities.PageImageableArea.ExtentWidth;
double sizeHeight = capabilities.PageImageableArea.ExtentHeight;
var fd = new FlowDocument();
DocumentPaginator sd = ((IDocumentPaginatorSource)fd).DocumentPaginator;
sd.PageSize = new Size(sizeWidth + 20, sizeHeight);
pd.PrintDocument(sd, "My Doc");
// GET THE PRINTER STATUS IN MESSAGE BOX HERE..
MessageBox.Show(printerStatus()); // printerStatus() is a pseudo method to retrieve the status of the printer.
How can i get the current status of the printer so that it will output, Printing, Out of Paper, Paper jam, Printer Offline, etc message????
Upon searching, I came across this page: http://msdn.microsoft.com/en-us/library/system.printing.printqueuestatus.aspx
However I have no clue on it's usage. Can you any body help me to get in with it?
This print process is being running in a STA thread.

you can check like this
using System.Management;
class PrinterOffline
{
private static void Main(string[] args)
{
// Set management scope
ManagementScope scope = new ManagementScope("\\root\\cimv2");
scope.Connect();
// Select Printers from WMI Object Collections
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Printer");
string printerName = "";
foreach (ManagementObject printer in searcher.Get())
{
printerName = printer("Name").ToString().ToLower();
if (printerName.Equals("Name_Of_Printer"))
{
Console.WriteLine("Printer = " + printer("Name"));
if (printer("WorkOffline").ToString().ToLower().Equals("true"))
{
// printer is offline by user
Console.WriteLine("Your Plug-N-Play printer is not connected.");
}
else
{
// printer is not offline
Console.WriteLine("Your Plug-N-Play printer is connected.");
}
}
}
}
}
pls go through this link for more information on status of the printer

Related

How to change the following printer properties, SpoolEnabled & KeepPrintedJobs, using C#?

I'm trying to change the printer properties, SpoolEnabled & KeepPrintedJobs, using C#. I tried using the win32_printer but the SpoolEnabled value didn't change. I'm using .NET windows forms (4.6) & Windows 10.
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Printer Where Default = True");
ManagementObjectCollection printerCollection = new ManagementObjectSearcher(query).Get();
if (printerCollection.Count > 0)
{
foreach (ManagementObject printer in printerCollection)
{
PropertyDataCollection printerProperties = printer.Properties;
if ((bool)printerProperties["Default"].Value)
{
printerProperties["SpoolEnabled"].Value = true;
printer.Put();
}
}
}
Also, I tried using the following code with no success:
ManagementPath mPath = new ManagementPath("//./root/cimv2");
mPath.RelativePath = "Win32_Printer.DeviceID=\"" + PrinterName + "\"";
ManagementObject Printer = new ManagementObject(mPath);
string oldname = Printer.Properties["SpoolEnabled"].Value.ToString();
Printer.Properties["SpoolEnabled"].Value = true;
Printer.Put();
What library should I use, using c#, to change the SpoolEnabled & KeepPrintedJobs properties?

Print PDF from C# using pdfium to roll paper

I am trying to print from a pdf file which has been generated to replicate a 80mm wide roll printout. Ie the pdf is printed to a custom 80mm wide page type.
I send this file using the code below, it is passed a papername of 80 x 297mm which corresponds to a physical thermal printer paper size. I cannot work out why pdfiumviewer is making the output on the printer scaled down to only being about 20mm wide on the 80mm wide paper When I print the PDF directly from EDGE ot adobe the pdf fits perfectly on the paper. I cannot work out why it is scaling down.
If anyone has a solution or a better way to print PDF silently to a destination printer I am very open to suggestions.
public bool PrintPDF(string printer, string paperName, string filename, int copies)
{
try
{
// Create the printer settings for our printer
var printerSettings = new PrinterSettings
{
PrinterName = printer,
Copies = (short)copies,
};
// Create our page settings for the paper size selected
var pageSettings = new PageSettings(printerSettings)
{
Margins = new Margins(0, 0, 0, 0),
};
foreach (PaperSize papersize in printerSettings.PaperSizes)
{
if (papersize.PaperName == paperName)
{
pageSettings.PaperSize = papersize;
break;
}
}
// Now print the PDF document
using (var document = PdfDocument.Load(filename))
{
using (var printDocument = document.CreatePrintDocument())
{
printDocument.PrinterSettings = printerSettings;
printDocument.DefaultPageSettings = pageSettings;
printDocument.Print();
}
}
return true;
}
catch
{
return false;
}
}

C# Print pdf file programmatically?

My printing code given below
void SaveReport(Telerik.Reporting.Report report, string fileName)
{
ReportProcessor reportProcessor = new ReportProcessor();
Telerik.Reporting.InstanceReportSource instanceReportSource = new Telerik.Reporting.InstanceReportSource();
instanceReportSource.ReportDocument = report;
RenderingResult result = reportProcessor.RenderReport("PDF", instanceReportSource, null);
using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
fs.Write(result.DocumentBytes, 0, result.DocumentBytes.Length);
}
// initialize PrintDocument object
PrintDocument doc = new PrintDocument()
{
PrinterSettings = new PrinterSettings()
{
// set the printer to 'Microsoft Print to PDF'
PrinterName = "Canon LBP3000",
// tell the object this document will print to file
// PrintToFile = true,
// set the filename to whatever you like (full path)
PrintFileName = fileName,
}
};
doc.DocumentName = "My";
doc.Print();
}
Then I call the function like
SaveReport(new ThermalPrint(), Server.MapPath(#"~\Report\123.pdf"));
The function executes without error but printer not print the pdf file.
The printer printing dialog like
I can't understand the problem.
If you want to print the report, call reportProcessor.PrintReport(typeReportSource, printerSettings) but make sure you provide a valid PrinterSettings instance.

Document printed or not in C#

I used following code to print a pdf :
var fileName = filepath;
ProcessStartInfo psInfo = new ProcessStartInfo();
psInfo.Arguments = ConfigurationManager.AppSettings["printer_name"];
psInfo.FileName = fileName;
psInfo.WindowStyle = ProcessWindowStyle.Hidden;
psInfo.Verb = "print";
psInfo.CreateNoWindow = false;
psInfo.UseShellExecute = true;
process = Process.Start(psInfo);
following to get status of printer :
string query = string.Format("SELECT * from Win32_Printer "+ "WHERE Name LIKE '% {0}'",printerName);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection coll = searcher.Get();
foreach (ManagementObject printer in coll)
{
foreach (PropertyData property in printer.Properties)
{
Logger.LogInfo(""+property.Name, "" +property.Value);
}
}
and also tried following to monitor Print queue :
LocalPrintServer server = new LocalPrintServer();
PrintQueueCollection queueCollection = server.GetPrintQueues();
PrintQueue printQueue = null;
foreach (PrintQueue pq in queueCollection)
{
if (pq.FullName == "HP LaserJet P1505n")
printQueue = pq;
}
int numberOfJobs = 0;
if (printQueue != null)
numberOfJobs = printQueue.NumberOfJobs;
All i want to do is to know is wether the document i did print using (1) is printed succesfully or not!! (2)nd code Snippet just shows same property anme and values always.So cannot notify print status.(3)rd code Snippet always monitors queue once and says '0' numberofjobs.
So what is the actual way to getback the print status?
To Know about print job status..! Try this,
SelectQuery qry = new SelectQuery("PrintJob");
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(qry))
using (ManagementObjectCollection printJobs = searcher.Get())
foreach (ManagementObject printJob in printJobs)
{
string name = (string) product["Name"];
string[] nameParts = name.Split(',');
string printerName = nameParts[0];
string jobNumber = nameParts[1];
string document = (string) product["Document"];
string jobStatus = (string) product["JobStatus"];
}
I hope this helps.

Determine the IP Address of a Printer in C#

I would like to determine the IP address of a printer, using C# (.NET 2.0). I have only the printer share name as set up on the Windows OS, in the format \\PC Name\Printer Name. The printer is a network printer, and has a different IP address to the PC. Does anyone have any pointers?
Thanks in advance for your help.
Regards, Andy.
Just adding an another solution here using .Net Framework 4.0 or higher
Using System.Printing
var server = new PrintServer();
var queues = server.GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections });
foreach (var queue in queues)
{
string printerName = queue.Name;
string printerPort = queue.QueuePort.Name;
}
Check this question: How to get Printer Info in C#.NET?. I think that you have to get the property PortName from the WMI properties.
I know this is an old post, but I had the same issue where I was able to get the Printer Port name, but not the IP. In my case I couldn't rely on the Port Name being IP_[IP Address] but found how to get hold of the actual IP from the port name.
Windows stores the information about ports in the registry under
HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\[port name]
This key contains the values set up in the port configuration page, including IP address and port number.
A quick C# example to get the IP address
using Microsoft.Win32;
RegistryKey key = Registry.LocalMachine.OpenSubKey(#"System\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\" + printerPortName, RegistryKeyPermissionCheck.Default, System.Security.AccessControl.RegistryRights.QueryValues);
if (key != null)
{
String IP = (String)key.GetValue("IPAddress", String.Empty, RegistryValueOptions.DoNotExpandEnvironmentNames);
}
Using WIN32_Printer class is not enough here. It should be combined with Win32_TCPIPPrinterPort class.
Below is the code which should help:
static void Main(string[] args)
{
var scope = new ManagementScope(#"\root\cimv2");
scope.Connect();
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Printer");
var results = searcher.Get();
Console.WriteLine("Network printers list:");
foreach (var printer in results)
{
var portName = printer.Properties["PortName"].Value;
var searcher2 = new ManagementObjectSearcher("SELECT * FROM Win32_TCPIPPrinterPort where Name LIKE '" + portName + "'");
var results2 = searcher2.Get();
foreach (var printer2 in results2)
{
Console.WriteLine("Name:" + printer.Properties["Name"].Value);
//Console.WriteLine("PortName:" + portName);
Console.WriteLine("PortNumber:" + printer2.Properties["PortNumber"].Value);
Console.WriteLine("HostAddress:" + printer2.Properties["HostAddress"].Value);
}
Console.WriteLine();
}
Console.ReadLine();
}
string printerName = "POS-80C";
LocalPrintServer server = new LocalPrintServer();
PrintQueue printQueue = server.GetPrintQueue(printerName);
string portName = printQueue.QueuePort.Name;
string portNumber = "";
string hostAddress = "";
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_TCPIPPrinterPort where Name LIKE '" + portName + "'");
var results = searcher.Get();
foreach (var printer in results)
{
portNumber = (printer.Properties["PortNumber"].Value).ToString();
hostAddress = (printer.Properties["HostAddress"].Value).ToString();
}
Is this printer set up in a network which has Active Directory?
Or is this on your own local network with just a switch and your printer plugged into it?
If it is the former, then you should be able to query for it based on the "printer name". This article show how to get c# .net to connect to the AD. But this does require some knowledge of AD servers in your network.
This solution seems a bit long to me, but may be a good starting point?
Based on the link How to get Printer Info in .NET? (Thanks, Panos, I was already looking at the link!), I have the following solution from Panos's answer:
using System.Management;
...
string printerName = "YourPrinterName";
string query = string.Format("SELECT * from Win32_Printer WHERE Name LIKE '%{0}'", printerName);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection coll = searcher.Get();
foreach (ManagementObject printer in coll)
{
string portName = printer["PortName"].ToString();
if(portName.StartsWith("IP_"))
{
Console.WriteLine(string.Format("Printer IP Address: {0}", portName.Substring(3)));
}
}
Obviously, this only works if the port name for the printer is given in the format "IP_IPAddress", which is I believe is the default.

Categories