private static string GetDeviceName(IntPtr pDevInfoSet, SetupApi.SpDevInfoData deviceInfoData) { IntPtr hDeviceRegistryKey = SetupApi.SetupDiOpenDevRegKey(pDevInfoSet, deviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE); if (hDeviceRegistryKey == IntPtr.Zero) { throw new Exception("Failed to open a registry key for device-specific configuration information"); } var deviceNameBuf = new StringBuilder(256); try { uint lpRegKeyType; uint length = (uint)deviceNameBuf.Capacity; int result = RegQueryValueEx(hDeviceRegistryKey, "PortName", 0, out lpRegKeyType, deviceNameBuf, ref length); if (result != 0) { throw new Exception("Can not read registry value PortName for device " + deviceInfoData.ClassGuid); } } finally { RegCloseKey(hDeviceRegistryKey); } string deviceName = deviceNameBuf.ToString(); return(deviceName); }
/// <summary> /// Obtains the serial ports and their descriptions using SetupAPI. /// Prefered over the WMI implementation because it is significantly /// faster, but requires admin access. /// </summary> private static IEnumerable <SerialPortInfo> GetPortsSetupApi() { var guids = new[] { Guid.Parse(GUID_DEVINTERFACE_COMPORT2), // Guid.AddToBuffer(GUID_DEVINTERFACE_COMPORT) }; foreach (var guid in guids) { var guidCopy = guid; IntPtr hDeviceInfoSet = SetupApi.SetupDiGetClassDevs(ref guidCopy, null, IntPtr.Zero, SetupApi.DiGetFlags.Present); if (hDeviceInfoSet == IntPtr.Zero) { throw new Exception("Failed to get device information set for the COM ports"); } Int32 iMemberIndex = 0; while (true) { var deviceInfoData = new SetupApi.SpDevInfoData(); deviceInfoData.cbSize = (uint)Marshal.SizeOf(typeof(SetupApi.SpDevInfoData)); bool success = SetupApi.SetupDiEnumDeviceInfo(hDeviceInfoSet, (uint)iMemberIndex, deviceInfoData); if (!success) { // No more devices in the device information set break; } var spiq = new SerialPortInfo { Name = GetDeviceName(hDeviceInfoSet, deviceInfoData), }; GetRegistryProperties(spiq, hDeviceInfoSet, deviceInfoData); if (!string.IsNullOrEmpty(spiq.Name) && spiq.Name.Contains("COM")) { yield return(spiq); } iMemberIndex++; } SetupApi.SetupDiDestroyDeviceInfoList(hDeviceInfoSet); } }
private static void GetRegistryProperties(SerialPortInfo spiq, IntPtr hDeviceInfoSet, SetupApi.SpDevInfoData deviceInfoData) { var propertyBuffer = new StringBuilder(256); const uint propRegDataType = 0; uint length = (uint)propertyBuffer.Capacity; bool success = SetupApi.SetupDiGetDeviceRegistryProperty(hDeviceInfoSet, deviceInfoData, (int)SetupApi.SPDRP.SPDRP_DEVICEDESC, propRegDataType, propertyBuffer, length, out length); //if (!success) throw new Exception("Can not read registry for device " + deviceInfoData.ClassGuid); if (success) { spiq.Description = propertyBuffer.ToString(); } propertyBuffer = new StringBuilder(256); length = (uint)propertyBuffer.Capacity; success = SetupApi.SetupDiGetDeviceRegistryProperty(hDeviceInfoSet, deviceInfoData, (int)SetupApi.SPDRP.SPDRP_HARDWAREID, propRegDataType, propertyBuffer, length, out length); if (success) { spiq.HardwareID = propertyBuffer.ToString(); } }