Tangiest
Tangiest

Reputation: 44657

Determine the IP Address of a Printer in C#

I would like to determine the IP address of a printer, using C# (.NET 2.0). I have only the printer share name as set up on the Windows OS, in the format \\PC Name\Printer Name. The printer is a network printer, and has a different IP address to the PC. Does anyone have any pointers?

Thanks in advance for your help.

Regards, Andy.

Upvotes: 6

Views: 28535

Answers (8)

Denis Brodbeck
Denis Brodbeck

Reputation: 133

Adding to the previous answers, if you are dealing with industrial label printers (like Zebra ZD421) and you connect those via network, you are in for a ride.

Depending on the driver used you get different network port monitors installed and most of those are custom and won't show under WMI SELECT * FROM Win32_TCPIPPrinterPort.

Here are some common registry location (building upon @michael-balls answer)

Used Driver-Vendor (local SYSTEM install):

  • Generic / Text Only (you're sending raw control commands to printer, very fast mode)
    • printername label-text, ip 10.33.99.170
    • get Port under HKLM\SYSTEM\CurrentControlSet\Control\Print\Printers\label-text (here label-text)
    • get HostName and PortNumber under HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\label-text
  • NiceLabel driver
    • printername label-nicelabel, ip 10.33.99.170
    • get Port under HKLM\SYSTEM\CurrentControlSet\Control\Print\Printers\label-nicelabel (here LAN_label-nicelabel)
    • get IPAddress and PortNumber under HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\Advanced Port Monitor\Ports\LAN_label-nicelabel
  • Zebra Driver
    • printername label-zebra, ip 10.33.99.170
    • get Port under HKLM\SYSTEM\CurrentControlSet\Control\Print\Printers\label-zebra (here LAN_label-zebra)
    • get IPAddress and PortNumber under HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\ZDesigner Port Monitor\Ports\LAN_label-zebra

If you are connecting those printers through a windows print server (because your client os is domain-joined), things get hairy pretty soon. In this deployment model drivers get installed locally, but printers can be installed in user context or system context. Further print jobs can travel from the client all the way through the central print server to the printer, or short-circuit from client to printer directly (often enabled by central IT - but there are cases where this is may not be desirable).

Just some pointers, where to even look in those cases: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\Client Side Rendering Print Provider\Servers\PRINTSRV.contoso.com\Printers\{91A22A41-2CD8-4327-A822-2351C086696A}\DsSpooler

Upvotes: 1

Vlad Sargsyan
Vlad Sargsyan

Reputation: 11

string printerName = "POS-80C";

LocalPrintServer server = new LocalPrintServer();
PrintQueue printQueue = server.GetPrintQueue(printerName);
string portName = printQueue.QueuePort.Name;
string portNumber = "";
string hostAddress = "";

var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_TCPIPPrinterPort where Name LIKE '" + portName + "'");
var results = searcher.Get();
foreach (var printer in results)
{
    portNumber = (printer.Properties["PortNumber"].Value).ToString();
    hostAddress = (printer.Properties["HostAddress"].Value).ToString();
}

Upvotes: 1

Alexander A. Sharygin
Alexander A. Sharygin

Reputation: 281

Using WIN32_Printer class is not enough here. It should be combined with Win32_TCPIPPrinterPort class.

Below is the code which should help:

static void Main(string[] args)
{
var scope = new ManagementScope(@"\root\cimv2");
scope.Connect();
 
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Printer");
var results = searcher.Get();
Console.WriteLine("Network printers list:");
foreach (var printer in results)
{
  var portName = printer.Properties["PortName"].Value;
 
  var searcher2 = new ManagementObjectSearcher("SELECT * FROM Win32_TCPIPPrinterPort where Name LIKE '" + portName + "'");
  var results2 = searcher2.Get();
  foreach (var printer2 in results2)
  {
    Console.WriteLine("Name:" + printer.Properties["Name"].Value);
    //Console.WriteLine("PortName:" + portName);
    Console.WriteLine("PortNumber:" + printer2.Properties["PortNumber"].Value);
    Console.WriteLine("HostAddress:" + printer2.Properties["HostAddress"].Value);
                }
    Console.WriteLine();
  }
  Console.ReadLine();
}

Upvotes: 3

Jay
Jay

Reputation: 1889

Just adding an another solution here using .Net Framework 4.0 or higher

Using System.Printing

 var server = new PrintServer();
            var queues = server.GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections });
            foreach (var queue in queues)
            {
                string printerName = queue.Name;
                string printerPort = queue.QueuePort.Name;
             }

Upvotes: 9

Michael Ball
Michael Ball

Reputation: 81

I know this is an old post, but I had the same issue where I was able to get the Printer Port name, but not the IP. In my case I couldn't rely on the Port Name being IP_[IP Address] but found how to get hold of the actual IP from the port name.

Windows stores the information about ports in the registry under

HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\[port name]

This key contains the values set up in the port configuration page, including IP address and port number.

A quick C# example to get the IP address

using Microsoft.Win32;

RegistryKey key = Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\" + printerPortName, RegistryKeyPermissionCheck.Default, System.Security.AccessControl.RegistryRights.QueryValues);
if (key != null)
{
    String IP = (String)key.GetValue("IPAddress", String.Empty, RegistryValueOptions.DoNotExpandEnvironmentNames);
}

Upvotes: 6

Tangiest
Tangiest

Reputation: 44657

Based on the link How to get Printer Info in .NET? (Thanks, Panos, I was already looking at the link!), I have the following solution from Panos's answer:

using System.Management;

...

string printerName = "YourPrinterName";
string query = string.Format("SELECT * from Win32_Printer WHERE Name LIKE '%{0}'", printerName);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection coll = searcher.Get();

foreach (ManagementObject printer in coll)
{
    string portName = printer["PortName"].ToString();
    if(portName.StartsWith("IP_"))
    {
        Console.WriteLine(string.Format("Printer IP Address: {0}", portName.Substring(3)));
    }
}

Obviously, this only works if the port name for the printer is given in the format "IP_IPAddress", which is I believe is the default.

Upvotes: 0

Irfy
Irfy

Reputation: 2521

Is this printer set up in a network which has Active Directory? Or is this on your own local network with just a switch and your printer plugged into it?

If it is the former, then you should be able to query for it based on the "printer name". This article show how to get c# .net to connect to the AD. But this does require some knowledge of AD servers in your network.

This solution seems a bit long to me, but may be a good starting point?

Upvotes: 0

Panos
Panos

Reputation: 19152

Check this question: How to get Printer Info in C#.NET?. I think that you have to get the property PortName from the WMI properties.

Upvotes: 5

Related Questions