VB.NET 監控 USB 裝置插拔

為了可以監控 USB 裝置插拔, 採用 WMI(Windows Management Instrumentation) 來實現, 如果是在本機查詢的話, 不會有 CPU 佔用使用率的問題 (wmiprvse.exe), 但是在某遠端電腦的監控, 就會有 CPU 使用率過高的問題, 後來改用 WINPROC 處理 Windows 訊息, 不過要用到 window Setup API 由於程式編輯器是 VB.NET, 找到 VC++ 的源碼, 再一步步的轉譯, 再來就是測試, 後來寫成一個類別, 發現處理訊息要靠 Form 表單來觸發, 於是加上繼承類別 NativeWindow, 並使用 AssignHandle 方法, 因為不知道主程式表單的 handle 何時產生, 又加上 Timers.Timer 來監控主程式表單, 結果碰到跨執行緒的問題, 所以再加上 invoke 功能, 到此測試監控遠端電腦 USB 裝置插拔的功能正常, 也許還有 bug 和改進的空間, 繼續工作囉,...

留言

匿名表示…
不好意思..想請教一下..
請問你是怎麼去抓取USB設備的編號呀??
如果我想要用WIN32 API來控制USB停用再啟用不知道該怎麼做呢??希望可以請您指導一下!!先謝了
ROY寫道…
以下是 c# 的程式碼, 也許對您有幫助,

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;

private void button1_Click(object sender, EventArgs e)
{
RegistryKey delKey = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\USBSTOR", true);
delKey.SetValue("Start", "00000004",RegistryValueKind.DWord);
MessageBox.Show("USB MassStorage Disabled");
}

private void button2_Click(object sender, EventArgs e)
{
RegistryKey delKey = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Services\\USBSTOR",true);
delKey.SetValue("Start", "00000003", RegistryValueKind.DWord);
MessageBox.Show("USB MassStorage Enabled");
}

Google 大神搜尋關鍵字 "codeproject usb disable enable"...
ROY寫道…
自動掃描usb 裝置有插拔動作時:

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

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)
On Error Resume Next

If M.Msg = WM_DEVICECHANGE Then
Select Case M.WParam
Case DBT_DEVICEARRIVAL
Dim DevType As Integer = Marshal.ReadInt32(M.LParam, 4)
If DevType = DBT_DEVTYP_VOLUME Then
Dim Vol As New DEV_BROADCAST_VOLUME
Vol = Marshal.PtrToStructure(M.LParam, GetType(DEV_BROADCAST_VOLUME))

If Vol.Dbcv_Flags = 0 Then
For i = 0 To 20
If Math.Pow(2, i) = Vol.Dbcv_Unitmask Then
Dim Usb As String = Chr(65 + i) + ":\"
Msgbox (Usb)
Exit For
End If
Next
End If
End If
End Select
End If
MyBase.WndProc(M)
End Sub
Unknown寫道…
哈囉!!非常感激你的解答><"
雖然我是寫VB.NET的..裡面可能有些看不太懂XD
我現在遇到的問題讓我很困擾..其實我是用一條USB轉RS232的線來做傳輸的..傳輸過程是持續不間段的(工作需求XD)
但是有時候USB會突然當掉..當掉之後就得要把USB拔掉再插一次才能復原..
但是我有嘗試過從裝置管理員把它停用再啟用也能復原..所以我在想USB當掉時能不能透過WMI去找到這個裝置用程式把它停用在啟用呢?
另外USB轉RS232這個裝置在裝置管理員內他是顯示在通訊阜內的..這樣我找的方向應該是往停用USB還是停用RS232呢?
Unknown寫道…
不好意思!!一直打擾你
我發現我需要的是停用裝置跟啟用裝置的指令
不知道是否有這樣的指令或是api可以用呢?
如果可以是vb.net的話那就更感激了><
ROY寫道…
停用裝置跟啟用裝置的指令, 請參考以上 c# 的程式碼...
ROY寫道…
如果是USB RS232, 註冊機碼的位置為SYSTEM\\CurrentControlSet\\Services\\FTSER2K

熱門文章