Как определить, какое устройство было подключено к USB-слоту?
Я хочу определить, когда пользователь подключает или удаляет звуковую карту USB. Мне удалось на самом деле поймать событие, когда это происходит, но я не могу сказать, что только что подключен.
Я попробовал подход, основанный на этом вопросе:
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).
РЕДАКТИРОВАТЬ: Основываясь на предложениях победившего автора, я создал полное решение, которое охватывает все функции.
3 ответа
Если я использую ваш первый код, я могу определить свое событие следующим образом:
// 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);
}
}
}
И это будет сбрасывать что-то вроде этого:
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
Он должен содержать все, что вам нужно, включая идентификатор устройства, который вы можете получить с чем-то вроде instance["DeviceID"]
,
РЕДАКТИРОВАТЬ 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"]);
}
}
}
Когда я попробовал решение @AngryHacker, я заметил, что DeviceChangedEventArgs
класс никогда не вызывали, хотя. Я удалил его и просто добавил Console.WriteLines()
в 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