[C# Helper]
Index Books FAQ Contact About Rod
[Essential Algorithms, Second Edition]

[The Modern C# Challenge]

[WPF 3d, Three-Dimensional Graphics with WPF and C#]

[The C# Helper Top 100]

[Interview Puzzles Dissected]

[C# 24-Hour Trainer]

[Beginning Software Engineering]

[C# 5.0 Programmer's Reference]

[MCSD Certification Toolkit (Exam 70-483): Programming in C#]

Title: Use WMI to get detailed printer information in C#


This example shows how you can use WPI 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 the example to experiment with it and to see additional details.

© 2009-2022 Rocky Mountain Computer Consulting, Inc. All rights reserved.