如何检测 Vb.net 上第一个插入的 USB 闪存

how to detect first plug usb flash memory on Vb.net

我正在尝试制作一个锁屏软件,只有插入正确的闪存驱动器时才会解锁,拔出时会锁定。所以我搜索并找到了一些检测闪存驱动器的代码。当只有一个闪存驱动器时它可以正常工作但是如果有多个闪存驱动器并且我没有通过就拔掉了一个,我的软件仍然锁定屏幕。有人可以帮忙吗?

这是我的代码

Imports System.Runtime.InteropServices
Imports System.IO

Public Class Form1

Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
    e.Cancel = True
End Sub

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    Me.WindowState = FormWindowState.Maximized
    Me.TopMost = True
End Sub


Private Const WM_DEVICECHANGE As Integer = &H219
Private Const DBT_DEVICEARRIVAL As Integer = &H8000
Private Const DBT_DEVTYP_VOLUME As Integer = &H2
Private Const DBT_DEVICEREMOVECOMPLETE As Integer = &H8004


Public Structure DEV_BROADCAST_HDR
    Public dbch_size As Int32
    Public dbch_devicetype As Int32
    Public dbch_reserved As Int32
End Structure

Private Structure DEV_BROADCAST_VOLUME
    Public dbcv_size As Int32
    Public dbcv_devicetype As Int32
    Public dbcv_reserved As Int32
    Public dbcv_unitmask As Int32
    Public dbcv_flags As Int16
End Structure

Private Function GetDriveLetterFromMask(ByRef Unit As Int32) As Char
    For i As Integer = 0 To 25
        If Unit = (2 ^ i) Then
            Return Chr(Asc("A") + i)
        End If
    Next
End Function


Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)

    If m.Msg = WM_DEVICECHANGE Then
        If m.WParam.ToInt32 = DBT_DEVICEARRIVAL Then
            If CInt(m.WParam) = DBT_DEVICEARRIVAL Then
                Dim DeviceInfo As DEV_BROADCAST_HDR
                DeviceInfo = DirectCast(Marshal.PtrToStructure(m.LParam, GetType(DEV_BROADCAST_HDR)), DEV_BROADCAST_HDR)
                If DeviceInfo.dbch_devicetype = DBT_DEVTYP_VOLUME Then
                    Dim Volume As DEV_BROADCAST_VOLUME
                    Volume = DirectCast(Marshal.PtrToStructure(m.LParam, GetType(DEV_BROADCAST_VOLUME)), DEV_BROADCAST_VOLUME)
                    Dim DriveLetter As String = (GetDriveLetterFromMask(Volume.dbcv_unitmask) & ":\")
                    If IO.File.Exists(IO.Path.Combine(DriveLetter, "password.info")) Then


                        Dim fso As Scripting.FileSystemObject
                        Dim oDrive As Scripting.Drive

                        fso = CreateObject("Scripting.FileSystemObject")

                        oDrive = fso.GetDrive(DriveLetter)


                        Dim passline As String() = File.ReadAllLines(DriveLetter & "password.info")

                        If passline(3) = "1120" & oDrive.SerialNumber Then
                            MessageBox.Show("Welcome!")
                            Me.TopMost = False
                            Me.WindowState = FormWindowState.Minimized

                        Else
                            MsgBox("This is not your password.")
                        End If

                    Else

                        MessageBox.Show("Password couldn't be found!")
                    End If
                End If
            End If
        End If
        If m.WParam.ToInt32 = DBT_DEVICEREMOVECOMPLETE Then

            Me.WindowState = FormWindowState.Maximized
            Me.TopMost = True
            MsgBox("Device is removed!")


        End If
    Else

    End If


    MyBase.WndProc(m)
End Sub

End Class

由于在删除驱动器时无法获取设备 ID,因此无法判断删除了哪个设备,您所知道的只是删除了一些东西。

此时您确实需要扫描并查看预期的驱动器是否仍处于连接状态。

您需要在检测到时将正确的 USB 驱动器的驱动器号存储在 class 中,然后在移除驱动器时检查它是否仍然存在..

类似

    Dim Key_Is_Gone = True
    For Each drv As DriveInfo In My.Computer.FileSystem.Drives
        If drv.Name = DriveLetter Then
            Key_Is_Gone = False
            Exit For 
        End If
    Next

    If Key_Is_Gone Then
         'Do what you have to do
    End If

虽然如果驱动器盘符确实存在,您可能需要检查驱动器的其他 属性 以验证它是否确实是相同的密钥。否则,一些明亮的火花可能会重新分配您的驱动器号。

也许

drv.RootDirectory.CreationTime

在检测到 Key 时读取并存储它,并使用该存储的值进行测试。

    Dim Key_Is_Gone = True
    For Each drv As DriveInfo In My.Computer.FileSystem.Drives
        If drv.Name = DriveLetter andalso drv.RootDirectory.CreationTime = DetectedKeyDate Then
            Key_Is_Gone = False
            Exit For 
        End If
    Next

    If Key_Is_Gone Then
         'Do what you have to do
    End If

另外:不要使用 FSO,使用原生 VB.NET

My.Computer.FileSystem

对象。

如果它是唯一的可移动设备,您可以获得设备类型,然后做任何您想做的事

Dim folder = New FolderBrowserDialog()
Dim drives = System.IO.DriveInfo.GetDrives()
Dim usbDrive = drives.FirstOrDefault(Function(m) m.DriveType = System.IO.DriveType.Removable)

For i As Integer = 0 To drives.Count - 1

    If drives(i).DriveType = System.IO.DriveType.Removable Then
       'Codes will not run if there were no removable device
       folder.SelectedPath = usbDrive.RootDirectory.FullName
       MessageBox.Show(folder.SelectedPath)
    End If

Next i

代码使用 Visual Basic 语言