Get Printer Port Number in c#

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;

I can get is port name , but not the port number, please help.

Upvotes: 2

Views: 8437

Answers (3)

praveenkumar s
praveenkumar s

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

Pavan Chandaka
Pavan Chandaka

Reputation: 12831

ManagementObject has a properties property, which returns collection of PropertyData objects.

https://msdn.microsoft.com/en-us/library/system.management.managementbaseobject.properties(v=vs.110).aspx

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

Jared Feldman
Jared Feldman

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

Related Questions