是否有可能获得 PC 的物理 USB 端口数?
Is it possible to get PC's # of physical USB ports?
我正在尝试获取不同 Windows 操作系统的 PC 物理 USB 端口数。开始这似乎是一件容易的事,但现在我变得绝望了。
也许这个问题甚至无效,因为我不知道 USB 端口在硬件级别上是如何处理的。
我认为使用 WMI(C)
和 ManagementObjectSearcher
将是正确的路径,并且它返回正确的值...在某些操作系统上。或者这就是我的想法。
例如,我尝试了以下操作:
// >wmic path win32_usbhub get name
private const string UsbProperty = "Name";
private const string UsbPath = "Win32_USBHub";
private const string UsbPortName = "USB ROOT HUB";
...
// Get USB Ports
public IEnumerable<string> GetUsbPorts()
{
// All from Win32_USBHub where name contains USB ROOT HUB
return GetManagementObjectValues(UsbProperty, UsbPath).Where(name =>
CultureInfo.CurrentCulture.CompareInfo.IndexOf(
name, UsbPortName, CompareOptions.IgnoreCase) >= 0);
}
.
// Query
private static IEnumerable<string> GetManagementObjectValues(
string properties, string path, Func<object, string> formatter = null)
{
var values = new List<string>();
string query = string.Format("SELECT {0} FROM {1}", properties, path);
var search = new ManagementObjectSearcher(query);
try
{
foreach (ManagementObject item in search.Get())
{
string value = string.Empty;
foreach (string property in properties.Split(',')
.Select(prop => prop.Trim()))
{
if (item[property] == null)
continue;
if (value.Length > 0)
value += " ";
if (formatter != null)
value += formatter(item[properties]);
value += item[property].ToString();
}
values.Add(value.TrimEnd());
}
}
catch (Exception e)
{
if (e is ManagementException)
Logger.Warn(string.Format(
"Can't extract {0} properties of {1}", properties, path), e);
else
Logger.Error(e);
}
return values.Count >= 1 ? values : new List<string> { DefaultValue };
}
这似乎让我在 Windows8 上得到了正确的数量,但在 WindowsXP 上它完全关闭了。
接下来,我尝试了(例如)以下操作。我注意到在 Win8 上我有 USB<number>
作为 ExternalReferenceDesignator
但在 WinXP 上,有普通的 USB
作为 InternalReferenceDesignator
并且外部是空的。
对于 XP,这似乎工作得很好,但在 Win8 上,端口数量又是六 (6)。实际端口数为 3,扩展坞站为七 (7) 个。
// >wmic path Win32_PortConnector get ExternalReferenceDesignator,InternalReferenceDesignator
private const string UsbPortName = "USB";
private const string PortProperties =
"ExternalReferenceDesignator, InternalReferenceDesignator";
private const string PortPath = @"Win32_PortConnector";
...
public IEnumerable<string> GetEthernetPorts()
{
// All where external includes USB or internal equals USB
return GetManagementObjectValues(PortProperties, PortPath).Where(name =>
CultureInfo.CurrentCulture.CompareInfo.IndexOf(
name, UsbPortName, CompareOptions.IgnoreCase) >= 0 ||
string.Compare(name, UsbPortName, StringComparison.OrdinalIgnoreCase) == 0);
}
这有可能吗,还是我只是从错误的地方看?
然后回答我自己的问题:不,这是不可能的。
Win32_USBController
(或某些相关路径)的 WMIC 查询结果可能看起来是正确的,但您不能从中得出任何结论。有关连接器的信息也未存储在基板或任何其他位置。
例如,带有 Windows XP SP3 的旧戴尔 Latitude D830 具有三 (3) 个物理连接器,但 WMIC 和 USBView.exe
显示以下结果:
C:\>wmic path win32_usbcontroller get caption
Caption
Intel(R) ICH8 Family USB Universal Host Controller - 2834
Intel(R) ICH8 Family USB Universal Host Controller - 2835
Intel(R) ICH8 Family USB2 Enhanced Host Controller - 283A
Intel(R) ICH8 Family USB Universal Host Controller - 2830
Intel(R) ICH8 Family USB Universal Host Controller - 2831
Intel(R) ICH8 Family USB Universal Host Controller - 2832
Intel(R) ICH8 Family USB2 Enhanced Host Controller - 2836
我正在尝试获取不同 Windows 操作系统的 PC 物理 USB 端口数。开始这似乎是一件容易的事,但现在我变得绝望了。
也许这个问题甚至无效,因为我不知道 USB 端口在硬件级别上是如何处理的。
我认为使用 WMI(C)
和 ManagementObjectSearcher
将是正确的路径,并且它返回正确的值...在某些操作系统上。或者这就是我的想法。
例如,我尝试了以下操作:
// >wmic path win32_usbhub get name
private const string UsbProperty = "Name";
private const string UsbPath = "Win32_USBHub";
private const string UsbPortName = "USB ROOT HUB";
...
// Get USB Ports
public IEnumerable<string> GetUsbPorts()
{
// All from Win32_USBHub where name contains USB ROOT HUB
return GetManagementObjectValues(UsbProperty, UsbPath).Where(name =>
CultureInfo.CurrentCulture.CompareInfo.IndexOf(
name, UsbPortName, CompareOptions.IgnoreCase) >= 0);
}
.
// Query
private static IEnumerable<string> GetManagementObjectValues(
string properties, string path, Func<object, string> formatter = null)
{
var values = new List<string>();
string query = string.Format("SELECT {0} FROM {1}", properties, path);
var search = new ManagementObjectSearcher(query);
try
{
foreach (ManagementObject item in search.Get())
{
string value = string.Empty;
foreach (string property in properties.Split(',')
.Select(prop => prop.Trim()))
{
if (item[property] == null)
continue;
if (value.Length > 0)
value += " ";
if (formatter != null)
value += formatter(item[properties]);
value += item[property].ToString();
}
values.Add(value.TrimEnd());
}
}
catch (Exception e)
{
if (e is ManagementException)
Logger.Warn(string.Format(
"Can't extract {0} properties of {1}", properties, path), e);
else
Logger.Error(e);
}
return values.Count >= 1 ? values : new List<string> { DefaultValue };
}
这似乎让我在 Windows8 上得到了正确的数量,但在 WindowsXP 上它完全关闭了。
接下来,我尝试了(例如)以下操作。我注意到在 Win8 上我有 USB<number>
作为 ExternalReferenceDesignator
但在 WinXP 上,有普通的 USB
作为 InternalReferenceDesignator
并且外部是空的。
对于 XP,这似乎工作得很好,但在 Win8 上,端口数量又是六 (6)。实际端口数为 3,扩展坞站为七 (7) 个。
// >wmic path Win32_PortConnector get ExternalReferenceDesignator,InternalReferenceDesignator
private const string UsbPortName = "USB";
private const string PortProperties =
"ExternalReferenceDesignator, InternalReferenceDesignator";
private const string PortPath = @"Win32_PortConnector";
...
public IEnumerable<string> GetEthernetPorts()
{
// All where external includes USB or internal equals USB
return GetManagementObjectValues(PortProperties, PortPath).Where(name =>
CultureInfo.CurrentCulture.CompareInfo.IndexOf(
name, UsbPortName, CompareOptions.IgnoreCase) >= 0 ||
string.Compare(name, UsbPortName, StringComparison.OrdinalIgnoreCase) == 0);
}
这有可能吗,还是我只是从错误的地方看?
然后回答我自己的问题:不,这是不可能的。
Win32_USBController
(或某些相关路径)的 WMIC 查询结果可能看起来是正确的,但您不能从中得出任何结论。有关连接器的信息也未存储在基板或任何其他位置。
例如,带有 Windows XP SP3 的旧戴尔 Latitude D830 具有三 (3) 个物理连接器,但 WMIC 和 USBView.exe
显示以下结果:
C:\>wmic path win32_usbcontroller get caption
Caption
Intel(R) ICH8 Family USB Universal Host Controller - 2834
Intel(R) ICH8 Family USB Universal Host Controller - 2835
Intel(R) ICH8 Family USB2 Enhanced Host Controller - 283A
Intel(R) ICH8 Family USB Universal Host Controller - 2830
Intel(R) ICH8 Family USB Universal Host Controller - 2831
Intel(R) ICH8 Family USB Universal Host Controller - 2832
Intel(R) ICH8 Family USB2 Enhanced Host Controller - 2836