thongkorn โพสต์ 2019-2-1 15:03:43

[VB.NET] การตรวจจับ USB Flash Drive แบบอัตโนมัติตามค่าเวลาที่ตั้งไว้ด้วย WMI

http://www.g2gnet.com/webboard/images/vbnet/detectusb.png

บทความนี้ก็จะคล้ายๆกับเรื่อง Device Watcher ที่แอดมินจะกล่าวถึงต่อไปในตอนหน้า คือเป็นการดักหรือตรวจสอบ USB Flash Drive ที่เสียบอยู่กับเครื่องคอมพิวเตอร์ เพื่อทำการอ่านค่า Drive Letter, Model และหมายเลข Serial Number ด้วยการตั้งค่าเวลาในการดักตรวจสอบระดับวินาที ...

อย่าลืม Add Reference System.Management ก่อนการใช้งาน WMI (Windows Management Instrumentation) ทุกครั้ง ...

มาดูโค้ด VB.NET กันเถอะ ...
' / --------------------------------------------------------------------------------
' / Developer : Mr.Surapon Yodsanga (Thongkorn Tubtimkrob)
' / eMail : thongkorn@hotmail.com
' / URL: http://www.g2gnet.com (Khon Kaen - Thailand)
' / Facebook: https://www.facebook.com/g2gnet (For Thailand)
' / Facebook: https://www.facebook.com/commonindy (Worldwide)
' / MORE: http://www.g2gnet.com/webboard
' /
' / Purpose: Detect USB Flash Drive with WMI (Windows Management Instrumental)
' / Microsoft Visual Basic .NET (2010)
' /
' / This is open source code under @Copyleft by Thongkorn Tubtimkrob.
' / You can modify and/or distribute without to inform the developer.
' / --------------------------------------------------------------------------------

'// Don't forget add --> Reference --> System.Management
Imports System.Management

Public Class frmDetectUSBFlashDrive

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
      Timer1.Enabled = True
      For i As Byte = 0 To 60
            cmbTimer.Items.Add(i)
      Next
      cmbTimer.SelectedIndex = 5    ' 5 Second
      Timer1.Interval = Val(cmbTimer.Text) * 1000
      '// Start
      Call ReadUsbFlashSerialNo()
    End Sub

    ' / --------------------------------------------------------------------------------
    ' / Function to read Usb Flash Serial Number (Not Volume) and return value all drives.
    Sub ReadUsbFlashSerialNo()
      Dim strTemp As String = ""
      Dim strSerial As String = ""
      Dim strArr() As String
      Dim MaxLen As Byte = 0
      Dim idx As Byte = 0
      ' Initialize ListView Control
      With lvwData
            .View = View.Details
            .GridLines = True
            .FullRowSelect = True
            .HideSelection = False
            .MultiSelect = False
            .Columns.Add("Drive", lvwData.Width \ 3 - 130)
            .Columns.Add("Model", lvwData.Width \ 3 + 60)
            .Columns.Add("Physical Serial Number", lvwData.Width \ 3 + 40)
      End With
      Dim LV As ListViewItem
      Try
            ' Windows Query Language หรือ WQL "Win32_DiskDrive"
            Dim WmiQuery As String = "SELECT * FROM " & "Win32_DiskDrive"
            Dim WmiSearcher As New ManagementObjectSearcher(WmiQuery)
            For Each info As ManagementObject In WmiSearcher.Get()
                If info("InterfaceType") = "USB" Then
                  Dim strModel As String = (String.Format("{0}", info("Model")))
                  strTemp = (String.Format("{0}", info("PnPDeviceID")))
                  '// หาเครื่องหมาย \ ตัวแรก แต่เป็นการนับมาจากทางขวาด้วยคำสั่ง InStrRev (InStr จะนับจากทางซ้ายมาขวา)
                  '// เช่น "USBSTOR\DISK&VEN_&PROD_&REV_1.00\7&15FF80F3&0&__&0" <-- เจอหน้าเลข 7
                  strTemp = Mid(strTemp, InStrRev(strTemp, "\") + 1, Len(strTemp) - InStrRev(strTemp, "\") + 1)
                  '// ก็จะได้ "7&15FF80F3&0&__&0"
                  '// แยกชุดข้อมูลออกจากกันด้วยเครื่องหมาย &
                  strArr = strTemp.Split("&")
                  '//
                  For Count As Byte = 0 To strArr.Length - 1
                        '// หาความยาวสูงสุด เพราะนั่นแหละคือ Serial Number
                        If MaxLen < Len(strArr(Count)) Then
                            '// เก็บค่า Index เป็นคำตอบ
                            idx = Count
                            '// นำค่าความยาวมากที่สุดกลับไปเปรียบเทียบใหม่
                            MaxLen = Len(strArr(Count))
                        End If
                  Next
                  '// Put them into ListView Control.
                  '// Drive Letter
                  LV = lvwData.Items.Add(GetDriveLetterFromDisk(String.Format("{0}", info("Name"))))
                  '// Model
                  LV.SubItems.Add(Trim(strModel))
                  '// Physical Serial Number
                  LV.SubItems.Add(Replace(Trim(strArr(idx)), Chr(0), ""))
                End If
            Next
      Catch err As ManagementException
            MessageBox.Show("An error occurred while querying for WMI data: " & err.Message)
      End Try
    End Sub

    ' / --------------------------------------------------------------------------------
    ' / Function to read Usb Flash Drive Letter.
    Private Function GetDriveLetterFromDisk(ByVal Name As String) As String
      Dim qPart, qDisk As ObjectQuery
      Dim mPart, mDisk As ManagementObjectSearcher
      Dim objPart, objDisk As ManagementObject
      Dim DriveLetter 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
      qPart = New ObjectQuery("ASSOCIATORS OF {Win32_DiskDrive.DeviceID=""" & Name & """} WHERE AssocClass = Win32_DiskDriveToDiskPartition")
      mPart = New ManagementObjectSearcher(qPart)
      For Each objPart In mPart.Get()
            qDisk = New ObjectQuery("ASSOCIATORS OF {Win32_DiskPartition.DeviceID=""" & objPart("DeviceID").ToString & """} WHERE AssocClass = Win32_LogicalDiskToPartition")
            mDisk = New ManagementObjectSearcher(qDisk)
            For Each objDisk In mDisk.Get()
                DriveLetter &= objDisk("Name").ToString
            Next
      Next
      Return DriveLetter
    End Function

    ' / --------------------------------------------------------------------------------
    ' / Timer for trigger.
    Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
      lvwData.Clear()
      ReadUsbFlashSerialNo()
    End Sub

    Private Sub cmbTimer_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles cmbTimer.SelectedIndexChanged
      If Val(cmbTimer.Text) <> 0 Then
            Timer1.Enabled = True
            '// Multiply by 1000 ms.
            Timer1.Interval = Val(cmbTimer.Text) * 1000
      Else
            Timer1.Enabled = False
      End If
    End Sub
End Class
ดาวน์โหลดโค้ดต้นฉบับ VB.NET (2010) ได้ที่นี่ ...
หน้า: [1]
ดูในรูปแบบกติ: [VB.NET] การตรวจจับ USB Flash Drive แบบอัตโนมัติตามค่าเวลาที่ตั้งไว้ด้วย WMI