2

I've been trying to create a quick app that detects a usb device has been pluged in to get all its information.

At the moment I've got as far as to detect all the usb devices plugged in but whenever I try to get the information of the plugged device I get an error in VB

this is my code.

Imports System.Management
Imports System.Runtime.InteropServices

Public Class Form1
    'Used to detected if any of the messages are any of these constants values.
    Private Const WM_DEVICECHANGE As Integer = &H219
    Private Const DBT_DEVICEARRIVAL As Integer = &H8000
    Private Const DBT_DEVICEREMOVECOMPLETE As Integer = &H8004
Private Const DBT_DEVTYP_VOLUME As Integer = &H2  '
'
'Get the information about the detected volume.
Private Structure DEV_BROADCAST_VOLUME
    Dim Dbcv_Size As Integer
    Dim Dbcv_Devicetype As Integer
    Dim Dbcv_Reserved As Integer
    Dim Dbcv_Unitmask As Integer
    Dim Dbcv_Flags As Short
End Structure

Protected Overrides Sub WndProc(ByRef M As System.Windows.Forms.Message)
    Dim USBClass As New System.Management.ManagementClass("Win32_USBHub")
    Dim USBCollection As System.Management.ManagementObjectCollection = USBClass.GetInstances()
    Dim USB As System.Management.ManagementObject

    If M.Msg = WM_DEVICECHANGE Then


        For Each USB In USBCollection
            RTextBox1.Text = RTextBox1.Text & "Description = " & USB("Name").ToString()
            RTextBox1.Text = RTextBox1.Text & "Device ID = " & USB("deviceid").ToString()
            RTextBox1.Text = RTextBox1.Text & "PNP Device ID = " & USB("PNPDeviceID").ToString()
        Next USB

    End If
    MyBase.WndProc(M)
End Sub


Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    ScanUSB()


End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    RTextBox1.Text = ""
End Sub

Private Sub ScanUSB()
    Dim strComputer As String
    Dim objWMIService As Object
    Dim colDevices As Object
    Dim strDeviceName As String
    Dim strQuotes As String
    Dim arrDeviceNames As Array
    Dim colUSBDevices As Object
    Dim objUSBDevice As Object
    Dim item2 As String


    strComputer = "."

    objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    colDevices = objWMIService.ExecQuery _
        ("Select * From Win32_USBControllerDevice")

    For Each objDevice In colDevices
        strDeviceName = objDevice.Dependent
        strQuotes = Chr(34)
        strDeviceName = Replace(strDeviceName, strQuotes, "")
        arrDeviceNames = Split(strDeviceName, "=")
        strDeviceName = arrDeviceNames(1)
        colUSBDevices = objWMIService.ExecQuery _
            ("Select * From Win32_PnPEntity Where DeviceID = '" & strDeviceName & "'")
        For Each objUSBDevice In colUSBDevices
            RTextBox1.Text = RTextBox1.Text & "Availability: " & objUSBDevice.Availability & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "Caption: " & objUSBDevice.Caption & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "ClassGuid: " & objUSBDevice.ClassGuid & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "ConfigManagerErrorCode: " & objUSBDevice.ConfigManagerErrorCode & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "ConfigManagerUserConfig: " & objUSBDevice.ConfigManagerUserConfig & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "CreationClassName: " & objUSBDevice.CreationClassName & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "Description: " & objUSBDevice.Description & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "DeviceID: " & objUSBDevice.DeviceID & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "ErrorCleared: " & objUSBDevice.ErrorCleared & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "ErrorDescription: " & objUSBDevice.ErrorDescription & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "InstallDate: " & objUSBDevice.InstallDate & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "LastErrorCode: " & objUSBDevice.LastErrorCode & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "Manufacturer: " & objUSBDevice.Manufacturer & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "Name: " & objUSBDevice.Name & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "PNPDeviceID: " & objUSBDevice.PNPDeviceID & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "PowerManagementCapabilities: " & objUSBDevice.PowerManagementCapabilities & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "PowerManagementSupported: " & objUSBDevice.PowerManagementSupported & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "Service: " & objUSBDevice.Service & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "Status: " & objUSBDevice.Status & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "StatusInfo: " & objUSBDevice.StatusInfo & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "SystemCreationClassName: " & objUSBDevice.SystemCreationClassName & Chr(13)
            RTextBox1.Text = RTextBox1.Text & "SystemName: " & objUSBDevice.SystemName & Chr(13)
            For Each item2 In objUSBDevice.HardwareID
                RTextBox1.Text = RTextBox1.Text & "HardwareID: " & item2 & Chr(13)
            Next
            RTextBox1.Text = RTextBox1.Text & objUSBDevice.Description() & Chr(13)
            RTextBox1.Text = RTextBox1.Text & Chr(13) & Chr(13)
        Next
    Next

End Sub

End Class

Kafe Cadm
  • 21
  • 1
  • 2
  • What error do you get? On which line of code? Without that information people here cannot really help you. – Ken Y-N May 19 '15 at 23:27
  • Transition into COM context 0x41dd08 for this RuntimeCallableWrapper failed with the following error: No se puede hacer una llamada de salida desde la aplicación que está ejecutando una llamada sincrónica de entrada. (Exception from HRESULT: 0x8001010D (RPC_E_CANTCALLOUT_ININPUTSYNCCALL)) The line is Dim USBCollection As System.Management.ManagementObjectCollection = USBClass.GetInstances() – Kafe Cadm May 20 '15 at 00:18
  • See [Watch for the Arrival and Removal of USB drives](http://stackoverflow.com/a/25187240/1070452) – Ňɏssa Pøngjǣrdenlarp May 20 '15 at 00:19
  • The problem is that there is nothing in the Win Msg to tell you WHICH device arrived or even if something was plugged in or removed. You have to start with a collection of devices, create a new collection when you get the Msg, then compare the 2 to see what has been added or removed. The test for arrival should be `m.Msg = WM_DEVICECHANGE AndAlso m.WParam.ToInt32 = DBT_DEVNODES_CHANGED` – Ňɏssa Pøngjǣrdenlarp May 20 '15 at 00:55
  • possible duplicate of [Monitor USB drives and retrieve device Info using a DeviceWatcher?](http://stackoverflow.com/questions/24944865/monitor-usb-drives-and-retrieve-device-info-using-a-devicewatcher) – Ňɏssa Pøngjǣrdenlarp Jun 10 '15 at 01:48

1 Answers1

1

Was struggling to find solution in VB.NET; Lots of resources in C#/C++ and I found this snippet which works like charm:

Imports System.Management ' Also had to add System.Management as a reference

Public Class Form1

    Private WithEvents m_MediaConnectWatcher As ManagementEventWatcher
    Public USBDriveName As String
    Public USBDriveLetter As String

    Public Sub StartDetection()
        ' __InstanceOperationEvent will trap both Creation and Deletion of class instances
        Dim query2 As New WqlEventQuery("SELECT * FROM __InstanceOperationEvent WITHIN 1 " _
  & "WHERE TargetInstance ISA 'Win32_DiskDrive'")

        m_MediaConnectWatcher = New ManagementEventWatcher
        m_MediaConnectWatcher.Query = query2
        m_MediaConnectWatcher.Start()
    End Sub


    Private Sub Arrived(ByVal sender As Object, ByVal e As System.Management.EventArrivedEventArgs) Handles m_MediaConnectWatcher.EventArrived

        Dim mbo, obj As ManagementBaseObject

        ' the first thing we have to do is figure out if this is a creation or deletion event
        mbo = CType(e.NewEvent, ManagementBaseObject)
        ' next we need a copy of the instance that was either created or deleted
        obj = CType(mbo("TargetInstance"), ManagementBaseObject)

        Select Case mbo.ClassPath.ClassName
            Case "__InstanceCreationEvent"
                If obj("InterfaceType") = "USB" Then
                    MsgBox(obj("Caption") & " (Drive letter " & GetDriveLetterFromDisk(obj("Name")) & ") has been plugged in")
                Else
                    MsgBox(obj("InterfaceType"))
                End If
            Case "__InstanceDeletionEvent"
                If obj("InterfaceType") = "USB" Then
                    MsgBox(obj("Caption") & " has been unplugged")
                    If obj("Caption") = USBDriveName Then
                        USBDriveLetter = ""
                        USBDriveName = ""
                    End If
                Else
                    MsgBox(obj("InterfaceType"))
                End If
            Case Else
                MsgBox("nope: " & obj("Caption"))
        End Select
    End Sub

    Private Function GetDriveLetterFromDisk(ByVal Name As String) As String
        Dim oq_part, oq_disk As ObjectQuery
        Dim mos_part, mos_disk As ManagementObjectSearcher
        Dim obj_part, obj_disk As ManagementObject
        Dim ans As String = ""

        ' WMI queries use the "\" as an escape charcter
        Name = Replace(Name, "\", "\\")

        ' First we map the Win32_DiskDrive instance with the association called
        ' Win32_DiskDriveToDiskPartition. Then we map the Win23_DiskPartion
        ' instance with the assocation called Win32_LogicalDiskToPartition

        oq_part = New ObjectQuery("ASSOCIATORS OF {Win32_DiskDrive.DeviceID=""" & Name & """} WHERE AssocClass = Win32_DiskDriveToDiskPartition")
        mos_part = New ManagementObjectSearcher(oq_part)
        For Each obj_part In mos_part.Get()

            oq_disk = New ObjectQuery("ASSOCIATORS OF {Win32_DiskPartition.DeviceID=""" & obj_part("DeviceID") & """} WHERE AssocClass = Win32_LogicalDiskToPartition")
            mos_disk = New ManagementObjectSearcher(oq_disk)
            For Each obj_disk In mos_disk.Get()
                ans &= obj_disk("Name") & ","
            Next
        Next

        Return ans.Trim(","c)
    End Function

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        StartDetection()
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        m_MediaConnectWatcher.Stop()
        Application.Exit()
    End Sub

End Class

Ref: MSDN

wpcoder
  • 1,016
  • 11
  • 17