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?
Visual Basic.NETC#.NET Programming

Avatar of undefined
Last Comment
XGenwareS

8/22/2022 - Mon
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.


 
XGenwareS

ASKER
Could I please see an example of this?
nffvrxqgrcfqvvc

Sure.. But I have to write an example so it will take few minutes...
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
XGenwareS

ASKER
ya sure take your time. thanks alot!
nffvrxqgrcfqvvc

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
nffvrxqgrcfqvvc

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
XGenwareS

ASKER
wow thx alot. ill try it out as soon as I get home
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
XGenwareS

ASKER
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
XGenwareS

ASKER
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!