Solved

VB.Net Usb

Posted on 2010-09-04
9
879 Views
Last Modified: 2012-05-10
How would I create a loop that waits for a remmovable usb device (like a flash drive) to be plugged in, then when it is, show a messagebox?
0
Comment
Question by:XGenwareS
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
9 Comments
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 33603831

There is a couple of different ways you might get this information.

Using RegisterDeviceNotification() specify the global identifier for USB devices {A5DCBF10-6530-11D2-901F-00C04FB951ED}.

You won't need a loop because windows will broadcast the message to the WindowProc() so using this method would only require that you override WndProc() on your Form after registering the message.


 
0
 

Author Comment

by:XGenwareS
ID: 33603966
Could I please see an example of this?
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 33603973
Sure.. But I have to write an example so it will take few minutes...
0
Major Incident Management Communications

Major incidents and IT service outages cost companies millions. Often the solution to minimizing damage is automated communication. Find out more in our Major Incident Management Communications infographic.

 

Author Comment

by:XGenwareS
ID: 33604013
ya sure take your time. thanks alot!
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 33604192
Add the following example to the form (copy paste friendly)  =)

Imports System.Runtime.InteropServices
Imports Microsoft.Win32.SafeHandles
'egl1044
Public Class Form1
    ''' <summary>
    ''' Detect USB notifications.
    ''' </summary>
    ''' <param name="m"></param>
    ''' <remarks></remarks>
    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Dim lpdb As UsbNotification.DevBroadcastHdr
        Dim lpdbv As UsbNotification.DevBroadcastVolume
        Dim lpdbdi As UsbNotification.DevBroadcastDeviceInterface
        Static fUsb As Boolean
        If m.Msg = UsbNotification.WM_DEVICECHANGE Then
            Select Case m.WParam.ToInt32
                Case UsbNotification.DBT_DEVICEARRIVAL
                    lpdb = CType(m.GetLParam(lpdb.GetType), UsbNotification.DevBroadcastHdr)
                    If lpdb.dbch_devicetype = UsbNotification.DBT_DEVTYP_DEVICEINTERFACE Then
                        lpdbdi = CType(m.GetLParam(lpdbdi.GetType), UsbNotification.DevBroadcastDeviceInterface)
                        fUsb = True
                    End If
                    If lpdb.dbch_devicetype = UsbNotification.DBT_DEVTYP_VOLUME AndAlso fUsb Then
                        lpdbv = CType(m.GetLParam(lpdbv.GetType), UsbNotification.DevBroadcastVolume)
                        fUsb = False
                        ' Inserted
                        Debug.Print("Inserted @ drive= {0}", UsbNotification.GetDrive(lpdbv.DBCV_UnitMask))
                    End If
                Case UsbNotification.DBT_DEVICEREMOVECOMPLETE
                    lpdb = CType(m.GetLParam(lpdb.GetType), UsbNotification.DevBroadcastHdr)
                    If lpdb.dbch_devicetype = UsbNotification.DBT_DEVTYP_DEVICEINTERFACE AndAlso fUsb Then
                        lpdbdi = CType(m.GetLParam(lpdbdi.GetType), UsbNotification.DevBroadcastDeviceInterface)
                        fUsb = True
                    End If
                    If lpdb.dbch_devicetype = UsbNotification.DBT_DEVTYP_VOLUME Then
                        lpdbv = CType(m.GetLParam(lpdbv.GetType), UsbNotification.DevBroadcastVolume)
                        fUsb = False
                        ' Removed
                        Debug.Print("Removed @ drive= {0}", UsbNotification.GetDrive(lpdbv.DBCV_UnitMask))
                    End If
            End Select
        End If
        MyBase.WndProc(m)
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        UsbNotification.Start(Me.Handle)
    End Sub
    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        UsbNotification.Cancel()
    End Sub
End Class

''' <summary>
''' Registers for USB notifications.
''' </summary>
''' <remarks></remarks>
Public Class UsbNotification
    Public Const WM_DEVICECHANGE As Integer = &H219
    Public Const DBT_DEVICEARRIVAL As Integer = 32768
    Public Const DBT_DEVICEREMOVECOMPLETE As Integer = 32772
    Public Const DBT_DEVTYP_DEVICEINTERFACE As Integer = 5
    Public Const DBT_DEVTYP_VOLUME As Integer = &H2

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Public Structure DevBroadcastHdr
        Dim dbch_size As UInt32
        Dim dbch_devicetype As UInt32
        Dim dbch_reserved As UInt32
    End Structure
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Public Structure DevBroadcastDeviceInterface
        Dim dbcc_size As UInt32
        Dim dbcc_devicetype As UInt32
        Dim dbcc_reserved As UInt32
        Dim dbcc_classguid As Guid
        Dim dbcc_name As IntPtr
    End Structure
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Public Structure DevBroadcastVolume
        Dim DBCV_Size As UInt32
        Dim DBCV_DeviceType As UInt32
        Dim DBCV_Reserved As UInt32
        Dim DBCV_UnitMask As UInt32
        Dim DBCV_Flags As UInt16
    End Structure

    <DllImport("user32.dll", ExactSpelling:=False, SetLastError:=True, CharSet:=CharSet.Unicode)> _
    Private Shared Function RegisterDeviceNotification(ByVal hRecipient As IntPtr, _
                                                       ByRef NotificationFilter As DevBroadcastDeviceInterface, _
                                                       ByVal Flags As UInt32) As SafeDeviceNotificationHandle
    End Function

    Private Shared hDeviceNotify As SafeDeviceNotificationHandle = Nothing
    Private Sub New()
    End Sub
    Public Shared Sub Start(ByVal hRecipient As IntPtr)
        Dim dbd As DevBroadcastDeviceInterface = Nothing
        If hDeviceNotify IsNot Nothing Then
            UsbNotification.Cancel()
        End If
        dbd.dbcc_size = CUInt(Marshal.SizeOf(dbd))
        dbd.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE
        dbd.dbcc_classguid = New Guid("{A5DCBF10-6530-11D2-901F-00C04FB951ED}")
        hDeviceNotify = RegisterDeviceNotification(hRecipient, dbd, 0)
        If hDeviceNotify.IsInvalid Then
            Debug.Print("Failed")
        Else
            Debug.Print("Register OK")
        End If
    End Sub
    Public Shared Sub Cancel()
        If hDeviceNotify IsNot Nothing Then
            hDeviceNotify.Close()
            hDeviceNotify.Dispose()
            hDeviceNotify = Nothing
            Debug.Print("UnRegister OK")
        End If
    End Sub
    Public Shared Function GetDrive(ByVal UnitMask As UInteger) As String
        GetDrive = Chr(CInt(65 + (Math.Log(UnitMask) / Math.Log(2))))
    End Function
End Class

''' <summary>
''' Represents a wrapper class for a device notification handle.
''' </summary>
''' <remarks></remarks>
Public Class SafeDeviceNotificationHandle
    Inherits SafeHandleZeroOrMinusOneIsInvalid
    <DllImport("user32.dll", ExactSpelling:=True, SetLastError:=True, CharSet:=CharSet.Unicode)> _
    Private Shared Function UnregisterDeviceNotification(ByVal Handle As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    Private Sub New()
        MyBase.New(True)
    End Sub
    Protected Overloads Overrides Function ReleaseHandle() As Boolean
        Return UnregisterDeviceNotification(handle)
    End Function
End Class

Open in new window

0
 
LVL 29

Accepted Solution

by:
nffvrxqgrcfqvvc earned 500 total points
ID: 33604266
Whoops.. I made a minor mistake in the WndProc() in the above example @ line 31 the bit flag checksum should really be placed @ line 35. If you don't fix this then CDROM devices will also be detected on Removal.
Use the updated example below which is the fixed version of the above lines.

Imports System.Runtime.InteropServices
Imports Microsoft.Win32.SafeHandles
'egl1044
Public Class Form1
    ''' <summary>
    ''' Detect USB notifications.
    ''' </summary>
    ''' <param name="m"></param>
    ''' <remarks></remarks>
    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Dim lpdb As UsbNotification.DevBroadcastHdr
        Dim lpdbv As UsbNotification.DevBroadcastVolume
        Dim lpdbdi As UsbNotification.DevBroadcastDeviceInterface
        Static fUsb As Boolean
        If m.Msg = UsbNotification.WM_DEVICECHANGE Then
            Select Case m.WParam.ToInt32
                Case UsbNotification.DBT_DEVICEARRIVAL
                    lpdb = CType(m.GetLParam(lpdb.GetType), UsbNotification.DevBroadcastHdr)
                    If lpdb.dbch_devicetype = UsbNotification.DBT_DEVTYP_DEVICEINTERFACE Then
                        lpdbdi = CType(m.GetLParam(lpdbdi.GetType), UsbNotification.DevBroadcastDeviceInterface)
                        fUsb = True
                    End If
                    If lpdb.dbch_devicetype = UsbNotification.DBT_DEVTYP_VOLUME AndAlso fUsb Then
                        lpdbv = CType(m.GetLParam(lpdbv.GetType), UsbNotification.DevBroadcastVolume)
                        fUsb = False
                        ' Inserted
                        Debug.Print("Inserted @ drive= {0}", UsbNotification.GetDrive(lpdbv.DBCV_UnitMask))
                    End If
                Case UsbNotification.DBT_DEVICEREMOVECOMPLETE
                    lpdb = CType(m.GetLParam(lpdb.GetType), UsbNotification.DevBroadcastHdr)
                    If lpdb.dbch_devicetype = UsbNotification.DBT_DEVTYP_DEVICEINTERFACE Then
                        lpdbdi = CType(m.GetLParam(lpdbdi.GetType), UsbNotification.DevBroadcastDeviceInterface)
                        fUsb = True
                    End If
                    If lpdb.dbch_devicetype = UsbNotification.DBT_DEVTYP_VOLUME AndAlso fUsb Then
                        lpdbv = CType(m.GetLParam(lpdbv.GetType), UsbNotification.DevBroadcastVolume)
                        fUsb = False
                        ' Removed
                        Debug.Print("Removed @ drive= {0}", UsbNotification.GetDrive(lpdbv.DBCV_UnitMask))
                    End If
            End Select
        End If
        MyBase.WndProc(m)
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        UsbNotification.Start(Me.Handle)
    End Sub
    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        UsbNotification.Cancel()
    End Sub
End Class

''' <summary>
''' Registers for USB notifications.
''' </summary>
''' <remarks></remarks>
Public Class UsbNotification
    Public Const WM_DEVICECHANGE As Integer = &H219
    Public Const DBT_DEVICEARRIVAL As Integer = 32768
    Public Const DBT_DEVICEREMOVECOMPLETE As Integer = 32772
    Public Const DBT_DEVTYP_DEVICEINTERFACE As Integer = 5
    Public Const DBT_DEVTYP_VOLUME As Integer = &H2

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Public Structure DevBroadcastHdr
        Dim dbch_size As UInt32
        Dim dbch_devicetype As UInt32
        Dim dbch_reserved As UInt32
    End Structure
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Public Structure DevBroadcastDeviceInterface
        Dim dbcc_size As UInt32
        Dim dbcc_devicetype As UInt32
        Dim dbcc_reserved As UInt32
        Dim dbcc_classguid As Guid
        Dim dbcc_name As IntPtr
    End Structure
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Public Structure DevBroadcastVolume
        Dim DBCV_Size As UInt32
        Dim DBCV_DeviceType As UInt32
        Dim DBCV_Reserved As UInt32
        Dim DBCV_UnitMask As UInt32
        Dim DBCV_Flags As UInt16
    End Structure

    <DllImport("user32.dll", ExactSpelling:=False, SetLastError:=True, CharSet:=CharSet.Unicode)> _
    Private Shared Function RegisterDeviceNotification(ByVal hRecipient As IntPtr, _
                                                       ByRef NotificationFilter As DevBroadcastDeviceInterface, _
                                                       ByVal Flags As UInt32) As SafeDeviceNotificationHandle
    End Function

    Private Shared hDeviceNotify As SafeDeviceNotificationHandle = Nothing
    Private Sub New()
    End Sub
    Public Shared Sub Start(ByVal hRecipient As IntPtr)
        Dim dbd As DevBroadcastDeviceInterface = Nothing
        If hDeviceNotify IsNot Nothing Then
            UsbNotification.Cancel()
        End If
        dbd.dbcc_size = CUInt(Marshal.SizeOf(dbd))
        dbd.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE
        dbd.dbcc_classguid = New Guid("{A5DCBF10-6530-11D2-901F-00C04FB951ED}")
        hDeviceNotify = RegisterDeviceNotification(hRecipient, dbd, 0)
        If hDeviceNotify.IsInvalid Then
            Debug.Print("Failed")
        Else
            Debug.Print("Register OK")
        End If
    End Sub
    Public Shared Sub Cancel()
        If hDeviceNotify IsNot Nothing Then
            hDeviceNotify.Close()
            hDeviceNotify.Dispose()
            hDeviceNotify = Nothing
            Debug.Print("UnRegister OK")
        End If
    End Sub
    Public Shared Function GetDrive(ByVal UnitMask As UInteger) As String
        Return Chr(CInt(65 + (Math.Log(UnitMask) / Math.Log(2))))
    End Function
End Class

''' <summary>
''' Represents a wrapper class for a device notification handle.
''' </summary>
''' <remarks></remarks>
Public Class SafeDeviceNotificationHandle
    Inherits SafeHandleZeroOrMinusOneIsInvalid
    <DllImport("user32.dll", ExactSpelling:=True, SetLastError:=True, CharSet:=CharSet.Unicode)> _
    Private Shared Function UnregisterDeviceNotification(ByVal Handle As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    Private Sub New()
        MyBase.New(True)
    End Sub
    Protected Overloads Overrides Function ReleaseHandle() As Boolean
        Return UnregisterDeviceNotification(handle)
    End Function
End Class

Open in new window

0
 

Author Comment

by:XGenwareS
ID: 33604296
wow thx alot. ill try it out as soon as I get home
0
 

Author Comment

by:XGenwareS
ID: 33604601
I'm getting this error when I insert or remove a usb drive:

System.InvalidCastException: Conversion from string "Q" to type 'Integer' is not valid. ---> System.FormatException: Input string was not in a correct format.

Visual Studio isn't giving me the exact line the error is on. It just stops working. I had to run it without the debugger to get the error message
0
 

Author Comment

by:XGenwareS
ID: 33604646
Nvm I found the problem. It was at this line:

Debug.Print("Inserted @ drive= {0}", UsbNotification.GetDrive(lpdbv.DBCV_UnitMask))

I just changed it to:

 MsgBox("Inserted")

That seemed to fix it. It works perfect now!
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video Micro Tutorial shows how to password-protect PDF files with free software. Many software products can do this, such as Adobe Acrobat (but not Adobe Reader), Nuance PaperPort, and Nuance Power PDF, but they are not free products. This vide…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question