private static Dictionary <string, string> GetDeviceIds(IntPtr hDevInfoSet, NativeMethods.DevInfoData devInfoData) { var buffer = new StringBuilder(256); var length = (uint)buffer.Capacity; NativeMethods.SetupDiGetDeviceRegistryProperty(hDevInfoSet, ref devInfoData, NativeMethods.DeviceInfoRegistryProperty.SPDRP_HARDWAREID, out _, buffer, length, out _); var result = new Dictionary <string, string>(); var regex = new Regex(@"(?<Enum>[^\\]*)\\((?<ID>[^&]+)&?)+"); //Matches 'USB\VID_123&PID_456&REV_001' or 'root\GenericDevice' var match = regex.Match(buffer.ToString()); if (!match.Success || !match.Groups["ID"].Success) { return(result); //empty result. The ID group should always match if the match succeeded. But testing here for completeness. } foreach (var id in match.Groups["ID"].Captures) { var splitIndex = id.ToString().IndexOf('_'); if (splitIndex < 0) { result.Add("GENERIC", id.ToString()); } else { result.Add(id.ToString().Substring(0, splitIndex), id.ToString().Substring(splitIndex + 1)); } } return(result); }
private static string GetDescription(IntPtr hDevInfoSet, NativeMethods.DevInfoData devInfoData) { var buffer = new StringBuilder(256); var length = (uint)buffer.Capacity; NativeMethods.SetupDiGetDeviceRegistryProperty(hDevInfoSet, ref devInfoData, NativeMethods.DeviceInfoRegistryProperty.SPDRP_DEVICEDESC, out _, buffer, length, out _); return(buffer.ToString()); }
private static string GetFriendlyName(IntPtr hDevInfoSet, NativeMethods.DevInfoData devInfoData) { var buffer = new StringBuilder(256); var length = (uint)buffer.Capacity; NativeMethods.SetupDiGetDeviceRegistryProperty(hDevInfoSet, ref devInfoData, NativeMethods.DeviceInfoRegistryProperty.SPDRP_FRIENDLYNAME, out _, buffer, length, out _); return(buffer.ToString()); }
public static IEnumerable <UsbSerialDevice> EnumerateDevices(bool presentOnly = true) { var hDevInfoSet = NativeMethods.SetupDiGetClassDevs( ref NativeMethods.GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR, null, IntPtr.Zero, presentOnly ? NativeMethods.DiGetClassFlags.DIGCF_PRESENT : 0); if (hDevInfoSet.ToInt64() == NativeMethods.INVALID_HANDLE_VALUE) { yield break; } try { var devInfoData = new NativeMethods.DevInfoData { CbSize = (uint)Marshal.SizeOf <NativeMethods.DevInfoData>() }; for (uint i = 0; NativeMethods.SetupDiEnumDeviceInfo(hDevInfoSet, i, ref devInfoData); i++) { var id = GetDeviceIds(hDevInfoSet, devInfoData); var device = new UsbSerialDevice { PortName = GetPortName(hDevInfoSet, devInfoData), FriendlyName = GetFriendlyName(hDevInfoSet, devInfoData), Description = GetDescription(hDevInfoSet, devInfoData), Vid = id.ContainsKey("VID") ? (int?)int.Parse(id["VID"], System.Globalization.NumberStyles.HexNumber) : null, Pid = id.ContainsKey("PID") ? (int?)int.Parse(id["PID"], System.Globalization.NumberStyles.HexNumber) : null, Rev = id.ContainsKey("REV") ? (int?)int.Parse(id["REV"], System.Globalization.NumberStyles.HexNumber) : null, }; yield return(device); } if (Marshal.GetLastWin32Error() != NativeMethods.NO_ERROR && Marshal.GetLastWin32Error() != NativeMethods.ERROR_NO_MORE_ITEMS) { throw new Win32Exception(Marshal.GetLastWin32Error(), $"Failed to enumerate USB serial devices. Error: [{Marshal.GetLastWin32Error()}] HR: [{Marshal.GetHRForLastWin32Error()}]"); } } finally { NativeMethods.SetupDiDestroyDeviceInfoList(hDevInfoSet); } }
private static string GetPortName(IntPtr hDevInfoSet, NativeMethods.DevInfoData devInfoData) { var hRegKey = NativeMethods.SetupDiOpenDevRegKey( hDevInfoSet, ref devInfoData, NativeMethods.DeviceInfoPropertyScope.DICS_FLAG_GLOBAL, 0, NativeMethods.DeviceInfoRegistryKeyType.DIREG_DEV, NativeMethods.RegistrySpecificAccessRights.KEY_QUERY_VALUE); if (hRegKey == IntPtr.Zero) { return(string.Empty); } var safeHandle = new SafeRegistryHandle(hRegKey, true); var key = RegistryKey.FromHandle(safeHandle); return(key.GetValue(@"PortName") as string); }