首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何通过友好名称打开串口?

如何通过友好名称打开串口?
EN

Stack Overflow用户
提问于 2010-05-30 12:47:28
回答 8查看 34K关注 0票数 24

友好名称=出现在“设备管理器”中“端口(COM & LPT)”下的名称。

编辑:下面提供了两个解决方案。一个使用WMI,另一个使用SetupAPI。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2010-05-30 18:35:18

尝试在Win32_SerialPort类上运行WMI查询。下载WmiCodeCreator进行实验并自动生成C#代码。

票数 0
EN

Stack Overflow用户

发布于 2010-05-30 12:49:45

发布今晚的代码,让每个人都能享受:

代码语言:javascript
复制
public class SetupDiWrap
{
    static public string ComPortNameFromFriendlyNamePrefix(string friendlyNamePrefix)
    {
        const string className = "Ports";
        Guid[] guids = GetClassGUIDs(className);

        System.Text.RegularExpressions.Regex friendlyNameToComPort =
            new System.Text.RegularExpressions.Regex(@".? \((COM\d+)\)$");  // "..... (COMxxx)" -> COMxxxx

        foreach (Guid guid in guids)
        {
            // We start at the "root" of the device tree and look for all
            // devices that match the interface GUID of a disk
            Guid guidClone = guid;
            IntPtr h = SetupDiGetClassDevs(ref guidClone, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_PROFILE);
            if (h.ToInt32() != INVALID_HANDLE_VALUE)
            {
                int nDevice = 0;
                while (true)
                {
                    SP_DEVINFO_DATA da = new SP_DEVINFO_DATA();
                    da.cbSize = (uint)Marshal.SizeOf(da);

                    if (0 == SetupDiEnumDeviceInfo(h, nDevice++, ref da))
                        break;

                    uint RegType;
                    byte[] ptrBuf = new byte[BUFFER_SIZE];
                    uint RequiredSize;
                    if (SetupDiGetDeviceRegistryProperty(h, ref da,
                        (uint)SPDRP.FRIENDLYNAME, out RegType, ptrBuf,
                        BUFFER_SIZE, out RequiredSize))
                    {
                        const int utf16terminatorSize_bytes = 2;
                        string friendlyName = System.Text.UnicodeEncoding.Unicode.GetString(ptrBuf, 0, (int)RequiredSize - utf16terminatorSize_bytes);

                        if (!friendlyName.StartsWith(friendlyNamePrefix))
                            continue;

                        if (!friendlyNameToComPort.IsMatch(friendlyName))
                            continue;

                        return friendlyNameToComPort.Match(friendlyName).Groups[1].Value;
                    }
                } // devices
                SetupDiDestroyDeviceInfoList(h);
            }
        } // class guids

        return null;
    }

    /// <summary>
    /// The SP_DEVINFO_DATA structure defines a device instance that is a member of a device information set.
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    private struct SP_DEVINFO_DATA
    {
        /// <summary>Size of the structure, in bytes.</summary>
        public uint cbSize;
        /// <summary>GUID of the device interface class.</summary>
        public Guid ClassGuid;
        /// <summary>Handle to this device instance.</summary>
        public uint DevInst;
        /// <summary>Reserved; do not use.</summary>
        public uint Reserved;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct SP_DEVICE_INTERFACE_DATA
    {
        public Int32 cbSize;
        public Guid interfaceClassGuid;
        public Int32 flags;
        private UIntPtr reserved;
    }

    const int BUFFER_SIZE = 1024;

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    private struct SP_DEVICE_INTERFACE_DETAIL_DATA
    {
        public int cbSize;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = BUFFER_SIZE)]
        public string DevicePath;
    }

    private enum SPDRP
    {
        DEVICEDESC = 0x00000000,
        HARDWAREID = 0x00000001,
        COMPATIBLEIDS = 0x00000002,
        NTDEVICEPATHS = 0x00000003,
        SERVICE = 0x00000004,
        CONFIGURATION = 0x00000005,
        CONFIGURATIONVECTOR = 0x00000006,
        CLASS = 0x00000007,
        CLASSGUID = 0x00000008,
        DRIVER = 0x00000009,
        CONFIGFLAGS = 0x0000000A,
        MFG = 0x0000000B,
        FRIENDLYNAME = 0x0000000C,
        LOCATION_INFORMATION = 0x0000000D,
        PHYSICAL_DEVICE_OBJECT_NAME = 0x0000000E,
        CAPABILITIES = 0x0000000F,
        UI_NUMBER = 0x00000010,
        UPPERFILTERS = 0x00000011,
        LOWERFILTERS = 0x00000012,
        MAXIMUM_PROPERTY = 0x00000013,
    }

    [DllImport("setupapi.dll", SetLastError = true)]
    static extern bool SetupDiClassGuidsFromName(string ClassName,
        ref Guid ClassGuidArray1stItem, UInt32 ClassGuidArraySize,
        out UInt32 RequiredSize);

    [DllImport("setupapi.dll")]
    internal static extern IntPtr SetupDiGetClassDevsEx(IntPtr ClassGuid,
        [MarshalAs(UnmanagedType.LPStr)]String enumerator,
        IntPtr hwndParent, Int32 Flags, IntPtr DeviceInfoSet,
        [MarshalAs(UnmanagedType.LPStr)]String MachineName, IntPtr Reserved);

    [DllImport("setupapi.dll")]
    internal static extern Int32 SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);

    [DllImport(@"setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern Boolean SetupDiEnumDeviceInterfaces(
       IntPtr hDevInfo,
       IntPtr optionalCrap, //ref SP_DEVINFO_DATA devInfo,
       ref Guid interfaceClassGuid,
       UInt32 memberIndex,
       ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData
    );

    [DllImport("setupapi.dll")]
    private static extern Int32 SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet,
        Int32 MemberIndex, ref SP_DEVINFO_DATA DeviceInterfaceData);

    [DllImport("setupapi.dll")]
    private static extern Int32 SetupDiClassNameFromGuid(ref Guid ClassGuid,
        StringBuilder className, Int32 ClassNameSize, ref Int32 RequiredSize);

    [DllImport("setupapi.dll")]
    private static extern Int32 SetupDiGetClassDescription(ref Guid ClassGuid,
        StringBuilder classDescription, Int32 ClassDescriptionSize, ref Int32 RequiredSize);

    [DllImport("setupapi.dll")]
    private static extern Int32 SetupDiGetDeviceInstanceId(IntPtr DeviceInfoSet,
        ref SP_DEVINFO_DATA DeviceInfoData,
        StringBuilder DeviceInstanceId, Int32 DeviceInstanceIdSize, ref Int32 RequiredSize);

    [DllImport("setupapi.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SetupDiGetClassDevs(           // 1st form using a ClassGUID only, with null Enumerator
       ref Guid ClassGuid,
       IntPtr Enumerator,
       IntPtr hwndParent,
       int Flags
    );

    [DllImport(@"setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern Boolean SetupDiGetDeviceInterfaceDetail(
       IntPtr hDevInfo,
       ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData,
       ref SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData,
       UInt32 deviceInterfaceDetailDataSize,
       out UInt32 requiredSize,
       ref SP_DEVINFO_DATA deviceInfoData
    );

    /// <summary>
    /// The SetupDiGetDeviceRegistryProperty function retrieves the specified device property.
    /// This handle is typically returned by the SetupDiGetClassDevs or SetupDiGetClassDevsEx function.
    /// </summary>
    /// <param Name="DeviceInfoSet">Handle to the device information set that contains the interface and its underlying device.</param>
    /// <param Name="DeviceInfoData">Pointer to an SP_DEVINFO_DATA structure that defines the device instance.</param>
    /// <param Name="Property">Device property to be retrieved. SEE MSDN</param>
    /// <param Name="PropertyRegDataType">Pointer to a variable that receives the registry data Type. This parameter can be NULL.</param>
    /// <param Name="PropertyBuffer">Pointer to a buffer that receives the requested device property.</param>
    /// <param Name="PropertyBufferSize">Size of the buffer, in bytes.</param>
    /// <param Name="RequiredSize">Pointer to a variable that receives the required buffer size, in bytes. This parameter can be NULL.</param>
    /// <returns>If the function succeeds, the return value is nonzero.</returns>
    [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool SetupDiGetDeviceRegistryProperty(
        IntPtr DeviceInfoSet,
        ref SP_DEVINFO_DATA DeviceInfoData,
        uint Property,
        out UInt32 PropertyRegDataType,
        byte[] PropertyBuffer,
        uint PropertyBufferSize,
        out UInt32 RequiredSize);


    const int DIGCF_DEFAULT = 0x1;
    const int DIGCF_PRESENT = 0x2;
    const int DIGCF_ALLCLASSES = 0x4;
    const int DIGCF_PROFILE = 0x8;
    const int DIGCF_DEVICEINTERFACE = 0x10;
    const int INVALID_HANDLE_VALUE = -1;

    private static Guid[] GetClassGUIDs(string className)
    {
        UInt32 requiredSize = 0;
        Guid[] guidArray = new Guid[1];

        bool status = SetupDiClassGuidsFromName(className, ref guidArray[0], 1, out requiredSize);
        if (true == status)
        {
            if (1 < requiredSize)
            {
                guidArray = new Guid[requiredSize];
                SetupDiClassGuidsFromName(className, ref guidArray[0], requiredSize, out requiredSize);
            }
        }
        else
            throw new System.ComponentModel.Win32Exception();

        return guidArray;
    }


}
票数 25
EN

Stack Overflow用户

发布于 2010-11-16 04:41:04

This article的代码帮我完成了这项工作(他链接到了这篇文章,但他自己似乎没有在这里提供答案)。

代码语言:javascript
复制
using System.Management;
internal class ProcessConnection { 

   public static ConnectionOptions ProcessConnectionOptions()
   {
     ConnectionOptions options = new ConnectionOptions();
     options.Impersonation = ImpersonationLevel.Impersonate;
     options.Authentication = AuthenticationLevel.Default;
     options.EnablePrivileges = true;
     return options;
   }

   public static ManagementScope ConnectionScope(string machineName, ConnectionOptions options, string path)
   {
     ManagementScope connectScope = new ManagementScope();
     connectScope.Path = new ManagementPath(@"\\" + machineName + path);
     connectScope.Options = options;
     connectScope.Connect();
     return connectScope;
   }
}

public class COMPortInfo
{
   public string Name { get; set; }
   public string Description { get; set; }

   public COMPortInfo() { }     

   public static List<COMPortInfo> GetCOMPortsInfo()
   {
     List<COMPortInfo> comPortInfoList = new List<COMPortInfo>();

     ConnectionOptions options = ProcessConnection.ProcessConnectionOptions();
     ManagementScope connectionScope = ProcessConnection.ConnectionScope(Environment.MachineName, options, @"\root\CIMV2");

     ObjectQuery objectQuery = new ObjectQuery("SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0");
     ManagementObjectSearcher comPortSearcher = new ManagementObjectSearcher(connectionScope, objectQuery);

     using (comPortSearcher)
     {
       string caption = null;
       foreach (ManagementObject obj in comPortSearcher.Get())
       {
         if (obj != null)
         {
           object captionObj = obj["Caption"];
           if (captionObj != null)
           {
              caption = captionObj.ToString();
              if (caption.Contains("(COM"))
              {
                COMPortInfo comPortInfo = new COMPortInfo();
                comPortInfo.Name = caption.Substring(caption.LastIndexOf("(COM")).Replace("(", string.Empty).Replace(")",
                                                     string.Empty);
                comPortInfo.Description = caption;
                comPortInfoList.Add(comPortInfo);
              }
           }
         }
       }
     } 
     return comPortInfoList;
   } 
}

用法:

代码语言:javascript
复制
foreach (COMPortInfo comPort in COMPortInfo.GetCOMPortsInfo())
{
  Console.WriteLine(string.Format("{0} – {1}", comPort.Name, comPort.Description));
}
票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2937585

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档