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 5 main methods that I normally use
1. AddPrinter – Adds or maps a specific printer to the client machine.
2. DeletePrinter – Removes or unmaps a specific printer to the client machine.
3. RenamePrinter – Renames the printer on the client machine.
4. SetDefaultPrinter – Sets the printer as default on clients machine.
5. GetPrinterInfo – Gets the Printer Information.
6. IsPrinterInstalled – Checks whether the printer is installed.
Now for the the codes:
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“, now 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 “\ServerNamePrinterName“ but since its in C# you will see when you put a watch on it, it will show as “\\ServerName\PrinterName” its only when it is passed as the parameter then it is recognized as “\ServerNamePrinterName“ 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.
Thanks alot for this, exactly what I was looking for 🙂
Keep up!
How can i print landscape without dilog by WMI or Printdocument ?
Thanks. Do you have other articles in the series regarding start up scripts?
I have found another article about network drives in your blog.
I am thinking about develoing a small application for managing user environment.
Printer, drives, regkeys, desktop links…
Thanks
I have several of these but I have not posted it on-line. I had a similar project before hence most of what you need I might have just let me know what components you need I might be able to help.
Hello,
thanks for your reply.
Well first step will be printer (default printer and additional printers), network drive mapping, registry keys and shortcut/links on desktop and/or startmenue. Maybe after that favorites, copying files or so.
Configuration stored in database…
So at the moment the plan. We have also taken a closer look on products at the market, but most of them have a lot of functionality we did not need.
regards
How can i print landscape without dilog by WMI or Printdocument ?
How can i print landscape without dilog by WMI or Printdocument .I want to print on network printer?
can i print html file using PrintDocument in c#