Monday, April 11, 2011

Enumerating a List of systems Com Ports in Delphi

Objective: I would like to be able to list the available COM Ports on a system in Delphi.

Homework: I have read this SO thread on enumerating the LPT ports of a system using the registry. I have also found that the COM ports are listed in the registry at HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM but found unanswered gesticulation in the same thread that this might not be reliable on different machines and different versions of windows.

I also found articles referencing the use of QueryDosDevice() but upon trying this sample code, I found that it did not appear to list any COM ports at all.

Question: What is the most reliable way (across unknown Windows Versions) to list the COM ports on a Windows Machine?

From stackoverflow
  • DEVICEMAP\SERIALCOMM is good for all NT versions. You'll probably need to look under DYN_DATA for Win9x.

    Use this method if you need runtime reliability.

    jamiei : This looks to be the best way but if I'm reading the documentation correctly it is created on start-up. Does that mean that Serial Devices added after boot up will not be present?
    ssg : Is this really an issue?
    jamiei : Probably not. But as the device actually uses a USB to Serial Bridge it may confuse a few people who are used to plugging in USB devices after boot.
    ssg : I added an alternative way of doing it which can handle runtime.
    jamiei : The Same as posted @lakshmanaraj below. I'm guessing that someone must have translated this for Delphi use before?
    ssg : It's pure Win32 API you should be able to write it in Delphi in an hour.
    tomlogic : I had a lot of trouble getting the codeproject.com sample working with Cygwin (ANSI C), and ended up creating a simple function based on `GetDefaultCommConfig()`. See http://stackoverflow.com/questions/1205383/listing-serial-com-ports-on-windows/3018813#3018813
  • Please try this code :

    function GetSerialPortNames: string;
    var
      Index: Integer;
      Data: string;
      TmpPorts: String;
      sr : TSearchRec;
    begin
      try
        TmpPorts := '';
        if FindFirst('/dev/ttyS*', $FFFFFFFF, sr) = 0 then
        begin
          repeat
            if (sr.Attr and $FFFFFFFF) = Sr.Attr then
            begin
              data := sr.Name;
              index := length(data);
              while (index > 1) and (data[index] <> '/') do
                index := index - 1;
              TmpPorts := TmpPorts + ' ' + copy(data, 1, index + 1);
            end;
          until FindNext(sr) <> 0;
        end;
        FindClose(sr);
      finally
        Result:=TmpPorts;
      end;
    end;
    

    I tried this code in Win XP. Don't know the other OS. (I advice SYNAPSE library for network communication application.)

    jamiei : Thanks but this gave me an empty string on the target machine.
    SimaWB : Sorry I sent wrong function. It's used for Linux.
  • Please go through URL which is written in C++

    http://www.codeproject.com/KB/system/serial_portsenum_fifo.aspx

    and same approach can be implemented in delphi too.. or somebody can convert for you in SO..

    This will work for all windows versions since this works from the principle of device manager which is available for all window versions.

    tomlogic : Simpler method (in C) in my answer to another SO question: http://stackoverflow.com/questions/1205383/listing-serial-com-ports-on-windows/3018813#3018813

0 comments:

Post a Comment