Here, the ManagementEventWatcher is initialized on a Button.Click()
event. Of course, you can initialize it elsewhere. In Form.Load()
for example.
The ManagementEventWatcher.EventArrived event is subscribed, setting the delegate to private void DeviceInsertedEvent()
. The watching procedure is the started using ManagementEventWatcher.Start() (MOWatcher.Start();
)
When an event is notified, the EventArrivedEventArgs e.NewEvent.Properties["TargetInstance"].Value
will be set to a ManagementBaseObject, which will reference a Win32_DiskDrive WMI/CIM class.
Read the documentation to see what informations are available in this class.
This event is not rasised in the UI Thread. To notify the main UI interface of the nature of the event, we need to .Invoke() a method in that thread.
this.BeginInvoke((MethodInvoker)delegate { this.UpdateUI(DriveArrival, EventMessage); });
Here, the private void UpdateUI()
method is called, delegating the UI update to a method which is executed in the UI thread.
Update:
Added RegisterWindowMessage() to register QueryCancelAutoPlay, to prevent the AutoPlay window from popping up in front of our Form, stealing the focus.
A visual sample of the results:
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern uint RegisterWindowMessage(string lpString);
private uint CancelAutoPlay = 0;
private void button1_Click(object sender, EventArgs e)
{
WqlEventQuery query = new WqlEventQuery() {
EventClassName = "__InstanceOperationEvent",
WithinInterval = new TimeSpan(0, 0, 3),
Condition = @"TargetInstance ISA 'Win32_DiskDrive'"
};
ManagementScope scope = new ManagementScope("root\CIMV2");
using (ManagementEventWatcher MOWatcher = new ManagementEventWatcher(query))
{
MOWatcher.Options.Timeout = ManagementOptions.InfiniteTimeout;
MOWatcher.EventArrived += new EventArrivedEventHandler(DeviceChangedEvent);
MOWatcher.Start();
}
}
private void DeviceChangedEvent(object sender, EventArrivedEventArgs e)
{
using (ManagementBaseObject MOBbase = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)
{
bool DriveArrival = false;
string EventMessage = string.Empty;
string oInterfaceType = MOBbase.Properties["InterfaceType"]?.Value.ToString();
if (e.NewEvent.ClassPath.ClassName.Equals("__InstanceDeletionEvent"))
{
DriveArrival = false;
EventMessage = oInterfaceType + " Drive removed";
}
else
{
DriveArrival = true;
EventMessage = oInterfaceType + " Drive inserted";
}
EventMessage += ": " + MOBbase.Properties["Caption"]?.Value.ToString();
this.BeginInvoke((MethodInvoker)delegate { this.UpdateUI(DriveArrival, EventMessage); });
}
}
private void UpdateUI(bool IsDriveInserted, string message)
{
if (IsDriveInserted)
this.lblDeviceArrived.Text = message;
else
this.lblDeviceRemoved.Text = message;
}
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (CancelAutoPlay == 0)
CancelAutoPlay = RegisterWindowMessage("QueryCancelAutoPlay");
if ((int)m.Msg == CancelAutoPlay) { m.Result = (IntPtr)1; }
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…