11

命令されたときに異なるインターフェイス、VID、PID、およびシリアル番号で列挙するUSB​​デバイスがあります。この変更が発生した後、物理デバイスを追跡したいと思います。私の考えは、ハブとポートの場所で追跡することでした。

Win32_PnPSignedDriverクラスには、完璧に見えた「場所」フィールドがありますが(たとえばPort_#0001.Hub_#0010)、ドライバーが最初にロードされたときのデバイスの場所のみが含まれています。ハードウェアを別のポートに接続しても、そのフィールドは更新されません。

ただし、デバイスマネージャでデバイスを表示すると、[詳細]タブの下に[位置情報]フィールドがあるため、情報はどこかで利用できます。この情報は、 WMIクエリまたはその他の方法で取得できますか?この問題を解決するためのより良いアプローチはありますか?

編集:私はこれが奇妙なシナリオのように聞こえることを知っています。これらのデバイスのマイクロコントローラーには、CDCデバイス(つまりシリアルポート)として列挙され、プログラミングを可能にするROMが含まれています。製造中に、製造元のROM(一意のVID / PID /シリアル番号)とカスタムファームウェアインターフェイス(異なるVID / PID /シリアル番号)の間でデバイスが変更されるため、デバイスを追跡すると便利です。

4

5 に答える 5

10

この回答についての活動からしばらく経ちましたが、私はこれと同様の機能を必要とするプロジェクトに取り組んでおり、それは確かに可能であると言えます。私の知る限り、DDKが必要であり、PInvokeこの情報用のC#またはWMIインターフェイスはありません。低レベルのUSBルートハブデバイスを開き、ドライバーIOCTLコマンドをそれらに直接送信する必要があります。

幸いなことに、Microsoftは、すべてのUSBデバイスを完全に列挙し、それらが接続されているポートを正確に表示するC++アプリケーションの例を提供しています。そのアプリケーションはUSBViewサンプルアプリケーションです

このアプリケーションをコンパイルして実行すると、デバイスが接続されている場所が正確に表示され、そのポートにデバイスを接続すると、同じ場所に表示されることがわかると思います。おそらく、C#アプリケーションが必要な情報を取得するために使用できるいくつかの呼び出しを提供するアンマネージC++DLLを作成する方が簡単かもしれません。

EnumerateHubPorts()コード内の関数について次のように述べています。

開いているハブへのハンドルとハブのダウンストリームポートの数を指定して、ハブの各ダウンストリームポートに対してIOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX要求を送信し、各ポートに接続されているデバイス(存在する場合)に関する情報を取得します。

これに必要なすべてについてのアイデアを与えるために(1つのポートのみに関心がある場合でも、すべてを上から列挙する必要があります)、enum.cコードのファイルの上部にリストされているコメントを次に示します。

/*

This source file contains the routines which enumerate the USB bus
and populate the TreeView control.

The enumeration process goes like this:

(1) Enumerate Host Controllers and Root Hubs
EnumerateHostControllers()
EnumerateHostController()
Host controllers currently have symbolic link names of the form HCDx,
where x starts at 0.  Use CreateFile() to open each host controller
symbolic link.  Create a node in the TreeView to represent each host
controller.

GetRootHubName()
After a host controller has been opened, send the host controller an
IOCTL_USB_GET_ROOT_HUB_NAME request to get the symbolic link name of
the root hub that is part of the host controller.

(2) Enumerate Hubs (Root Hubs and External Hubs)
EnumerateHub()
Given the name of a hub, use CreateFile() to map the hub.  Send the
hub an IOCTL_USB_GET_NODE_INFORMATION request to get info about the
hub, such as the number of downstream ports.  Create a node in the
TreeView to represent each hub.

(3) Enumerate Downstream Ports
EnumerateHubPorts()
Given an handle to an open hub and the number of downstream ports on
the hub, send the hub an IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX
request for each downstream port of the hub to get info about the
device (if any) attached to each port.  If there is a device attached
to a port, send the hub an IOCTL_USB_GET_NODE_CONNECTION_NAME request
to get the symbolic link name of the hub attached to the downstream
port.  If there is a hub attached to the downstream port, recurse to
step (2).  

GetAllStringDescriptors()
GetConfigDescriptor()
Create a node in the TreeView to represent each hub port
and attached device.
*/
于 2013-02-09T07:10:19.337 に答える
2

デバイスマネージャーの下の[位置情報]は、WMIから取得した文字列とまったく同じです。

デバイスが別のポートに接続されている場合、メタデータを新しい場所で更新する代わりに、Windowsが新しいドライバーインスタンスと新しいメタデータを作成することを考慮しましたか。現在接続されているものだけを対象にオブジェクトインスタンスをフィルタリングしてみてくださいWin32_PnPDevice。現在の場所情報が見つかると思います。

たとえば、USBマウスを別のポートに移動すると、デバイスマネージャの下にまだリストされている古いポートに関連付けられたマウスのコピーがあり、デフォルトでは非表示になっています。これらの切断されたデバイスを表示する手順については、 http://oreilly.com/pub/h/3105を参照してください。または、管理者特権のコマンドプロンプトから次のコマンドを実行します。

C:\Windows\system32>set devmgr_show_nonpresent_devices=1
C:\Windows\system32>devmgmt
于 2011-07-01T16:48:48.240 に答える
2

SetupDiを試しましたか?API関数のSetupDiクラスを使用して、DeviceManagerから情報を取得できます。

于 2011-07-01T16:39:00.833 に答える
0

参照:「Win32_PnPSignedDriverクラスには、完璧に見えた「場所」フィールド(Port_#0001.Hub_#0010など)がありますが、ドライバーが最初にロードされたときのデバイスの場所のみが含まれています。ハードウェアを別のポートに接続すると、そのフィールドを更新しないでください。」

それは私のためになります。ただし、ポートスワップ間でregeditアプリを更新(F5)してください。そうしないと、変更が表示されません。

ここではいくつかの例を示します。

ポート2ハブ
2ポート2ハブ4ポート3
ハブ4

于 2020-08-31T10:30:57.797 に答える
-2

より良いアイデアは、USBデバイスの一意のシリアル番号を使用することです。

于 2011-06-27T06:10:50.887 に答える