Fernando Torres
Fernando Torres

Reputation: 1180

How to get a PrinterName for a given ip address

I am printing using PrintDocument class.

I have a DB table having doc info to be printed. Instead of having its PrintName I just have IP address of the printer. All printers are installed locally. And I'm working on a windows service that will print those documents.

There is another app, out of my scope, where the user chose one printer, but just its IP is stored at DB... so

How can I set PrinterSettings.PrinterName having just its IP address??

Upvotes: 0

Views: 2566

Answers (1)

Kaspar Kjeldsen
Kaspar Kjeldsen

Reputation: 992

By printername I assume you mean the name the printer is set up with in Windows and not the printer model, or sharename. I don't really understand what you mean by the printers are installed locally. Is your computer acting as a printserver for the printers, since you have their IP address, or are they installed and shared from another printserver?

What you are actually looking for, when you only have the IP address is the printers TCPIPPrinterPort, which then is related to a printer. Unfortunatly the PrintServer class in C# doesn't return the hostaddress of the associated port (which is why we always name our ports "IP_10.200.49.230" or the like, because then you can find the port by name instead of hostaddress, which IS included in the printserver class.

In your situation I would do something like this:

static void Main(string[] args)
{
    String serverName = "Print-Server"; //set servername (your own computername if you truly are hosting the printers locally)
    String ipToSearchFor = "10.91.40.75";//ip to search for in this example
    //this loads all TCPPrinterPorts into a Dictionary indexed by the ports Hostaddress (IP)
    //I'm loading all because I assume you are going to iterate over them at some point, since It seems you have a list
    Dictionary<string, ManagementObject> printerPorts = LoadScope(serverName, "select * from Win32_TCPIPPrinterPort");
    //after we've got the ports, open the printserver
    using (PrintServer ps = new PrintServer("\\\\" + serverName))
    {
        //find the queue where queueport.name equals name of port we look up from IP
        var queue = ps.GetPrintQueues().Where(p => p.QueuePort.Name == printerPorts[ipToSearchFor]["Name"].ToString()).FirstOrDefault();
        //print sharename
        Console.WriteLine(queue.ShareName);
    }
}
//Loads everything in scope into a dictionary, in this case indexed by hostaddress
private static Dictionary<string, ManagementObject> LoadScope(string server, string query)
{
    ManagementScope scope = new ManagementScope("\\\\" + server + "\\root\\cimv2");
    scope.Connect();
    SelectQuery q = new SelectQuery(query);
    ManagementObjectSearcher search = new ManagementObjectSearcher(scope, q);
    ManagementObjectCollection pp = search.Get();
    Dictionary<string, ManagementObject> objects = new Dictionary<string, ManagementObject>();
    foreach (ManagementObject p in pp)
    {
        string name = p["HostAddress"].ToString().ToLower();
        if (!objects.ContainsKey(name))
            objects.Add(name, p);
    }
    return objects;
}

I would advise for you to loop through your list and from here on, also save the sharename and servername of the printer.

Upvotes: 1

Related Questions