2013-05-18 58 views
12

ユーザーがUSBサウンドカードを差し込んだり、取り外したりしたときに検出したい。私は、この問題が発生したときに実際にイベントをキャッチするために管理してきましたが、私はちょうどに差し込まれてしまったものを言うことができないUSBスロットにどのデバイスが接続されているかを特定するにはどうすればよいですか?

私はthis質問に基づいたアプローチを試してみました:私は、通知を得る一方で

string query = 
    "SELECT * FROM __InstanceCreationEvent " + 
    "WITHIN 2 " 
    + "WHERE TargetInstance ISA 'Win32_PnPEntity'"; 
var watcher = new ManagementEventWatcher(query); 
watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived); 
watcher.Start(); 

EventArrivedイベントを介して、私はプラグインされたばかりのデバイスの実際の名前をどのように判断するのか分かりません。私はすべてのプロパティを通過し、そこから頭や尾を作ることができませんでした。

var query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent where EventType = 1 or EventType = 2"); 
var watcher = new ManagementEventWatcher(query); 
watcher.EventArrived += watcher_EventArrived; 
watcher.Stopped += watcher_Stopped; 
watcher.Query = query; 
watcher.Start(); 

も無駄に:

は、私はまた、別のクエリを試してみました。プラグインまたは削除されたデバイスの名前を見つける方法はありますか?

最後に、USBサウンドカードがシステムに接続されたか、システムから取り外されたかを知りたいと思います。それはWindows 7とVistaでも動作するはずです(ただし、私はWin7のみで解決します)。

EDIT:受賞した提出者の提案に基づいて、私はfull solutionを作成してすべての機能をラップします。

+0

何RegisterDeviceNotificationイベントを使用してはどうですか? https://code.google.com/p/winusbnet/ –

+0

@SimonMourierこのライブラリは、USBデバイスを検出するのではなく、通信するためのものです。私はデバイスを検出する方法を示す例は見当たりませんし、APIにはこの目的に役立つものは何も見つかりません。 – AngryHacker

答えて

9

が、私はこのように私のイベントを定義することができます:

同じ問題を記述


二つのリンク

// define USB class guid (from devguid.h) 
    static readonly Guid GUID_DEVCLASS_USB = new Guid("{36fc9e60-c465-11cf-8056-444553540000}"); 

    static void watcher_EventArrived(object sender, EventArrivedEventArgs e) 
    { 
     ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"]; 
     if (new Guid((string)instance["ClassGuid"]) == GUID_DEVCLASS_USB) 
     { 
      // we're only interested by USB devices, dump all props 
      foreach (var property in instance.Properties) 
      { 
       Console.WriteLine(property.Name + " = " + property.Value); 
      } 
     } 
    } 

そして、これはこのような何かをダンプします:これは、あなたがinstance["DeviceID"]ようなもので取得することができ、デバイスIDを含む必要なすべてを、含まれている必要があり

Availability = 
Caption = USB Mass Storage Device 
ClassGuid = {36fc9e60-c465-11cf-8056-444553540000} 
CompatibleID = System.String[] 
ConfigManagerErrorCode = 0 
ConfigManagerUserConfig = False 
CreationClassName = Win32_PnPEntity 
Description = USB Mass Storage Device 
DeviceID = USB\VID_18A5&PID_0243\07072BE66DD78609 
ErrorCleared = 
ErrorDescription = 
HardwareID = System.String[] 
InstallDate = 
LastErrorCode = 
Manufacturer = Compatible USB storage device 
Name = USB Mass Storage Device 
PNPDeviceID = USB\VID_18A5&PID_0243\07072BE66DD78609 
PowerManagementCapabilities = 
PowerManagementSupported = 
Service = USBSTOR 
Status = OK 
StatusInfo = 
SystemCreationClassName = Win32_ComputerSystem 
SystemName = KILROY_WAS_HERE 

+0

deviceIDは問題なく機能しますが、実際のデバイスの名前はどのようにして取得できますか? 'Sennheiser USBヘッドセット' – AngryHacker

+0

GUID_DEVCLASS_USBチェックなしでそのコードを実行しようとしましたか?それは、デバイスの別のタイプ(クラス)として識別されてもよい。例えば、USBドライブを差し込むと、多くのイベント(USBデバイス、ハードディスク、ボリュームなど)が発生する可能性があります。 –

+0

はい、私は同じ問題に直面しています。 – AngryHacker

3

EDIT 1:ああ、USBストレージデバイスではなく、USBデバイスのみであることがわかります。私は別の解決策を探します。私はあなたの最初のコードを使用している場合

http://hintdesk.com/c-catch-usb-plug-and-unplug-event/

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/37123526-83fa-4e96-a767-715fe225bf28/

if (e.NewEvent.ClassPath.ClassName == "__InstanceCreationEvent") 
{ 
    Console.WriteLine("USB was plugged in"); 
    //Get disk letter 
    foreach (ManagementObject partition in new ManagementObjectSearcher(
"ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + mbo.Properties["DeviceID"].Value 
+ "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition").Get()) 
    { 
     foreach (ManagementObject disk in new ManagementObjectSearcher(
        "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" 
         + partition["DeviceID"] 
         + "'} WHERE AssocClass = Win32_LogicalDiskToPartition").Get()) 
     { 
      Console.WriteLine("Disk=" + disk["Name"]); 
     } 
    } 
} 
0

@AngryHackerソリューションを試したところ、DeviceChangedEventArgsクラスが呼び出されなかったことに気付きました。私はそれを削除し、ちょうどをwatcher_eventArrivedメソッドに追加しました。

DeviceChangedEventArgsの削除に加えて、ここに私の変更点は次のとおりです。

(at line 46 in EstablishedWatchEvents) 
// setup the query to monitor removal 
const string qryRemoval = "SELECT *" + "FROM __InstanceDeletionEvent " 
      + "WITHIN 2 " + "WHERE TargetInstance ISA 'Win32_PnPEntity' "; 

#region Events 

private void insertWatcher_EventArrived(object sender, EventArrivedEventArgs e) 
{ 

    var mbo = (ManagementBaseObject) e.NewEvent["TargetInstance"]; 
    if (new Guid((string) mbo["ClassGuid"]) == GUID_DEVCLASS_USB) 
    { 
     var deviceName = (string) mbo["Name"]; 
     Console.WriteLine(deviceName + " was inserted"); 

    } 
} 

private void removeWatcher_EventArrived(object sender, EventArrivedEventArgs e) 
{ 

    var mbo = (ManagementBaseObject)e.NewEvent["TargetInstance"]; 

    if (new Guid((string)mbo["ClassGuid"]) == GUID_DEVCLASS_USB) 
    { 
     var deviceName = (string)mbo["Name"]; 
     Console.WriteLine(deviceName + " was removed"); 
    } 
} 

#endregion 
関連する問題