Reputation: 215
Hello I have this code to retreive printer properties:
string printerName = "PrinterName";
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)
{
Console.WriteLine(string.Format("{0}: {1}",
property.Name,
property.Value));
}
}
But properties I need always return the same:
PrinterState:0
PrinterStatus:3
Basically I need this to check if printer is out of paper. What I think would be: PrinterState: 4
Tested on wxp-86 and w7-64 return the same, .Net 4.0
Thank you.
Upvotes: 1
Views: 13429
Reputation: 728
Additionally, you can check extended printer status and another properties; wired printer can provide more information than wireless printers(Lan, WLan, Bluetooth).
https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-printer
using System;
using System.Management;
using System.Windows.Forms;
namespace PrinterSet
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
QueryOnWMI();
}
private void QueryOnWMI()
{
try
{
// Common Information Model v2 (namespace)
string scope = @"root\CIMV2";
string printerName = printerNameTextBox.Text.Trim();
//printerName = "%DocuCentre%";
string query = "SELECT * FROM Win32_Printer";
if (!string.IsNullOrEmpty(printerName))
{
query += $" WHERE Name Like '%{printerName}%'";
}
Console.Clear();
var searcher = new ManagementObjectSearcher(scope, query);
var result = searcher.Get();
if (result == null || result.Count == 0)
{
Console.WriteLine($"Printer '{printerName}' not found");
}
var line = new string('-', 40);
foreach (ManagementObject queryObj in result)
{
Console.WriteLine(line);
Console.WriteLine($"Printer : {queryObj["Name"]}");
ushort ps = Convert.ToUInt16(queryObj["PrinterStatus"]);
var psEnum = (PrinterStatus)ps;
Console.WriteLine("PrinterStatus: {0} ({1})", psEnum, ps);
ps = Convert.ToUInt16(queryObj["ExtendedPrinterStatus"]);
var psExtended = (ExtendedPrinterStatus)ps;
Console.WriteLine("Extended Status: {0} ({1})", psExtended, ps);
//var papers = (string[])queryObj["PrinterPaperNames"];
//foreach (var paper in papers)
//{
// Console.WriteLine("Paper Name: {0}", paper);
//}
Console.WriteLine(line);
}
}
catch (ManagementException emx)
{
// TRY => NET STOP SPOOLER
// Generic failure is thrown
MessageBox.Show(this, "Invalid query: " + emx.Message);
}
}
public enum PrinterStatus : UInt16
{
Other = 1, Unknown = 2, Idle = 3, Printing= 4, Warmup = 5, StoppedPrinting = 6, Offline = 7,
}
public enum ExtendedPrinterStatus : UInt16
{
Other = 1, Unknown = 2, Idle = 3, Printing, WarmingUp, StoppedPrinting, Offline, Paused, Error,
Busy, NotAvailable, Waiting, Processing, Initialization, PowerSave, PendingDeletion, IOActive, ManualFeed
}
private void button1_Click(object sender, EventArgs e)
{
QueryOnWMI();
}
}
}
You can also explore the Windows spooler API: https://learn.microsoft.com/en-us/windows-hardware/drivers/print/introduction-to-spooler-components
and this: windows-printer-driver@stackoverflow
antonio
Upvotes: 0
Reputation: 10046
I had this problem as well and there is no easy fix to this.
The cause of the problem is that Windows Management Instrumentation (WMI) retrieves the printer information from the spoolsv.exe process. So the reliability of the information retrieved depends completely on the printer driver. It is likely that the driver of the printer you are querying information for is either bypassing the spooler to get the status or it does not report the status to the spooler process.
Win32_Printer will report whatever status is contained in the spooler. So if the spooler reports Ready then it never receives data with a status change as the default is Ready. Win32_Printer just exports this as Idle (PrinterStatus = 3 or PrinterState = 0).
Upvotes: 3
Reputation: 9862
According to msdn , Paper Out=5
using System;
using System.Management;
using System.Windows.Forms;
namespace WMISample
{
public class MyWMIQuery
{
public static void Main()
{
try
{
string printerName = "PrinterName";
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_Printer "
+ "WHERE Name LIKE '%{0}'", printerName););
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("Win32_Printer instance");
Console.WriteLine("-----------------------------------");
Console.WriteLine("PrinterStatus: {0}", queryObj["PrinterStatus"]);
}
}
catch (ManagementException e)
{
MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}
}
}
}
Upvotes: 2
Reputation: 1653
this line:
string query = string.Format("SELECT * from Win32_Printer "
+ "WHERE Name LIKE '%{0}'",
printerName);
try call it with % after printername:
string query = string.Format("SELECT * from Win32_Printer "
+ "WHERE Name LIKE '%{0}%'",
printerName);
often printer name is: "[printername] On [port]"
Upvotes: 0