Windowsコンピューターに接続されているすべてのUSBデバイスのリストを取得するにはどうすればよいですか?
回答:
プロジェクトのSystem.Managementへの参照を追加し、次のようなことを試してください。
namespace ConsoleApplication1
{
using System;
using System.Collections.Generic;
using System.Management; // need to add System.Management to your project references.
class Program
{
static void Main(string[] args)
{
var usbDevices = GetUSBDevices();
foreach (var usbDevice in usbDevices)
{
Console.WriteLine("Device ID: {0}, PNP Device ID: {1}, Description: {2}",
usbDevice.DeviceID, usbDevice.PnpDeviceID, usbDevice.Description);
}
Console.Read();
}
static List<USBDeviceInfo> GetUSBDevices()
{
List<USBDeviceInfo> devices = new List<USBDeviceInfo>();
ManagementObjectCollection collection;
using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_USBHub"))
collection = searcher.Get();
foreach (var device in collection)
{
devices.Add(new USBDeviceInfo(
(string)device.GetPropertyValue("DeviceID"),
(string)device.GetPropertyValue("PNPDeviceID"),
(string)device.GetPropertyValue("Description")
));
}
collection.Dispose();
return devices;
}
}
class USBDeviceInfo
{
public USBDeviceInfo(string deviceID, string pnpDeviceID, string description)
{
this.DeviceID = deviceID;
this.PnpDeviceID = pnpDeviceID;
this.Description = description;
}
public string DeviceID { get; private set; }
public string PnpDeviceID { get; private set; }
public string Description { get; private set; }
}
}
私は古い質問に返信していることはわかっていますが、この同じ演習を行ってもう少し情報を見つけただけです。それは、この議論に大きく貢献し、この質問を見つけてどこにいるのかを見ている人を助けるのに役立つと思います既存の回答では不十分です。
受け入れ答えは近く、使用して修正することができNedkoさんのコメント、それまでに。関連するWMIクラスをより詳細に理解すると、全体像がわかりやすくなります。
Win32_USBHub
USB ハブのみを返します。それは後から明らかなように見えますが、上の議論はそれを逃しています。すべての可能なUSBデバイスが含まれるわけではなく、(理論的には)追加のデバイスのハブとして機能できるデバイスのみが含まれます。ハブではない一部のデバイス(特に複合デバイスの一部)が欠落しています。
Win32_PnPEntity
すべてのUSBデバイス、および数百の非USBデバイスが含まれます。 「USB%」で始まるDeviceIDのWHERE句検索を使用してリストをフィルタリングするというラッセルガントマンのアドバイスWin32_PnPEntity
は役に立ちますが、少し不完全です。Bluetoothデバイス、一部のプリンター/プリントサーバー、HID準拠のマウスとキーボードがありません。「USB \%」、「USBSTOR \%」、「USBPRINT \%」、「BTH \%」、「SWD \%」、「HID \%」を見ました。 Win32_PnPEntity
ただし、他のソースからのPNPDeviceIDを取得したら、情報を検索するための適切な「マスター」参照です。
私が見つけたのは、USBデバイスを列挙する最良の方法はクエリすることWin32_USBControllerDevice
でした。デバイスの詳細情報は提供しませんが、USBデバイスを完全に列挙し、PNPDeviceID
USBデバイス(ハブ、ハブ以外のデバイス、HID準拠デバイスを含む)ごとにの先行/従属のペアを提供しますシステム。クエリから返される各DependentはUSBデバイスです。Antecedentは、それが割り当てられているコントローラーであり、クエリによって返されるUSBコントローラーの1つですWin32_USBController
。
おまけとして、クエリに応答するとき、WMIは内部でデバイスツリーをたどるWin32_USBControllerDevice
ように見えるため、これらの結果が返される順序は、親子関係の識別に役立ちます。(これは文書化されておらず、したがって推測にすぎません。最終的な結果を得るには、SetupDi APIのCM_Get_Parent(またはChild + Sibling)を使用してください。)SetupDi APIのオプションとして、Win32_USBHub
それらの下にリストされているすべてのデバイスを検索できるようですレジストリ(でHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ + PNPDeviceID
)にありParentIdPrefix
、その子のPNPDeviceIDの最後のフィールドのプレフィックスとなるパラメータがあるため、これをワイルドカード一致で使用してWin32_PnPEntity
クエリをフィルタリングすることもできます。
私のアプリケーションでは、次のことを行いました。
Win32_PnPEntity
後で検索できるように、結果をクエリして(PNPDeviceIDをキーとして)Key-Valueマップに保存しました。後で個々のクエリを実行する場合、これはオプションです。Win32_USBControllerDevice
私のシステム上のUSBデバイスの決定的なリスト(すべての扶養家族)のために、これらのPNPDeviceIDsを抽出しました。デバイスツリーに続く順序に基づいてさらに進んで、デバイスをルートハブ(コントローラーではなく最初に返されるデバイス)に割り当て、parentIdPrefixに基づいてツリーを構築しました。クエリが返す順序は、SetupDiを介したデバイスツリーの列挙と一致し、各ルートハブ(Antecedentがコントローラーを識別する)の後に、その下にあるデバイス(例:システム)の反復が続きます。
Win32_USBController
。これにより、デバイスツリーの最上位にあるコントローラー(前のクエリの前提条件でした)のPNPDeviceIDの詳細情報が得られました。前のステップで派生したツリーを使用して、その子(ルートハブ)とその子(他のハブ)とその子(非ハブデバイスと複合デバイス)とその子などを再帰的に反復しました。
Win32_PnPEntity
し、PNPDeviceIdを使用して個別にクエリを実行して、このステップで情報を取得できます。おそらく、CPUとメモリのトレードオフで、どちらの順序が適切かを判断します。)要約すると、Win32USBControllerDevice
Dependentsは、システム上のUSBデバイスの完全なリスト(同じクエリ内の前提条件であるコントローラー自体以外)であり、これらのPNPDeviceId
ペアをレジストリーや他のクエリからの情報と相互参照することで、詳細な画像を作成できます。
興味のあるデバイスを確認するために、この投稿に基づいて、Adel Hazzahのコードを置き換えWin32_USBHub
ましWin32_PnPEntity
た。これは私にとってはうまくいきます:
namespace ConsoleApplication1
{
using System;
using System.Collections.Generic;
using System.Management; // need to add System.Management to your project references.
class Program
{
static void Main(string[] args)
{
var usbDevices = GetUSBDevices();
foreach (var usbDevice in usbDevices)
{
Console.WriteLine("Device ID: {0}, PNP Device ID: {1}, Description: {2}",
usbDevice.DeviceID, usbDevice.PnpDeviceID, usbDevice.Description);
}
Console.Read();
}
static List<USBDeviceInfo> GetUSBDevices()
{
List<USBDeviceInfo> devices = new List<USBDeviceInfo>();
ManagementObjectCollection collection;
using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_PnPEntity"))
collection = searcher.Get();
foreach (var device in collection)
{
devices.Add(new USBDeviceInfo(
(string)device.GetPropertyValue("DeviceID"),
(string)device.GetPropertyValue("PNPDeviceID"),
(string)device.GetPropertyValue("Description")
));
}
collection.Dispose();
return devices;
}
}
class USBDeviceInfo
{
public USBDeviceInfo(string deviceID, string pnpDeviceID, string description)
{
this.DeviceID = deviceID;
this.PnpDeviceID = pnpDeviceID;
this.Description = description;
}
public string DeviceID { get; private set; }
public string PnpDeviceID { get; private set; }
public string Description { get; private set; }
}
}
Adel Hazzahの答えは実用的なコードを提供し、Daniel WiddisとNedkoのコメントはWin32_USBControllerDeviceをクエリしてそのDependentプロパティを使用する必要があると述べ、Danielの答えはコードなしで多くの詳細を提供します。
接続されたすべてのUSBデバイスの直接アクセス可能なPNPデバイスプロパティをリストする作業コードを提供するための上記の議論の合成は次のとおりです。
using System;
using System.Collections.Generic;
using System.Management; // reference required
namespace cSharpUtilities
{
class UsbBrowser
{
public static void PrintUsbDevices()
{
IList<ManagementBaseObject> usbDevices = GetUsbDevices();
foreach (ManagementBaseObject usbDevice in usbDevices)
{
Console.WriteLine("----- DEVICE -----");
foreach (var property in usbDevice.Properties)
{
Console.WriteLine(string.Format("{0}: {1}", property.Name, property.Value));
}
Console.WriteLine("------------------");
}
}
public static IList<ManagementBaseObject> GetUsbDevices()
{
IList<string> usbDeviceAddresses = LookUpUsbDeviceAddresses();
List<ManagementBaseObject> usbDevices = new List<ManagementBaseObject>();
foreach (string usbDeviceAddress in usbDeviceAddresses)
{
// query MI for the PNP device info
// address must be escaped to be used in the query; luckily, the form we extracted previously is already escaped
ManagementObjectCollection curMoc = QueryMi("Select * from Win32_PnPEntity where PNPDeviceID = " + usbDeviceAddress);
foreach (ManagementBaseObject device in curMoc)
{
usbDevices.Add(device);
}
}
return usbDevices;
}
public static IList<string> LookUpUsbDeviceAddresses()
{
// this query gets the addressing information for connected USB devices
ManagementObjectCollection usbDeviceAddressInfo = QueryMi(@"Select * from Win32_USBControllerDevice");
List<string> usbDeviceAddresses = new List<string>();
foreach(var device in usbDeviceAddressInfo)
{
string curPnpAddress = (string)device.GetPropertyValue("Dependent");
// split out the address portion of the data; note that this includes escaped backslashes and quotes
curPnpAddress = curPnpAddress.Split(new String[] { "DeviceID=" }, 2, StringSplitOptions.None)[1];
usbDeviceAddresses.Add(curPnpAddress);
}
return usbDeviceAddresses;
}
// run a query against Windows Management Infrastructure (MI) and return the resulting collection
public static ManagementObjectCollection QueryMi(string query)
{
ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher(query);
ManagementObjectCollection result = managementObjectSearcher.Get();
managementObjectSearcher.Dispose();
return result;
}
}
}
必要に応じて、例外処理を追加する必要があります。デバイスツリーなどを理解したい場合は、ダニエルの回答を参照してください。
これは、リムーバブルUSBドライブのみを探している人にとってははるかに単純な例です。
using System.IO;
foreach (DriveInfo drive in DriveInfo.GetDrives())
{
if (drive.DriveType == DriveType.Removable)
{
Console.WriteLine(string.Format("({0}) {1}", drive.Name.Replace("\\",""), drive.VolumeLabel));
}
}
ManagementObjectSearcherを次のように変更した場合:
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
@"SELECT * FROM Win32_PnPEntity where DeviceID Like ""USB%""");
したがって、「GetUSBDevices()は次のようになります」
static List<USBDeviceInfo> GetUSBDevices()
{
List<USBDeviceInfo> devices = new List<USBDeviceInfo>();
ManagementObjectCollection collection;
using (var searcher = new ManagementObjectSearcher(@"SELECT * FROM Win32_PnPEntity where DeviceID Like ""USB%"""))
collection = searcher.Get();
foreach (var device in collection)
{
devices.Add(new USBDeviceInfo(
(string)device.GetPropertyValue("DeviceID"),
(string)device.GetPropertyValue("PNPDeviceID"),
(string)device.GetPropertyValue("Description")
));
}
collection.Dispose();
return devices;
}
}
結果はUSBデバイスに限定されます(システム上のすべてのタイプとは対照的)
このスレッドが役に立つかもしれません。そして、これを例示するgoogleコードプロジェクトを次に示します(P / Invokes into setupapi.dll
)。
lstResult.Clear();
foreach (ManagementObject drive in new ManagementObjectSearcher("select * from Win32_DiskDrive where InterfaceType='USB'").Get())
{
foreach (ManagementObject partition in new ManagementObjectSearcher("ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + drive["DeviceID"] + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition").Get())
{
foreach (ManagementObject disk in new ManagementObjectSearcher("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + partition["DeviceID"] + "'} WHERE AssocClass = Win32_LogicalDiskToPartition").Get())
{
foreach (var item in disk.Properties)
{
object value = disk.GetPropertyValue(item.Name);
}
string valor = disk["Name"].ToString();
lstResult.Add(valor);
}
}
}
}
object value
は何をしますか?