Alexx Perez
Alexx Perez

Reputation: 215

c# printer properties WMI

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

Answers (4)

AntonioHL
AntonioHL

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

Derek W
Derek W

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

Mohammad Arshad Alam
Mohammad Arshad Alam

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

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

Related Questions