0 Replies - 3204 Views - Last Post: 14 December 2009 - 07:34 PM

#1 PsychoCoder   User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1663
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Retrieve list of available printer ports

Posted 14 December 2009 - 07:34 PM

Description: Need a reference to

System.Runtime.InteropServices
System.ComponentModel

Win32 API's and struct providedMethod to retrieve a list of all available printer ports
//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;
}

//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)
    {
        MessageBox.Show(string.Format("Error getting available ports: {0}", ex.Message));
        return null;
    }
    finally
    {
        if (buffer != IntPtr.Zero)
        {
            Marshal.FreeHGlobal(buffer);
            buffer = IntPtr.Zero;
            port = IntPtr.Zero;
            
        }
    }
}


Is This A Good Question/Topic? 0
  • +

Replies To: Retrieve list of available printer ports

#2 PsychoCoder   User is offline

  • Google.Sucks.Init(true);
  • member icon

Reputation: 1663
  • View blog
  • Posts: 19,853
  • Joined: 26-July 07

Re: Retrieve list of available printer ports

Posted 14 December 2009 - 07:34 PM

Description: Need a reference to

System.Runtime.InteropServices
System.ComponentModel

Win32 API's and struct providedMethod to retrieve a list of all available printer ports
//PortType enum
[Flags]
public enum PortType : int
{
    write = 0x1,
    read = 0x2,
    redirected = 0x4,
    net_attached = 0x8
}


//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;
}

//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)
    {
        MessageBox.Show(string.Format("Error getting available ports: {0}", ex.Message));
        return null;
    }
    finally
    {
        if (buffer != IntPtr.Zero)
        {
            Marshal.FreeHGlobal(buffer);
            buffer = IntPtr.Zero;
            port = IntPtr.Zero;
            
        }
    }
}

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1