Best way to detect USB Connection?

  • (2 Pages)
  • +
  • 1
  • 2

15 Replies - 18948 Views - Last Post: 23 July 2014 - 10:14 PM Rate Topic: -----

#1 martynball   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 128
  • Joined: 21-July 14

Best way to detect USB Connection?

Posted 23 July 2014 - 03:30 AM

Hey, I need to detect when a USB Device is attached, at the moment i'm using a timer to fetch all connected devices depending on their type:
public static List<System.IO.DriveInfo> GetConnectedDevices()
        {
            //Put all connected drives into an array
            System.IO.DriveInfo[] myDrives = System.IO.DriveInfo.GetDrives();

            List<System.IO.DriveInfo> Drives = new List<System.IO.DriveInfo>();

            return myDrives.Where(info => (info.DriveType == System.IO.DriveType.Removable && info.IsReady)).ToList();
        }


This works great, only thing is, I don't really want to have to run this code every second (currently using a timer I use for a click). So, I found this code online:

internal static class UsbNotification
        {
            public const int DbtDevicearrival = 0x8000; // system detected a new device        
            public const int DbtDeviceremovecomplete = 0x8004; // device is gone      
            public const int WmDevicechange = 0x0219; // device change event      
            private const int DbtDevtypDeviceinterface = 5;
            private static readonly Guid GuidDevinterfaceUSBDevice = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED"); // USB devices
            private static IntPtr notificationHandle;

            /// <summary>
            /// Registers a window to receive notifications when USB devices are plugged or unplugged.
            /// </summary>
            /// <param name="windowHandle">Handle to the window receiving notifications.</param>
            public static void RegisterUsbDeviceNotification(IntPtr windowHandle)
            {
                DevBroadcastDeviceinterface dbi = new DevBroadcastDeviceinterface
                {
                    DeviceType = DbtDevtypDeviceinterface,
                    Reserved = 0,
                    ClassGuid = GuidDevinterfaceUSBDevice,
                    Name = 0
                };

                dbi.Size = Marshal.SizeOf(dbi);
                IntPtr buffer = Marshal.AllocHGlobal(dbi.Size);
                Marshal.StructureToPtr(dbi, buffer, true);

                notificationHandle = RegisterDeviceNotification(windowHandle, buffer, 0);
            }

            /// <summary>
            /// Unregisters the window for USB device notifications
            /// </summary>
            public static void UnregisterUsbDeviceNotification()
            {
                UnregisterDeviceNotification(notificationHandle);
            }

            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern IntPtr RegisterDeviceNotification(IntPtr recipient, IntPtr notificationFilter, int flags);

            [DllImport("user32.dll")]
            private static extern bool UnregisterDeviceNotification(IntPtr handle);

            [StructLayout(LayoutKind.Sequential)]
            private struct DevBroadcastDeviceinterface
            {
                internal int Size;
                internal int DeviceType;
                internal int Reserved;
                internal Guid ClassGuid;
                internal short Name;
            }
        }


This is also perfect as it detects the "bubble" event of when a device is plugged in, the problem is, no matter how much I examine the code and try to understand it, I can't seem to adapt it so that I can see what type of device was plugged in, seems like it just notifies me when a device is plugged in but you can't get it's type.

I simply need some form of even listener which fires and event when Removable Storage is connected and also display information like it's VolumeLabel and Size ect...

Been reading these pages, but can't seem to understand how to use the functions to run some code when a USB Device is connected, from my understanding I would make an event listener to watch a function?
http://msdn.microsof...7(v=vs.85).aspx

Is This A Good Question/Topic? 0
  • +

Replies To: Best way to detect USB Connection?

#2 martynball   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 128
  • Joined: 21-July 14

Re: Best way to detect USB Connection?

Posted 23 July 2014 - 05:45 AM

Such a shame I can't edit my post...

Anyway, done some more reading into this subject, I have the below int's.

public const int WM_DEVICEARRIVAL = 0x8000; //Device has been connected
public const int WM_DEVICEREMOVED = 0x8004; //Device has been removed
public const int WM_DEVICECHANGE = 0x0219; // device change event


I have the below code, it sort of works. I'm not getting an messages from the current cases when I attach a device (SD Card Reader). But if I add the WM_DEVICECHANGE to the cases I get multiple messages, i'm assuming in the system connecting the device and getting it ready to use so it changes multiple times?

protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_DEVICEARRIVAL:
                    // The WParam value identifies what is occurring.
                    int n = (int)m.WParam;
                    MessageBox.Show("Device has been conneced!");
                    break;
                case WM_DEVICEREMOVED:
                    //Device has been removed
                    MessageBox.Show("Device has been removed!");
                    break;
            }
            base.WndProc(ref m);
        }


What am I doing wrong?
Was This Post Helpful? 0
  • +
  • -

#3 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7056
  • View blog
  • Posts: 23,994
  • Joined: 05-May 12

Re: Best way to detect USB Connection?

Posted 23 July 2014 - 05:52 AM

You are so close... See Detecting Media Insertion or Removal.

As a quick aside, anybody notice the sudden surge in question asking about detecting when storage devices are attached to the machine? Is there a fad or trend happening right now that I'm missing out on because I've been too busy at work?
Was This Post Helpful? 1
  • +
  • -

#4 martynball   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 128
  • Joined: 21-July 14

Re: Best way to detect USB Connection?

Posted 23 July 2014 - 05:52 AM

Did some debugging, here is what I get with the following code after I have connected a SD Card Reader.

Data:msg=0x219 (WM_DEVICECHANGE) hwnd=0xeb086e wparam=0x7 lparam=0x0 result=0x0
msg=0x219 (WM_DEVICECHANGE) hwnd=0xeb086e wparam=0x7 lparam=0x0 result=0x0
msg=0x219 (WM_DEVICECHANGE) hwnd=0xeb086e wparam=0x7 lparam=0x0 result=0x0
msg=0x219 (WM_DEVICECHANGE) hwnd=0xeb086e wparam=0x7 lparam=0x0 result=0x0
msg=0x219 (WM_DEVICECHANGE) hwnd=0xeb086e wparam=0x8000 lparam=0x618e150 result=0x0
msg=0x219 (WM_DEVICECHANGE) hwnd=0xeb086e wparam=0x7 lparam=0x0 result=0x0
msg=0x219 (WM_DEVICECHANGE) hwnd=0xeb086e wparam=0x7 lparam=0x0 result=0x0
msg=0x219 (WM_DEVICECHANGE) hwnd=0xeb086e wparam=0x7 lparam=0x0 result=0x0


Code:
public const int WM_DEVICEARRIVAL = 0x8000; //Device has been connected
        public const int WM_DEVICEREMOVED = 0x8004; //Device has been removed
        public const int WM_DEVICECHANGE = 0x0219; // device change event

protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_DEVICECHANGE:
                    // The WParam value identifies what is occurring.
                    int n = (int)m.WParam;
                    richTextBox1.AppendText(m.ToString() + Environment.NewLine);
                    break;
                case WM_DEVICEARRIVAL:
                    //Device has been removed
                    richTextBox1.AppendText(m.ToString() + Environment.NewLine);
                    break;
            }
            base.WndProc(ref m);
        }

Was This Post Helpful? 0
  • +
  • -

#5 martynball   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 128
  • Joined: 21-July 14

Re: Best way to detect USB Connection?

Posted 23 July 2014 - 06:00 AM

Got it working now, it detects devices being connected and disconnected, but it won't detect a SD card being plugged into the built in SD Card reader or an USB Card Reader... why not ?
Was This Post Helpful? 0
  • +
  • -

#6 martynball   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 128
  • Joined: 21-July 14

Re: Best way to detect USB Connection?

Posted 23 July 2014 - 06:09 AM

Sorry Skydiver didn't see your post, reading that link you added now.

Is that C#? There's a lot of objects that are defined elsewhere which I can't get my head around :S
Was This Post Helpful? 0
  • +
  • -

#7 martynball   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 128
  • Joined: 21-July 14

Re: Best way to detect USB Connection?

Posted 23 July 2014 - 06:36 AM

Below is my current code, still can't get it to detect when an SD Card has been inserted, the first "switch" statement isn't firing unless I attach a USB device. It will detect my USB Card Reader, but then not detect any cards plugged into that reader.

protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_DEVICECHANGE)
            {
                switch (m.WParam.ToInt32())
                {
                    case WM_DEVICEARRIVAL:
                        //Device connected
                        int devType = Marshal.ReadInt32(m.LParam, 4);
                        //…and is a Logical Volume (A storage device)
                        if (devType == DBT_DEVTYP_VOLUME)
                        {
                            richTextBox1.AppendText("SD Card has been instered!" + Environment.NewLine);
                        }
                        break;

                    case WM_DEVICEREMOVED:
                        //Device has been removed
                        richTextBox1.AppendText("Device has been removed!" + Environment.NewLine);
                        break;
                }
            }
            base.WndProc(ref m);
        }


Was This Post Helpful? 0
  • +
  • -

#8 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7056
  • View blog
  • Posts: 23,994
  • Joined: 05-May 12

Re: Best way to detect USB Connection?

Posted 23 July 2014 - 07:58 AM

Turn on the SetupAPI text logs and look at the SetupAPI.dev.log. If there is no entry there when the SD card is plugged in, then there's no way you'll get a device notification because as far as Windows is concerned it didn't see the event.
Was This Post Helpful? 0
  • +
  • -

#9 martynball   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 128
  • Joined: 21-July 14

Re: Best way to detect USB Connection?

Posted 23 July 2014 - 08:04 AM

View PostSkydiver, on 23 July 2014 - 07:58 AM, said:

Turn on the SetupAPI text logs and look at the SetupAPI.dev.log. If there is no entry there when the SD card is plugged in, then there's no way you'll get a device notification because as far as Windows is concerned it didn't see the event.


Been looking around online and it seems no one seems to have any luck. I've read that Shell32 has a lot of functionality for things like this.

Just trying to figure out how to use it now
Was This Post Helpful? 0
  • +
  • -

#10 martynball   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 128
  • Joined: 21-July 14

Re: Best way to detect USB Connection?

Posted 23 July 2014 - 08:20 AM

You got any idea how I would use Shell32 to detect SD Card's Skydriver?

Also, I have opened SetupAPI.dev.log, it's a huge file, where am I looking for a record?
Was This Post Helpful? 0
  • +
  • -

#11 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7056
  • View blog
  • Posts: 23,994
  • Joined: 05-May 12

Re: Best way to detect USB Connection?

Posted 23 July 2014 - 08:33 AM

Look at the time stamps. When you plug in the SD card, look at the events in the log file for that period of time. If there are no events at that time, then Windows didn't detect it. Search around for SetupAPI log parsers. There are a few of them floating around. That should help control the information overload when you look at the log files.
Was This Post Helpful? 0
  • +
  • -

#12 martynball   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 128
  • Joined: 21-July 14

Re: Best way to detect USB Connection?

Posted 23 July 2014 - 08:49 AM

View PostSkydiver, on 23 July 2014 - 08:33 AM, said:

Look at the time stamps. When you plug in the SD card, look at the events in the log file for that period of time. If there are no events at that time, then Windows didn't detect it. Search around for SetupAPI log parsers. There are a few of them floating around. That should help control the information overload when you look at the log files.


Changed the LogLevel to 0x00000070

Log errors, warnings and other information in verbose mode, plus time messages. All entries are time-stamped. Additional messages that can slow down the system, such as cache hits, are included.


then tried plugging in a card reader which gets detect with the above C# code, no new entries where added.
Was This Post Helpful? 0
  • +
  • -

#13 martynball   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 128
  • Joined: 21-July 14

Re: Best way to detect USB Connection?

Posted 23 July 2014 - 10:28 AM

Doesn't seem like this code is going to do what I want it to do, so for now I will just go back to using a timer as it does the job. Below is my code which will eventually populate a list with the connected devices, now I don't want it to keep updating this list every second if there are no new devices, or none have been unplugged.

What would be the best way to go about this? I was thinking keeping an additional List object with the devices to compare against, and if there is no change then don't update, but I can't for the life of me get this working, was thinking maybe using a reference in the method arguments?

private void timer1_Tick(object sender, EventArgs e)
        {
            //Scan for connected devices
            List<System.IO.DriveInfo> devices = JamSnaps.Functions.GetConnectedDevices();

            //Change icon if devices are plugged in
            if (devices.Count > 0)
            {
                //Change image to found
                richTextBox1.Text += "Found " + devices.Count + "devices connected!";
            }
            else
            {
                //Change image to searching
                richTextBox1.Text += "Found " + devices.Count + "devices connected!";
            }

            foreach (System.IO.DriveInfo item in devices)
            {
                richTextBox1.Text += item.VolumeLabel;
            }
        }  



Functions.cs
public static List<System.IO.DriveInfo> GetConnectedDevices(List<System.IO.DriveInfo> currentDrives)
        {
            //Put all connected drives into an array
            System.IO.DriveInfo[] myDrives = System.IO.DriveInfo.GetDrives();

            List<System.IO.DriveInfo> Drives = new List<System.IO.DriveInfo>();

            return myDrives.Where(info => (info.DriveType == System.IO.DriveType.Removable && info.IsReady)).ToList();
        }


Was This Post Helpful? 0
  • +
  • -

#14 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7056
  • View blog
  • Posts: 23,994
  • Joined: 05-May 12

Re: Best way to detect USB Connection?

Posted 23 July 2014 - 11:16 AM

Show us your code for your attempt to retain the list and check to see if there are changes.
Was This Post Helpful? 0
  • +
  • -

#15 martynball   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 128
  • Joined: 21-July 14

Re: Best way to detect USB Connection?

Posted 23 July 2014 - 03:50 PM

View PostSkydiver, on 23 July 2014 - 11:16 AM, said:

Show us your code for your attempt to retain the list and check to see if there are changes.


Not really got any, tried afew different things but none of them worked at all and I know I did it completely wrong.

I wanted to send a List object back to the GetConnectedDevices function to compare against, so then it wouldn't even need to send anything back every second which will save processing power.

-------

I had a thought to use the WndProc override and somehow make it workout if the device it has detected is a USB SD Card reader, then if it is I could run the above script every second to detect devices. Because then if the user uses a USB cable to the camera it should get detected and not need to refresh every second. Hope this makes sense.

There has got to be some way to just simple detect SD Card's being inserted as the AutoPlay fires, doesn't Shell32 control AutoPlay? Is there not a custom written dll which can listen for this?
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2