Use WMI to get detailed printer information in C#

example

This example shows how you can use WMI to get printer information for the printers installed on your system. When the program loads, it uses the following code to list the system’s installed printers.

// List the installed printers.
private void Form1_Load(object sender, EventArgs e)
{
    // Find all of the installed printers.
    foreach (string printer in PrinterSettings.InstalledPrinters)
    {
        cboPrinters.Items.Add(printer);
    }

    // Select the first printer.
    cboPrinters.SelectedIndex = 0;
}

This code just loops through the PrinterSettings.InstalledPrinters collection, adding the installed printers to the cboPrinters ComboBox.

When you select a printer from the list, the program uses Windows Management Instrumentation (WMI) to get information about that printer. It displays the printer’s name, state, status, description, default-ness, vertical and horizontal resolution, port name, and paper sizes supported.

(WMI is a sort of SQL-like scripting language that lets you learn about and control many parts of the system that are hard to get at through the .NET Framework or even API functions. It’s pretty amazing what information is in there if you can figure out how to find it. Note that to use WMI you need to add a reference to System.Management.)

When you select a printer from the ComboBox, the program uses the following code to display information about the selected printer.

// Display information about the selected printer.
private void cboPrinters_SelectedIndexChanged(object sender, EventArgs e)
{
    // Lookup arrays.
    string[] PrinterStatuses = 
    {
        "Other", "Unknown", "Idle", "Printing", "WarmUp",
        "Stopped Printing", "Offline"
    };
    string[] PrinterStates = 
    {
        "Paused", "Error", "Pending Deletion", "Paper Jam",
        "Paper Out", "Manual Feed", "Paper Problem",
        "Offline", "IO Active", "Busy", "Printing",
        "Output Bin Full", "Not Available", "Waiting",
        "Processing", "Initialization", "Warming Up", 
        "Toner Low", "No Toner", "Page Punt",
        "User Intervention Required", "Out of Memory",
        "Door Open", "Server_Unknown", "Power Save"};

    // Get a ManagementObjectSearcher for the printer.
    string query = "SELECT * FROM Win32_Printer WHERE Name='" +
        cboPrinters.SelectedItem.ToString() + "'";
    ManagementObjectSearcher searcher =
        new ManagementObjectSearcher(query);

    // Get the ManagementObjectCollection representing
    // the result of the WMI query. Loop through its
    // single item. Display some of that item's properties.
    foreach (ManagementObject service in searcher.Get())
    {
        txtName.Text = service.Properties["Name"].Value.ToString();

        UInt32 state =
            (UInt32)service.Properties["PrinterState"].Value;
        txtState.Text =
            PrinterStates[state];

        UInt16 status =
            (UInt16)service.Properties["PrinterStatus"].Value;
        txtStatus.Text = PrinterStatuses[status];

        txtDescription.Text =
            GetPropertyValue(service.Properties["Description"]);
        txtDefault.Text =
            GetPropertyValue(service.Properties["Default"]);
        txtHorRes.Text =
            GetPropertyValue(service.Properties["HorizontalResolution"]);
        txtVertRes.Text =
            GetPropertyValue(service.Properties["VerticalResolution"]);
        txtPort.Text =
            GetPropertyValue(service.Properties["PortName"]);

        lstPaperSizes.Items.Clear();
        string[] paper_sizes =
            (string[])service.Properties["PrinterPaperNames"].Value;
        foreach (string paper_size in paper_sizes)
        {
            lstPaperSizes.Items.Add(paper_size);
        }

        // List the available properties.
        foreach (PropertyData data in service.Properties)
        {
            string txt = data.Name;
            if (data.Value != null)
                txt += ": " + data.Value.ToString();
            Console.WriteLine(txt);
        }
    }
}

This code starts by defining some arrays to convert numeric values into textual values. The code then executes the statement SELECT * FROM Win32_Printer WHERE Name='name' for the printer you selected. The result is a ManagementObjectCollection containing a list of ManagementObjects. This example selects information for a single printer so the collection only holds one object.

The code examines the object and uses its Properties collection to retrieve key values. To make this a bit easier, the code uses the GetPropertyValue method described shortly.

The ManagementObject‘s PrinterPaperNames property contains an array of paper size names. The code loops through this array adding the paper sizes to a ListBox.

Finally, so you can see what values are available, the program loops through all of the object’s properties writing their names to the Console window.

The following GetPropertyValue method returns a string representing the value of a PropertyData object.

// If the data is not null and has a value, return it.
private string GetPropertyValue(PropertyData data)
{
    if ((data == null) || (data.Value == null)) return "";
    return data.Value.ToString();
}

If the object or its Value property is null, the method returns an empty string. Otherwise it returns the object’s Value converted into a string.

For more information about the data available in the Win32_Printer class, see: Win32_Printer class.


Download Example   Follow me on Twitter   RSS feed




This entry was posted in printers, system, WMI. Bookmark the permalink.

One Response to Use WMI to get detailed printer information in C#

  1. Rod Stephens says:

    I don’t think this example had an image, but there’s no reason why it shouldn’t so I added one.

    I build these pages in Firefox using the GoDaddy Quick Blogcast tool, so I can’t vouch for the pages displaying perfectly on all browsers.

Leave a Reply

Your email address will not be published. Required fields are marked *