Reputation: 9947
I want to get my printer's port number in c#
I have tried using Win32_Printer and PrinterSettings
//Required namespaces
using System.Management;
using System.Drawing.Printing;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Printing;
using System.IO.Ports;
using System.Net;
String printerName = "My printer name";
//String query = String.Format("Select Name, PortName from Win32_Printer WHERE Name LIKE '%{0}'", printerName);
String query = String.Format("Select * from Win32_Printer WHERE Name LIKE '%{0}'", printerName);
ManagementObjectSearcher printers = new ManagementObjectSearcher(query);
foreach (ManagementObject printer in printers.Get())
{
DeviceName = (string)printer.GetPropertyValue("Name");
//Console.WriteLine(DeviceName);
PortName = (string)printer.GetPropertyValue("PortName");
//Console.WriteLine(PortName);
}
PrinterSettings ps = new PrinterSettings();
ps.PrinterName = printerName;
Upvotes: 2
Views: 8437
Reputation: 325
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Collections.Generic;
using static System.Net.Mime.MediaTypeNames;
namespace ConsoleApp1
{
class Myclass
{
//PortType enum
//struct for PORT_INFO_2
[StructLayout(LayoutKind.Sequential)]
public struct PORT_INFO_2
{
public string pPortName;
public string pMonitorName;
public string pDescription;
public PortType fPortType;
internal int Reserved;
}
[Flags]
public enum PortType : int
{
write = 0x1,
read = 0x2,
redirected = 0x4,
net_attached = 0x8
}
//Win32 API
[DllImport("winspool.drv", EntryPoint = "EnumPortsA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern int EnumPorts(string pName, int Level, IntPtr lpbPorts, int cbBuf, ref int pcbNeeded, ref int pcReturned);
/// <summary>
/// method for retrieving all available printer ports
/// </summary>
/// <returns>generic list populated with post names (i.e; COM1, LTP1, etc)</returns>
public List<string> GetPortNames()
{
//variables needed for Win32 API calls
int result; int needed = 0; int cnt = 0; IntPtr buffer = IntPtr.Zero; IntPtr port = IntPtr.Zero;
//list to hold the returned port names
List<string> ports = new List<string>();
//new PORT_INFO_2 for holding the ports
PORT_INFO_2[] portInfo = null;
//enumerate through to get the size of the memory we need
result = EnumPorts("", 2, buffer, 0, ref needed, ref cnt);
try
{
//allocate memory
buffer = Marshal.AllocHGlobal(Convert.ToInt32(needed + 1));
//get list of port names
result = EnumPorts("", 2, buffer, needed, ref needed, ref cnt);
//check results, if 0 (zero) then we got an error
if (result != 0)
{
//set port value
port = buffer;
//instantiate struct
portInfo = new PORT_INFO_2[cnt];
//now loop through the returned count populating our array of PORT_INFO_2 objects
for (int i = 0; i < cnt; i++)
{
portInfo[i] = (PORT_INFO_2)Marshal.PtrToStructure(port, typeof(PORT_INFO_2));
port = (IntPtr)(port.ToInt32() + Marshal.SizeOf(typeof(PORT_INFO_2)));
}
port = IntPtr.Zero;
}
else
throw new Win32Exception(Marshal.GetLastWin32Error());
//now get what we want. Loop through al the
//items in the PORT_INFO_2 Array and populate our generic list
for (int i = 0; i < cnt; i++)
{
ports.Add(portInfo[i].pPortName);
}
//sort the list
ports.Sort();
return ports;
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Error getting available ports: {0}", ex.Message));
Console.ReadLine();
return null;
}
finally
{
if (buffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(buffer);
buffer = IntPtr.Zero;
port = IntPtr.Zero;
}
}
}
[STAThread]
static void Main()
{
Myclass m = new Myclass();
foreach (var item in m.GetPortNames())
{
Console.WriteLine(item.ToString());
}
Console.Read();
}
}
}
Upvotes: 0
Reputation: 12831
ManagementObject
has a properties
property, which returns collection of PropertyData
objects.
From PropertyData
you can get Name
and Value
. Just iterate all properties, you may find the port number.
https://msdn.microsoft.com/en-us/library/system.management.propertydata(v=vs.110).aspx
Below is pseudo code: (untested)
foreach (ManagementObject printer in printers.Get())
{
foreach (PropertyData property in printer.properties)
{
Console.WriteLine(property.Name);
Console.WriteLine(property.Value);
}
}
Upvotes: 0
Reputation: 23
Using Microsoft's WMI Code Creator v1.0 tool, I found you can access PortNumber for Standard TCP/IP Ports via Win32_TCPIPPrinterPort.
using System;
using System.Management;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_TCPIPPrinterPort");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("Win32_TCPIPPrinterPort instance");
Console.WriteLine("-----------------------------------");
Console.WriteLine("Name: {0}", queryObj["Name"]);
Console.WriteLine("PortNumber: {0}", queryObj["PortNumber"]);
}
}
catch (ManagementException e)
{
Console.WriteLine("An error occurred while querying for WMI data: " + e.Message);
}
Console.ReadKey();
}
}
}
Upvotes: 1