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

孤街醉人 提交于 2019-12-11 06:36:31

问题


I'm trying to make a screen locker software, that unlocks only when the correct flash drive plugged in and locks when it's unplugged. So that I have searched and found some codes that detects flash drive. It works properly when there is only one flash drive but if there are more than one flash drive and I unplugged the one without pass, my software still locks the screen. Can anyone help with it?

here is my codes

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

回答1:


Since you can't get the device ID when the drive is removed, you can not tell which device was removed, all you know is SOMETHING was removed.

At that point you really need to scan and see if the expected drive is still connected.

You need to store the DriveLetter of the right USB Drive in the class when it is detected, then check it still exists when a drive is removed..

Something like

    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

Though if the drive letter does exist, you may want to check some other property of the drive to verify it is really the same key. Otherwise, some bright spark may reassign the drive letters on you.

Perhaps

drv.RootDirectory.CreationTime

Read and store that on detecting the Key, and use that stored value to test.

    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

ALSO: Don't use FSO, use the native VB.NET

My.Computer.FileSystem

objects instead.




回答2:


You can get device type if it's the only removable device and then do whatever you want

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

Codes are in Visual Basic language



来源:https://stackoverflow.com/questions/42259734/how-to-detect-first-plug-usb-flash-memory-on-vb-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!