Link to home
Start Free TrialLog in
Avatar of XGenwareS
XGenwareS

asked on

VB.Net Usb

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?
Avatar of nffvrxqgrcfqvvc
nffvrxqgrcfqvvc


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.


 
Avatar of XGenwareS

ASKER

Could I please see an example of this?
Sure.. But I have to write an example so it will take few minutes...
ya sure take your time. thanks alot!
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

ASKER CERTIFIED SOLUTION
Avatar of nffvrxqgrcfqvvc
nffvrxqgrcfqvvc

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
wow thx alot. ill try it out as soon as I get home
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
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!