tags:

views:

1372

answers:

8

How to find available COM ports in my PC? I am using framework v1.1. Is it possible to find all COM ports? If possible, help me solve the problem.

A: 

Framework v1.1 AFAIK doesn't allow you to do this.

In 2.0 there is a static function

SerialPort.GetPortNames()

http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.getportnames.aspx

Vanuan
+1  A: 

WMI contains a lot of hardware information. Query for instances of Win32_SerialPort.

(OTOH I can't recall how much WMI query support was in .NET 1.1.)

Richard
+1  A: 

There is no support for SerialPort communication in .net v1.1. The most common solution for this was to use the MSCOMMCTL active X control from a VB6.0 installation (import into your .net project as a COM component from the add reference dialog box).

In later versions the Serial Port support is available through the System.IO.Ports name space. Also please note there is no API which will get you the list of free ports.

You can get a list of all the port names and then try opening a connection. An exception occurs if the port is already in use.

Sesh
A: 

Use QueryDosDevice API function. This is a VB6 snippet:

    ReDim vRet(0 To 255)

    sBuffer = String(100000, 1)
    Call QueryDosDevice(0, sBuffer, Len(sBuffer))
    sBuffer = Chr$(0) & sBuffer
    For lIdx = 1 To 255
        If InStr(1, sBuffer, Chr$(0) & "COM" & lIdx & Chr$(0), vbTextCompare) > 0 Then
            vRet(lCount) = "COM" & lIdx
            lCount = lCount + 1
        End If
    Next

cheers,
</wqw>

wqw
+1  A: 

The available serial ports can also be found at the values at the HKEY_LOCAL_MACHINE\hardware\devicemap\serialcomm key in the registry.

Steef
A: 

How about asking a straight question from operating system:

using System;
using System.Collections.Generic;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;

public class MyClass
{
 private const uint GENERIC_ALL = 0x10000000;
 private const uint GENERIC_READ = 0x80000000;
 private const uint GENERIC_WRITE = 0x40000000;
 private const uint GENERIC_EXECUTE = 0x20000000; 
 private const int OPEN_EXISTING = 3; 
 public const int INVALID_HANDLE_VALUE = -1;

 public static void Main()
 {
  for (int i = 1; i <= 32; i++)
   Console.WriteLine ("Port {0}: {1}", i, PortExists (i));
 }

 private static bool PortExists (int number) {
  SafeFileHandle h = CreateFile (@"\\.\COM" + number.ToString (), GENERIC_READ + GENERIC_WRITE, 
   0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);

  bool portExists = !h.IsInvalid;

  if (portExists)
   h.Close ();

  return portExists;
 }

 [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
 private static extern SafeFileHandle CreateFile (string lpFileName, System.UInt32 dwDesiredAccess, 
  System.UInt32 dwShareMode, IntPtr pSecurityAttributes, System.UInt32 dwCreationDisposition, 
  System.UInt32 dwFlagsAndAttributes, IntPtr hTemplateFile);
}
Hemant
OK...there is a catch! This will tell you if a port is available for the application. If a port is captured by another app, PortExists function will return false. If you want to get the list of port available in hardware (even if captured by other apps) then PInvoke GetDefaultCommConfig (http://msdn.microsoft.com/en-us/library/aa363262(VS.85).aspx).
Hemant
+1  A: 

As others suggested, you can use WMI. You can find a sample in CodeProject

try
{
    ManagementObjectSearcher searcher =
        new ManagementObjectSearcher("root\\WMI",
        "SELECT * FROM MSSerial_PortName");

    foreach (ManagementObject queryObj in searcher.Get())
    {
        Console.WriteLine("-----------------------------------");
        Console.WriteLine("MSSerial_PortName instance");
        Console.WriteLine("-----------------------------------");
        Console.WriteLine("InstanceName: {0}", queryObj["InstanceName"]);

        Console.WriteLine("-----------------------------------");
        Console.WriteLine("MSSerial_PortName instance");
        Console.WriteLine("-----------------------------------");
        Console.WriteLine("PortName: {0}", queryObj["PortName"]);

        //If the serial port's instance name contains USB 
        //it must be a USB to serial device
        if (queryObj["InstanceName"].ToString().Contains("USB"))
        {
            Console.WriteLine(queryObj["PortName"] + " 
      is a USB to SERIAL adapter/converter");
        }
    }
}
catch (ManagementException e)
{
    MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}
Juanma
+1  A: 

Hello,

Since you are using .net 1.1 one option is to use the AxMSCommLib control.

Here is a web page that assisted me in starting to use AxMSCommLib control. There is even a FindDevicePort() method listed that can be easily modified.

I have since switched to System.IO.Ports which appears to be much more robust.

http://www.devhood.com/tutorials/tutorial%5Fdetails.aspx?tutorial%5Fid=320

Thanks

Joe

Joe Pitz