Click here to Skip to main content
15,867,704 members
Articles / Desktop Programming / WPF

A USB Library to Detect USB Devices

Rate me:
Please Sign up or sign in to vote.
4.90/5 (122 votes)
21 Sep 2014CPOL3 min read 706.8K   87.8K   444   206
A USB library to detect USB devices, and manage Attach and Detach events

 

 

Introduction 

This article is about a USB library which enables you to manage Attach and Detach events of USB devices and detect your own device. I was not able to find a working code written in C# and which runs under both Windows XP and Windows 7 x64. I therefore decided to write my own code. I read various articles about USB Attach and Detach detection, and got some help from both the Microsoft website and the PINVOKE.NET website (http://www.pinvoke.net).

This code is a separate module that you can link to your own project. The code explains how to add additional properties.

Using the Code

Updating your Code

Windows Forms 

  • Add a reference to your project.
  • Add the using directive in your code:
    C#
    using USBClassLibrary;
  • Declare an instance of USBClass.
    C#
    private USBClassLibrary.USBClass USBPort;
  • Declare an instance List<T> of DeviceProperties if you want to read the properties of your devices.
    C#
    private List<USBClassLibrary.USBClass.DeviceProperties> ListOfUSBDeviceProperties;
  • Create an instance of the USBClass class.
    C#
    USBPort = new USBClass();
  • Create an instance List<T> of DeviceProperties class.
    C#
    ListOfUSBDeviceProperties = new List<USBClassLibrary.USBClass.DeviceProperties>();
  • Add handlers for the events exposed by the USBClass class.
    C#
    USBPort.USBDeviceAttached += new USBClass.USBDeviceEventHandler(USBPort_USBDeviceAttached);
    USBPort.USBDeviceRemoved += new USBClass.USBDeviceEventHandler(USBPort_USBDeviceRemoved);
  • Register your form to receive Windows messages when devices are added or removed.
    C#
    USBPort.RegisterForDeviceChange(true, this.Handle);
  • Then, check if your device is not already connected:
    C#
    if (USBClass.GetUSBDevice(MyDeviceVID, MyDevicePID, 
                 ref ListOfUSBDeviceProperties, false))
    {
       //My Device is connected
       MyUSBDeviceConnected = true;
    }
  • Implement Attach and Detach handlers:
    C#
    private void USBPort_USBDeviceAttached(object sender, 
                 USBClass.USBDeviceEventArgs e)
    {
       if (!MyUSBDeviceConnected)
       {
          if (USBClass.GetUSBDevice(MyDeviceVID, MyDevicePID, 
                                    ref ListOfUSBDeviceProperties, false))
          {
             //My Device is connected
             MyUSBDeviceConnected = true;
          }
       }
    }
    private void USBPort_USBDeviceRemoved(object sender, 
                 USBClass.USBDeviceEventArgs e)
    {
       if (!USBClass.GetUSBDevice(MyDeviceVID, MyDevicePID, 
                                  ref ListOfUSBDeviceProperties, false))
       {
          //My Device is removed
          MyUSBDeviceConnected = false;
       }
    }
  • Handle Windows message in your form to pass them to the USBClass class:
    C#
    protected override void WndProc(ref Message m)
    {
       bool IsHandled = false;
       USBPort.ProcessWindowsMessage(m.Msg, m.WParam, m.LParam, ref IsHandled);
       base.WndProc(ref m);
    }

WPF 

  • Add a reference to your project.
  • Add the using directive in your code:
    C#
    using USBClassLibrary;
  • Declare an instance of USBClass.
    C#
    private USBClassLibrary.USBClass USBPort;
  • Declare an instance List<T> of the DeviceProperties class if you want to read the properties of your devices.
    C#
    private List<USBClassLibrary.USBClass.DeviceProperties> ListOfUSBDeviceProperties;
  • Create an instance of the USBClass class.
    C#
    USBPort = new USBClass();
  • Create an instance List<T> of the DeviceProperties class.
    C#
    ListOfUSBDeviceProperties = new List<USBClassLibrary.USBClass.DeviceProperties>(); 
  • Add handlers for the events exposed by the USBClass class.
    C#
    USBPort.USBDeviceAttached += new USBClass.USBDeviceEventHandler(USBPort_USBDeviceAttached);
    USBPort.USBDeviceRemoved += new USBClass.USBDeviceEventHandler(USBPort_USBDeviceRemoved);
  • Override OnSourceInitialized in order to:
    • Retrieve the Windows Handle
    • Add an event handler that receives all window messages
    • Register your form to receive Windows messages when devices are added or removed 
  • C#
    protected override void OnSourceInitialized(EventArgs e)
    {
       base.OnSourceInitialized(e);
       HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
       source.AddHook(WndProc);
       //USB Connection
       USBPort.RegisterForDeviceChange(true, source.Handle);
       USBTryMyDeviceConnection();
       MyUSBDeviceConnected = false;
    } 
  • Handle Windows message in your form to pass them to the USBClass class
    C#
    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
       USBPort.ProcessWindowsMessage(msg, wParam, lParam, ref handled);
                
       return IntPtr.Zero;
    }
  • Then, check if your device is not already connected:
  • C#
    if (USBClass.GetUSBDevice(MyDeviceVID, MyDevicePID, 
                 ref ListOfUSBDeviceProperties, false))
    {
       //My Device is connected
       MyUSBDeviceConnected = true;
    }
  • Implement Attach and Detach handlers:
    C#
    private void USBPort_USBDeviceAttached(object sender, 
                 USBClass.USBDeviceEventArgs e)
    {
       if (!MyUSBDeviceConnected)
       {
          if (USBClass.GetUSBDevice(MyDeviceVID, MyDevicePID, 
                                    ref ListOfUSBDeviceProperties, false))
          {
             //My Device is connected
             MyUSBDeviceConnected = true;
          }
       }
    }
    private void USBPort_USBDeviceRemoved(object sender, 
                 USBClass.USBDeviceEventArgs e)
    {
       if (!USBClass.GetUSBDevice(MyDeviceVID, MyDevicePID, 
                                  ref ListOfUSBDeviceProperties, false))
       {
          //My Device is removed
          MyUSBDeviceConnected = false;
       }
    } 

Getting the COM Port Associated to a USB Device

If your device emulates a Serial Port, then you can retrieve its COM Port.

The GetUSBDevice function has a fourth parameter GetCOMPort:

C#
public static bool GetUSBDevice(UInt32 VID, UInt32 PID, ref List<deviceproperties> ListOfDP, bool GetCOMPort, Nullable<uint32> MI=null)

Set its value to True in your connection code and retrieve the COM Port from the DeviceProperties structure:

C#
if (USBClass.GetUSBDevice(MyDeviceVID, MyDevicePID, 
             ref ListOfUSBDeviceProperties, true))
{
   String COMPort;
   //My Device is connected
   MyUSBDeviceConnected = true;
   COMPort = DP.COMPort;
}

Compiling

In the project properties, Build tab, do not select Any CPU in the "Platform target" drop down list, pick up x86 or x64.

Updating the Code

If you need to read other device properties, simply update the code as follows:

  • Look up the SetupDiGetDeviceRegistryProperty function in MSDN and find the property you want to get.
  • Add a new variable to the DeviceProperties matching the characteristics of your property:
    C#
    public struct DeviceProperties
    {
       public string FriendlyName;
       public string DeviceDescription;
       public string DeviceType;
       public string DeviceManufacturer;
       public string DeviceClass;
       public string DeviceLocation;
       public string DevicePath;
       public string DevicePhysicalObjectName;
       public string COMPort;
    }
  • Update the GetUSBDevice function:
    C#
    public static bool GetUSBDevice(UInt32 VID, UInt32 PID, ref List<deviceproperties> ListOfDP, bool GetCOMPort, Nullable<uint32> MI=null)
    {
       ...
        DP.DevicePhysicalObjectName = String.Empty;
        if (Win32Wrapper.SetupDiGetDeviceRegistryProperty(h, ref DevInfoData, 
          (UInt32)Win32Wrapper.SPDRP.SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, 
          ref RegType, intptrBuffer, BUFFER_SIZE, ref RequiredSize))
        {
          DP.DevicePhysicalObjectName = Marshal.PtrToStringAuto(intptrBuffer);
        }
        ...
    }

History

  • Feb 22, 2010
    • Article first published
  • Feb 26, 2010
    • Added code to retrieve the COM Port associated to USB Devices emulating a serial port
    • Updated documentation accordingly
  •  November 17, 2013
    • Added support to detect composite devices and fixed a bug where DeviceProperties strings were not intialized correctly. 
    • Updated Demo application by adding a "MI" field.
  • February 5, 2014
    • Added support for WPF applications: the USB Class Library is modified to remove any reference to Windows Forms specific objects. 
    • The code works on Windows 8 and Windows 8.1 too 
  • September 21, 2014
    • Added the capability to identify more than 1 identical devices returning an array of Device Properties.

 

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Other HP
France France
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionWhere is the .dll reference??? Pin
Alvaro Navas13-Oct-22 2:39
Alvaro Navas13-Oct-22 2:39 
QuestionSerious Bugs in Library Pin
Vincent Okeyo6-Jun-21 18:22
Vincent Okeyo6-Jun-21 18:22 
QuestionCOMport for USB composite device Pin
Member 1364887026-Nov-20 3:06
Member 1364887026-Nov-20 3:06 
AnswerRe: COMport for USB composite device Pin
Vincent Okeyo6-Jun-21 18:19
Vincent Okeyo6-Jun-21 18:19 
QuestionDevice not found Pin
Member 147434227-Oct-20 23:48
Member 147434227-Oct-20 23:48 
QuestionDuplicate device change event when USB arrived or removed Pin
TabZhang21-Oct-19 0:04
TabZhang21-Oct-19 0:04 
Questionusing USBClassLibrary; Pin
Kiosk Thesis6-Aug-19 19:20
Kiosk Thesis6-Aug-19 19:20 
QuestionCode to communicate with the MM932LC module through USB Pin
Member 1451411627-Jun-19 4:03
Member 1451411627-Jun-19 4:03 
QuestionI have a problem! Pin
Member 1446846124-May-19 21:40
Member 1446846124-May-19 21:40 
QuestionSPDRP_DEVTYPE Pin
Member 603143221-May-19 1:59
Member 603143221-May-19 1:59 
Question"USBClass" can not be found PinPopular
projesis22-Mar-19 17:06
projesis22-Mar-19 17:06 
QuestionIs planned porting to .Net Framework 4.x and AnyCPU? Pin
teos.devnet11-Feb-19 6:05
teos.devnet11-Feb-19 6:05 
QuestionUpdated Usb/Hid Detection Pin
TheChristian15-Jan-19 19:22
TheChristian15-Jan-19 19:22 
GeneralMy vote of 5 Pin
csharpbd2-Sep-18 8:29
professionalcsharpbd2-Sep-18 8:29 
GeneralMy vote of 5 Pin
Daryl Huang15-Mar-18 15:09
Daryl Huang15-Mar-18 15:09 
Questionhow to receive and send data to usb? Pin
lyhoai2006tc4-Jun-17 23:19
lyhoai2006tc4-Jun-17 23:19 
QuestionIssues with deployment Pin
colinwp9-Mar-17 6:00
colinwp9-Mar-17 6:00 
QuestionDisconnected and Device properties Pin
msogun16-Feb-17 9:03
msogun16-Feb-17 9:03 
QuestionThe code works fine with Any CPU, what am I missing? Pin
Saragani23-Dec-16 21:24
Saragani23-Dec-16 21:24 
QuestionFTDI .. not detected well Pin
Member 1094240416-Mar-16 15:45
Member 1094240416-Mar-16 15:45 
QuestionNOT WORKING WELL WITH FTDI COM PORT Pin
Member 1094240416-Mar-16 14:38
Member 1094240416-Mar-16 14:38 
AnswerRe: NOT WORKING WELL WITH FTDI COM PORT Pin
nick70328-Apr-16 4:25
nick70328-Apr-16 4:25 
Questiondont work with VB.NET Pin
buddhafragt17-Dec-15 13:27
buddhafragt17-Dec-15 13:27 
AnswerRe: dont work with VB.NET Pin
RafStudio5-Oct-16 6:34
RafStudio5-Oct-16 6:34 
QuestionDisconnected! Pin
pip01024-Sep-15 1:16
pip01024-Sep-15 1:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.