Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a watcherprocess to detect a removeable USB Device?

Tags:

c#

.net

winapi

I build a little script that checks if a USB Stick with a given Name ist plugged into the Computer, but now I want to build a service around this Script to watch if the Stick plugged in or not. At first I try to do this with the filewatcher and create a file on the Stick but if remove the stick from the pc and replugged the filewatcher dosent realize it. The following script check one time if the Stick is plugged in or not, but I need a script to loop this DriveInfo.GetDrive function. I dont know if the best way is to buil a 10 second timer loop around this function or if there is any watcher class for removeable devices in the .NET Framework. Here comes the Script:

public static void Main()
{
    Run();
}

public static void Run()
{                     
    var drives = DriveInfo.GetDrives()
        .Where(drive => drive.IsReady && drive.DriveType == DriveType.Removable);
    if (drives.Count() > 0)
    {
        foreach (var drive in drives)
        {
           if (drive.VolumeLabel == "TESTLABEL") Console.WriteLine("USB Stick is plugged in");
        }
    }
}
like image 750
kockiren Avatar asked Aug 01 '13 16:08

kockiren


1 Answers

You can hook to (USB) Events using the ManagementEventWatcher.

Working example for LinqPad paraphrasing this neat answer which uses the Win32_DeviceChangeEvent:

// using System.Management;
// reference System.Management.dll
void Main()
{    
    using(var control = new USBControl()){
        Console.ReadLine();//block - depends on usage in a Windows (NT) Service, WinForms/Console/Xaml-App, library
    }
}

class USBControl : IDisposable
    {
        // used for monitoring plugging and unplugging of USB devices.
        private ManagementEventWatcher watcherAttach;
        private ManagementEventWatcher watcherDetach;

        public USBControl()
        {
            // Add USB plugged event watching
            watcherAttach = new ManagementEventWatcher();
            watcherAttach.EventArrived += Attaching;
            watcherAttach.Query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2");
            watcherAttach.Start();

            // Add USB unplugged event watching
            watcherDetach = new ManagementEventWatcher();
            watcherDetach.EventArrived += Detaching;
            watcherDetach.Query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 3");
            watcherDetach.Start();
        }

        public void Dispose()
        {
            watcherAttach.Stop();
            watcherDetach.Stop();
            //you may want to yield or Thread.Sleep
            watcherAttach.Dispose();
            watcherDetach.Dispose();
            //you may want to yield or Thread.Sleep
        }

        void Attaching(object sender, EventArrivedEventArgs e)
        {
            if(sender!=watcherAttach)return;
            e.Dump("Attaching");
        }

        void Detaching(object sender, EventArrivedEventArgs e)
        {
            if(sender!=watcherDetach)return;
            e.Dump("Detaching");
        }

        ~USBControl()
        {
            this.Dispose();// for ease of readability I left out the complete Dispose pattern
        }
    }

When attaching a USB-Stick I'll receive 7 attach (resp. detach) Events. Customize the Attaching/Detaching methods as you like. The blocking part is left to the reader, depending on his needs, with a Windows Service you wouldn't need to block at all.

like image 64
mbx Avatar answered Nov 06 '22 03:11

mbx