1

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.

Kjartan
  • 18,591
  • 15
  • 71
  • 96
Alexx Perez
  • 215
  • 2
  • 10
  • 19
  • possible duplicate of [How to get Printer Info in .NET?](http://stackoverflow.com/questions/296182/how-to-get-printer-info-in-net) – MethodMan Jan 22 '13 at 10:15
  • It's true, but it is what returns. – Alexx Perez Jan 22 '13 at 10:33
  • See my answer below for an explanation of why this is happening. I was attempting to use Win32_Printer to check if a Zebra Printer was online and ready, but I was always receiving a response of idle for the printer. Turns out that the problem is based around the printer driver. – Derek W Aug 13 '13 at 16:55

4 Answers4

3

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).

Derek W
  • 9,708
  • 5
  • 58
  • 67
1

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);
            }
        }
    }
}
Mohammad Arshad Alam
  • 9,694
  • 6
  • 38
  • 61
  • Well, it should return 5. But it always return the same, with printer working, idle, paper out, always return PrinterState:0 PrinterStatus:3 – Alexx Perez Jan 22 '13 at 10:37
  • 0 is not valid PrinterStatus according msdn. – Mohammad Arshad Alam Jan 22 '13 at 10:40
  • OK, this is working, just changing state from printing to out of paper take about 2 minutes. Why?? And I need to check even if i'm not printing – Alexx Perez Jan 22 '13 at 11:09
  • if its working then you can accept as solution, wmi queries on hardware , that why it takes time. you can set set interval time also. example ; http://msdn.microsoft.com/en-us/library/aa394527%28VS.85%29.aspx – Mohammad Arshad Alam Jan 22 '13 at 11:17
  • This solution doesn't work, it is identical to this one : https://stackoverflow.com/questions/887785/talking-to-a-printer?noredirect=1&lq=1 – Pedram Apr 23 '18 at 13:42
0

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]"

0

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

antonio
  • 548
  • 8
  • 16