Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用友好名称打开串行端口?_C#_Serial Port - Fatal编程技术网

C# 如何使用友好名称打开串行端口?

C# 如何使用友好名称打开串行端口?,c#,serial-port,C#,Serial Port,友好名称=出现在“设备管理器”中“端口(COM&LPT)”下的名称 编辑:下面提供了两个解决方案。一个使用WMI,另一个使用SetupAPI。发布今晚的代码,供大家欣赏: public class SetupDiWrap { static public string ComPortNameFromFriendlyNamePrefix(string friendlyNamePrefix) { const string className = "Ports";

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


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

发布今晚的代码,供大家欣赏:

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


}
public类SetupDiWrap
{
静态公共字符串ComPortNameFromFriendlyNamePrefix(字符串friendlyNamePrefix)
{
常量字符串className=“端口”;
Guid[]guids=GetClassGUIDs(className);
System.Text.RegularExpressions.Regex friendlyNameToComPort=
new System.Text.RegularExpressions.Regex(@“?\((COM\d+)\)$”;/“…(COMxxx)”->COMxxxx
foreach(Guid中的Guid)
{
//我们从设备树的“根”开始查找所有
//与磁盘的接口GUID匹配的设备
Guid guidClone=Guid;
IntPtr h=SetupDiGetClassDevs(参考guidClone、IntPtr.Zero、IntPtr.Zero、DIGCF|U PRESENT | DIGCF|U PROFILE);
如果(h.ToInt32()!=无效的句柄值)
{
int nDevice=0;
while(true)
{
SP_DEVINFO_DATA da=新SP_DEVINFO_DATA();
da.cbSize=(uint)Marshal.SizeOf(da);
如果(0==SetupDiEnumDeviceInfo(h,nDevice++,ref da))
打破
uint正则类型;
字节[]ptrBuf=新字节[缓冲区大小];
uint所需尺寸;
如果(设置数字设备逻辑属性(h,参考da,
(uint)SPDRP.FRIENDLYNAME,out RegType,ptrBuf,
缓冲区大小,超出所需大小)
{
常量int utf16terminatorSize_字节=2;
string friendlyName=System.Text.Unicode.Unicode.GetString(ptrBuf,0,(int)RequiredSize-utf16terminatorSize_字节);
如果(!friendlyName.StartsWith(friendlyNamePrefix))
继续;
如果(!friendlyNameToComPort.IsMatch(friendlyName))
继续;
返回friendlyNameToComPort.Match(friendlyName).Groups[1]。值;
}
}//设备
SetupDiDestroyDeviceInfo列表(h);
}
}//类GUID
返回null;
}
/// 
///SP_DEVINFO_数据结构定义了作为设备信息集成员的设备实例。
/// 
[StructLayout(LayoutKind.Sequential)]
私有结构SP_设备信息_数据
{
///结构的大小,以字节为单位。
公共单位cbSize;
///设备接口类的GUID。
公共Guid类Guid;
///此设备实例的句柄。
公共设备;
///保留;不要使用。
公共单位保留;
}
[StructLayout(LayoutKind.Sequential)]
专用结构SP_设备_接口_数据
{
公共Int32 cbSize;
公共Guid接口ClassGUID;
32面国旗;
保留私人UIntPtr;
}
const int BUFFER_SIZE=1024;
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
私有结构SP\u设备\u接口\u详细信息\u数据
{
公共机构的规模;
[Marshallas(UnmanagedType.ByValTStr,SizeConst=BUFFER\u SIZE)]
公共字符串设备路径;
}
私有枚举SPDRP
{
DEVICEDESC=0x00000000,
硬件ID=0x00000001,
COMPATIBLEIDS=0x00000002,
NTDevicePath=0x00000003,
服务=0x00000004,
配置=0x00000005,
CONFIGURATIONVECTOR=0x00000006,
类=0x00000007,
CLASSGUID=0x00000008,
驱动程序=0x00000009,
CONFIGFLAGS=0x0000000A,
制造商=0x0000000B,
FRIENDLYNAME=0x0000000C,
位置信息=0x0000000D,
物理设备对象名称=0x0000000E,
能力=0x0000000F,
UI_编号=0x00000010,
UPPERFILTERS=0x00000011,
LOWERFILTERS=0x00000012,
最大_属性=0x00000013,
}
[DllImport(“setupapi.dll”,SetLastError=true)]
静态外部布尔设置DiClassGuidsFromName(字符串类名称,
参考Guid CLASSGUIDARRAY1STIME,UInt32 ClassGuidArraySize,
out UInt32所需尺寸);
[DllImport(“setupapi.dll”)]
内部静态外部IntPtr SetupDiGetClassDevsEx(IntPtr类GUID,
[Marshallas(UnmanagedType.LPStr)]字符串枚举器,
IntPtr hwndParent、Int32标志、IntPtr设备信息集、,
[Marshallas(UnmanagedType.LPStr)]字符串MachineName,保留IntPtr);
[DllImport(“setupapi.dll”)]
内部静态外部Int32 SetupDiDestroyDeviceInfo列表(IntPtr DeviceInfo集);
[DllImport(@“setupapi.dll”,CharSet=CharSet.Auto,SetLastError=true)]
私有静态外部布尔SetupDienumDeviceInterface(
IntPtr hDevInfo,
IntPtr optionalCrap,//ref SP_DEVINFO_DATA DEVINFO,
ref Guid interfaceClassGuid,
UInt32成员索引,
参考SP_设备_接口_数据设备接口数据
);
[DllImport(“setupapi.dll”)]
专用静态外部程序Int32 SetupDiEnumDeviceInfo(IntPtr DeviceInfo,
Int32 MemberIndex,ref SP_DEVINFO_DATA DeviceInterfaceData);
[DllImport(“setupapi.dll”)]
私有静态外部Int32 SetupDiClassNameFromGuid(参考Guid ClassGuid,
StringBuilder类名称,Int32类名称,参考Int32 RequiredSize);
[DllImport(“setupapi.dll”)]
私有静态外部Int32 SetupDiGetClassDescription(参考Guid ClassGuid,
StringBuilder classDescription、Int32 ClassDescriptionSize、ref Int32 RequiredSize);
[DllImport(“setupapi.dll”)]
专用静态外部Int32 SetupDiGetDeviceInstanceId(IntPtr DeviceInfo集,
参考SP_设备信息_数据设备信息数据,
StringBuilder DeviceInstanceId、Int32 DeviceInstanceId、ref Int32 RequiredSize);
    Public Function foo() As Integer
    Try
        Dim searcher As New ManagementObjectSearcher( _
            "root\CIMV2", _
            "SELECT * FROM Win32_SerialPort")

        For Each queryObj As ManagementObject In searcher.Get()
            Debug.WriteLine(queryObj("Caption"))
            Debug.WriteLine(queryObj("Description"))
            Debug.WriteLine(queryObj("DeviceID"))
            Debug.WriteLine(queryObj("Name"))
            Debug.WriteLine(queryObj("PNPDeviceID"))

        Next
    Catch err As ManagementException
        Stop
    End Try
End Function

Public Function bar() As Integer
    Try
        Dim searcher As New ManagementObjectSearcher( _
            "root\CIMV2", _
            "SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0")

        For Each queryObj As ManagementObject In searcher.Get()
            If queryObj("Caption").ToString.Contains("(COM") Then
                Debug.WriteLine(queryObj("Caption"))
                Debug.WriteLine(queryObj("Description"))
                Debug.WriteLine(queryObj("DeviceID"))
                Debug.WriteLine(queryObj("Name"))
                Debug.WriteLine(queryObj("PNPDeviceID"))
            End If
        Next
    Catch err As ManagementException
        Stop
    End Try
End Function
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;
   } 
}
foreach (COMPortInfo comPort in COMPortInfo.GetCOMPortsInfo())
{
  Console.WriteLine(string.Format("{0} – {1}", comPort.Name, comPort.Description));
}
Dim searchFriendlyName = "Your Device Name".ToLower
Dim k0 = Registry.LocalMachine.OpenSubKey("SYSTEM\CurrentControlSet\Enum\USB\", False)
For Each k1Name In k0.GetSubKeyNames
    Dim k1 = k0.OpenSubKey(k1Name, False)
    For Each k2name In k1.GetSubKeyNames
        Dim k2 = k1.OpenSubKey(k2name, False)
        If k2.GetValueNames.Contains("FriendlyName") AndAlso k2.GetValue("FriendlyName").ToString.ToLower.Contains(searchFriendlyName) Then
            If k2.GetSubKeyNames.Contains("Device Parameters") Then
                Dim k3 = k2.OpenSubKey("Device Parameters", False)
                If k3.GetValueNames.Contains("PortName") Then
                    For Each s In SerialPort.GetPortNames
                        If k3.GetValue("PortName").ToString.ToLower = s.ToLower Then
                            Return s
                        End If
                    Next
                End If
            End If
        End If
    Next
Next
Dim mg As New System.Management.ManagementClass("Win32_SerialPort")
Try

    For Each i In mg.GetInstances()
        Dim name = i.GetPropertyValue("Name")
        If name IsNot Nothing AndAlso name.ToString.ToLower.Contains(searchFriendlyName.ToLower) Then
            Return i.GetPropertyValue("DeviceId").ToString
        End If
    Next
Finally
    mg.Dispose()
End Try
   private struct SP_DEVINFO_DATA
        {
            /// <summary>Size of the structure, in bytes.</summary>
            public int cbSize;
            /// <summary>GUID of the device interface class.</summary>
            public Guid ClassGuid;
            /// <summary>Handle to this device instance.</summary>
            public int DevInst;
            /// <summary>Reserved; do not use.</summary>
            public ulong Reserved;
        }
 da.cbSize = (uint)Marshal.SizeOf(da);
da.cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
 [DllImport("setupapi.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SetupDiGetClassDevs(       
           ref Guid ClassGuid,
           IntPtr Enumerator,
           IntPtr hwndParent,
           int Flags
        );
 [DllImport("setupapi.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SetupDiGetClassDevs( 
           ref Guid ClassGuid,
           UInt32 Enumerator,
           IntPtr hwndParent,
           UInt32 Flags
        );
IntPtr h = SetupDiGetClassDevs(ref guidClone, 0, IntPtr.Zero, DIGCF_PRESENT | DIGCF_PROFILE);