Click here to Skip to main content
15,867,906 members
Articles / All Topics

Managing Printers Programatically using C# and WMI

Rate me:
Please Sign up or sign in to vote.
4.87/5 (11 votes)
13 May 2010CPOL2 min read 76K   23   5
How to manage printers programmatically using C# and WMI

This is another part of my series regarding start up scripts. This post is for Printer Management, now why do I have to do that? I was tasked to do this as we have to map each printer in every shop we had when a user logs in. Now this is all managed in a SQL Server database where their subnets (which is unique per shop) are mapped to a printer or many printers, so any configuration changes have to be done in SQL Server rather than manually updating all of the clients, these configuration changes are things such as renaming printers (we have to do this as we still have some legacy apps that rely on Printer1 and Printer2, if you know what I mean), changing the IP Ports, changing default printers and much more.

Now I had created a class library to handle the Printer Management. I have 6 main methods that I normally use:

  • AddPrinter – Adds or maps a specific printer to the client machine
  • DeletePrinter - Removes or unmaps a specific printer to the client machine
  • RenamePrinter – Renames the printer on the client machine
  • SetDefaultPrinter – Sets the printer as default on clients machine
  • GetPrinterInfo – Gets the Printer Information
  • IsPrinterInstalled – Checks whether the printer is installed

Now for the codes:

C#
using System;
using System.Management;

class PrinterSettings
{
private static ManagementScope oManagementScope = null;
//Adds the Printer
public static bool AddPrinter(string sPrinterName)
{
 try
 {
 oManagementScope = new ManagementScope(ManagementPath.DefaultPath);
 oManagementScope.Connect();

 ManagementClass oPrinterClass = new ManagementClass
				(new ManagementPath("Win32_Printer"), null);
 ManagementBaseObject oInputParameters = 
	oPrinterClass.GetMethodParameters("AddPrinterConnection");

 oInputParameters.SetPropertyValue("Name", sPrinterName);

 oPrinterClass.InvokeMethod("AddPrinterConnection", oInputParameters, null);
 return true;
 }
 catch (Exception ex)
 {
 return false;
 }
}
//Deletes the printer
public static bool DeletePrinter(string sPrinterName)
{
 oManagementScope = new ManagementScope(ManagementPath.DefaultPath);
 oManagementScope.Connect();

 SelectQuery oSelectQuery = new SelectQuery();
 oSelectQuery.QueryString = @"SELECT * FROM Win32_Printer WHERE Name = '" + 
	sPrinterName.Replace("\\", "\\\\") + "'";

 ManagementObjectSearcher oObjectSearcher = 
	new ManagementObjectSearcher(oManagementScope, oSelectQuery);
 ManagementObjectCollection oObjectCollection = oObjectSearcher.Get();

 if (oObjectCollection.Count != 0)
 {
 foreach (ManagementObject oItem in oObjectCollection)
 {
 oItem.Delete();
 return true;
 }
 }
 return false;
}
//Renames the printer
public static void RenamePrinter(string sPrinterName, string newName)
{
 oManagementScope = new ManagementScope(ManagementPath.DefaultPath);
 oManagementScope.Connect();

 SelectQuery oSelectQuery = new SelectQuery();
 oSelectQuery.QueryString = @"SELECT * FROM Win32_Printer 
	WHERE Name = '" + sPrinterName.Replace("\\", "\\\\") + "'";

 ManagementObjectSearcher oObjectSearcher = 
	new ManagementObjectSearcher(oManagementScope, oSelectQuery);
 ManagementObjectCollection oObjectCollection = oObjectSearcher.Get();

 if (oObjectCollection.Count != 0)
 {
 foreach (ManagementObject oItem in oObjectCollection)
 {
 oItem.InvokeMethod("RenamePrinter", new object[] { newName });
 return;
 }
 }
}
//Sets the printer as Default
public static void SetDefaultPrinter(string sPrinterName)
{
 oManagementScope = new ManagementScope(ManagementPath.DefaultPath);
 oManagementScope.Connect();

 SelectQuery oSelectQuery = new SelectQuery();
 oSelectQuery.QueryString = @"SELECT * FROM Win32_Printer WHERE Name = 
			'" + sPrinterName.Replace("\\", "\\\\") + "'";

 ManagementObjectSearcher oObjectSearcher = 
	new ManagementObjectSearcher(oManagementScope, oSelectQuery);
 ManagementObjectCollection oObjectCollection = oObjectSearcher.Get();

 if (oObjectCollection.Count != 0)
 {
 foreach (ManagementObject oItem in oObjectCollection)
 {
 oItem.InvokeMethod("SetDefaultPrinter", new object[] { sPrinterName });
 return;
 }
 }
}
//Gets the printer information
public static void GetPrinterInfo(string sPrinterName)
{
 oManagementScope = new ManagementScope(ManagementPath.DefaultPath);
 oManagementScope.Connect();

 SelectQuery oSelectQuery = new SelectQuery();
 oSelectQuery.QueryString = @"SELECT * FROM Win32_Printer 
	WHERE Name = '" + sPrinterName.Replace("\\", "\\\\") + "'";

 ManagementObjectSearcher oObjectSearcher = 
	new ManagementObjectSearcher(oManagementScope, @oSelectQuery);
 ManagementObjectCollection oObjectCollection = oObjectSearcher.Get();

 foreach (ManagementObject oItem in oObjectCollection)
 {
 Console.WriteLine("Name : " + oItem["Name"].ToString());
 Console.WriteLine("PortName : " + oItem["PortName"].ToString());
 Console.WriteLine("DriverName : " + oItem["DriverName"].ToString());
 Console.WriteLine("DeviceID : " + oItem["DeviceID"].ToString());
 Console.WriteLine("Shared : " + oItem["Shared"].ToString());
 Console.WriteLine("---------------------------------------------------------------");
 }
}
//Checks whether a printer is installed
public bool IsPrinterInstalled(string sPrinterName)
{
 oManagementScope = new ManagementScope(ManagementPath.DefaultPath);
 oManagementScope.Connect();

 SelectQuery oSelectQuery = new SelectQuery();
 oSelectQuery.QueryString = @"SELECT * FROM Win32_Printer WHERE Name = '" + 
				sPrinterName.Replace("\\", "\\\\") + "'";

 ManagementObjectSearcher oObjectSearcher = 
	new ManagementObjectSearcher(oManagementScope, oSelectQuery);
 ManagementObjectCollection oObjectCollection = oObjectSearcher.Get();

 return oObjectCollection.Count > 0;
}
}

If you had noticed, on my WMI Queries, I added @ on each query. You need this because it terminates the character “\“, to make it more confusing, my Printer Name variable is something similar to this “\\\\ServerName\\PrinterName“. To make it more confusing, I added “Replace(“\\”, “\\\\”)”. Now what the hell am I doing.

The issue is that the “\“ character is the escape symbol for both C# and WQL and Using “@” tells C# not to escape the “\“ but you need to tell WQL the same thing. In C#, I had used “@” to escape the querystring which instructs the compiler to treat ANY special characters in the string as literals which then means you don't need to escape the “\“ symbol for C# but we need an extra “\“ as an escape for WQL parser.

To further elaborate, in my parameter sPrinterName, the value as text is “\\ServerName\PrinterName“ but since it's in C#, you will see when you put a watch on it, it will show as “\\\\ServerName\\PrinterName” it's only when it is passed as the parameter then it is recognized as “\\ServerName\PrinterName“ that’s why I have to do the replace so it would be “\\\\ServerName\\PrinterName again (which is a proper format for WQL) and add “@“ for C# to escape it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
New Zealand New Zealand
http://nz.linkedin.com/in/macaalay
http://macaalay.com/

Comments and Discussions

 
Questionhow to count paper that print ? Pin
Member 1108038428-Oct-15 23:56
Member 1108038428-Oct-15 23:56 
GeneralMy vote of 5 Pin
Sibeesh Venu8-Aug-14 1:28
professionalSibeesh Venu8-Aug-14 1:28 
Questionnice article - One question Pin
joekecalo30-Dec-13 21:47
joekecalo30-Dec-13 21:47 
Questioncan i print html file using PrintDocument in c# Pin
AmitGargash10-Dec-12 18:14
AmitGargash10-Dec-12 18:14 
QuestionManaging Scaner Programatically using C# and WMI Pin
Member 912854731-Jul-12 20:06
Member 912854731-Jul-12 20:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.