How to open a serial port by friendly name?

后端 未结 8 1939
日久生厌
日久生厌 2020-11-29 02:10

friendly name = the name that appears in \"Device Manager\" under \"Ports (COM & LPT).

EDIT: two solutions provided below. One with WMI and another with SetupAPI

8条回答
  •  感动是毒
    2020-11-29 03:08

    Pavel's class SetupDiWrap works great, it just needs a few small tweaks for Windows 7.

    Hopefully, this update will help other people struggling (like me) to get COM port numbers from VCP names in Windows 7.

    1) The SP_DEVINFO_DATA has changed in Windows 7, the total length is no longer 28 bytes, it is 32 bytes long. This is what works for me:

       private struct SP_DEVINFO_DATA
            {
                /// Size of the structure, in bytes.
                public int cbSize;
                /// GUID of the device interface class.
                public Guid ClassGuid;
                /// Handle to this device instance.
                public int DevInst;
                /// Reserved; do not use.
                public ulong Reserved;
            }
    

    Note ulong for Reserved instead of an int. Changing uint cbSize to int cbSize saved me a cast later on, otherwise you can leave it as uint.

    2) I also wrote the line:

     da.cbSize = (uint)Marshal.SizeOf(da);
    

    a bit different, for clarity, to get the cbSize to 32 bits:

    da.cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
    

    3) I changed

     [DllImport("setupapi.dll", CharSet = CharSet.Auto)]
            static extern IntPtr SetupDiGetClassDevs(       
               ref Guid ClassGuid,
               IntPtr Enumerator,
               IntPtr hwndParent,
               int Flags
            );
    

    to

     [DllImport("setupapi.dll", CharSet = CharSet.Auto)]
            private static extern IntPtr SetupDiGetClassDevs( 
               ref Guid ClassGuid,
               UInt32 Enumerator,
               IntPtr hwndParent,
               UInt32 Flags
            );
    

    The Enumerator is no longer an IntPtr, so you need to call SetupDiGetClassDevs like this:

    IntPtr h = SetupDiGetClassDevs(ref guidClone, 0, IntPtr.Zero, DIGCF_PRESENT | DIGCF_PROFILE);
    

    Note "0" instead of IntPtr.Zero when passing the Enumerator.

    The code now runs like a charm in Windows 7!

提交回复
热议问题