VB.NET で USBデバイス を検出する!
- ■ このページの目標
-
(1) ソフトを起動して…
(2) パソコンに PaSoRi を接続すると…
(3) PaSoRi のデバイス情報が表示されることを目標とします!
- ■ プログラム作成に必要な物
-
(1) Visual Basic 2005, 2008, 2010, 2012 のいずれかで Express Edition がインストールされていれば十分です。
プロジェクトを新規作成する時に、ターゲットとなる .NET Framework のバージョンは 2.0 でかまいません。
(2) FeliCaポートソフトウェア がインストールされていること。
PaSoRi があれば、付属のCDにドライバが入ってるはずなので、そこからインストールして下さい。
手元にCDがない場合は こちら からダウンロードしてインストールして下さい。
(3) PaSoRi
対応機種: RC-S380 / S370 / S330 / S320
- ■ VB.NET で USBデバイス(PaSoRi) を検出するサンプル
-
※VB 2005 (.NET Framework 2.0) 以降を対象としています。
※ライセンスは特に設けておりませんので、使いたい方がいれば自由に使って頂いてかまいません。
ただし、このサンプルを使用した事でいかなる損害が発生しても責任は負いかねますので、自己責任でお願い致します。
[ Visual Basic .NET ]
まず、プロジェクトを新規作成して、プロパティ画面で参照を追加します。
System.Management を追加して下さい。 ※WMI (Windows Management Instrumentation) を使うために必要です。
Form1 に TextBox を貼り付けて、下記プロパティを設定して下さい。
[ Form1.vb ]
'************************************************************************ ' PaSoRiが抜き差しされたタイミングで詳細情報を取得します。 '------------------------------------------------------------------------ ' (1) WndProc() でUSBデバイスの抜き差しを検知します。 ' --> Windowsメッセージが WM_DEVICECHANGE の場合に処理 ' (2) 別スレッドでPaSoRiの情報を取得します。 ' --> WMI(Windows Management Instrumentation)を使用 ' WMIの情報取得に多少時間がかかるため、別スレッドで実行します。 ' (3) 別スレッドから画面のコントロールを操作します。 ' --> Delegateを宣言、Invokeで呼び出す '------------------------------------------------------------------------ ' VB.NETのマルチスレッドに関しては下記URLに具体的なサンプルがございます。 ' http://codezine.jp/article/detail/135?p=1 ' ' WMIに関しては下記URLを参考にしました。 ' http://www.wmifun.net/library/win32_pnpentity.html '************************************************************************ Imports System.Threading Imports System.Management Public Class Form1 '================ ' Win32 API 定数 '================ Private Const WM_DEVICECHANGE As Integer = &H219 'USBに抜き差しを検知 '================ ' フォームロード '================ Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load '------------------------------------- ' PaSoRi が接続済みの場合は情報を取得 '------------------------------------- thread_GetWMI() End Sub '================================================ ' 別スレッドから関数を呼び出すためのDelegate宣言 '================================================ Delegate Sub txtWMI_Clear_Delegate() Delegate Sub txtWMI_Show_Delegate(ByVal msg As String) '=================================================== '【関数名】txtWMI_Clear '【引 数】なし '【戻り値】なし '--------------------------------------------------- ' txtWMI.Text に表示されているメッセージを消去する。 '=================================================== Private Sub txtWMI_Clear() txtWMI.Text = "" End Sub '=========================================== '【関数名】txtWMI_Show '【引 数】[in] String 表示するメッセージ '【戻り値】なし '------------------------------------------- ' txtWMI.Text に指定のメッセージを表示する。 '=========================================== Private Sub txtWMI_Show(ByVal msg As String) txtWMI.Text = msg End Sub '======================================================================== '【関数名】WndProc '【引 数】System.Windows.Forms.Message OSから送られたWindowsメッセージ '【戻り値】なし '------------------------------------------------------------------------ ' Windowsメッセージを処理します。 '======================================================================== Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) '-------------------- ' デバイス変更の検知 '-------------------- If m.Msg = WM_DEVICECHANGE Then '時間のかかる処理を別スレッドで実行 Dim th As New Thread(New ThreadStart(AddressOf thread_GetWMI)) th.Start() Return End If '---------------------------------------- ' 上記以外の場合はメッセージを処理しない '---------------------------------------- MyBase.WndProc(m) End Sub '=============================================================================== '【関数名】thread_GetWMI '【引 数】なし '【戻り値】なし '------------------------------------------------------------------------------- ' WMIの情報を取得して、txtWMI.Textに表示する。 ' デバイス名に PaSoRi が含まれていて、正常に動作しているものだけを抜き出します。 '=============================================================================== Private Sub thread_GetWMI() Try '-------------------------------- ' Delegate宣言した関数の使用準備 '-------------------------------- Dim txtWMIClear As New txtWMI_Clear_Delegate(AddressOf txtWMI_Clear) Dim txtWMIShow As New txtWMI_Show_Delegate(AddressOf txtWMI_Show) '-------------------------------- ' テキストボックスの情報をクリア '-------------------------------- Invoke(txtWMIClear) '-------------------- ' デバイス情報を取得 '-------------------- Dim oms As New ManagementObjectSearcher Dim omc As ManagementObjectCollection 'デバイス名に PaSoRi が含まれていて、正常に動作しているものを検索する oms.Query.QueryString = "select * from Win32_PnPEntity " & _ "where Name like '%PaSoRi%' and ConfigManagerErrorCode = 0" omc = oms.Get() Dim msg As String = "" For Each mo As ManagementObject In omc Dim list_CompatibleID As String() Dim list_HardwareID As String() Dim dt As New DateTime 'Availability Select Case mo.Item("Availability") Case 3 msg &= "Availability:[3] 電力 - 通常" Case 4 msg &= "Availability:[4] 電力 - 警告" Case 5 msg &= "Availability:[5] 電力 - テスト中" Case 10 msg &= "Availability:[10] 電力 - 低下" Case 13 msg &= "Availability:[13] 省電力 - 不明" Case 14 msg &= "Availability:[14] 省電力 - 低電力モード" Case 15 msg &= "Availability:[15] 省電力 - スタンバイ" Case 17 msg &= "Availability:[17] 省電力 - 警告" Case Else msg &= "Availability:" End Select msg &= vbNewLine 'Caption msg &= "Caption:" & mo.Item("Caption") & vbNewLine 'ClassGuid msg &= "ClassGuid:" & mo.Item("ClassGuid") & vbNewLine 'CompatibleID msg &= "CompatibleID:" If mo.Item("CompatibleID") IsNot Nothing Then list_CompatibleID = mo.Item("CompatibleID") For I As Integer = 0 To list_CompatibleID.Length() - 1 msg &= list_CompatibleID(I) If I <> list_CompatibleID.Length() - 1 Then msg &= ", " End If Next End If msg &= vbNewLine 'ConfigManagerErrorCode Select Case mo.Item("ConfigManagerErrorCode") Case 0 msg &= "ConfigManagerErrorCode:[0] " & _ "このデバイスは正常に動作しています。" Case 1 msg &= "ConfigManagerErrorCode:[1] " & _ "このデバイスは正しく構成されていません。" Case 2 msg &= "ConfigManagerErrorCode:[2] " & _ "このデバイスのドライバーを読み込めません。" Case 3 msg &= "ConfigManagerErrorCode:[3] " & _ "このデバイスのドライバーは壊れているか、" & _ "あるいはメモリまたは他のリソースが不足している状態で" & _ "システムが実行されている可能性があります。" Case 4 msg &= "ConfigManagerErrorCode:[4] " & _ "このデバイスは正常に動作していません。" & _ "ドライバーまたはレジストリが壊れている可能性があります。" Case 5 msg &= "ConfigManagerErrorCode:[5] " & _ "このデバイスのドライバーには Windows が管理できないリソースが必要です。" Case 6 msg &= "ConfigManagerErrorCode:[6] " & _ "このデバイスのブート構成が他のデバイスと競合しています。" Case 7 msg &= "ConfigManagerErrorCode:[7] " & _ "フィルター処理できません。" Case 8 msg &= "ConfigManagerErrorCode:[8] " & _ "デバイスのドライバー ローダーが見つかりません。" Case 9 msg &= "ConfigManagerErrorCode:[9] " & _ "このデバイスを制御するファームウェアからリソースが正しく報告されないため、" & _ "このデバイスは正常に動作していません。" Case 10 msg &= "ConfigManagerErrorCode:[10] " & _ "このデバイスを開始できません。" Case 11 msg &= "ConfigManagerErrorCode:[11] " & _ "このデバイスはエラーで停止しました。" Case 12 msg &= "ConfigManagerErrorCode:[12] " & _ "このデバイスで使用できる十分な空きリソースが見つかりません。" Case 13 msg &= "ConfigManagerErrorCode:[13] " & _ "このデバイスのリソースを確認できません。" Case 14 msg &= "ConfigManagerErrorCode:[14] " & _ "コンピューターを再起動するまでこのデバイスは正常に動作しません。" Case 15 msg &= "ConfigManagerErrorCode:[15] " & _ "このデバイスは、再列挙に問題が発生している可能性があり、" & _ "正常に動作していません。" Case 16 msg &= "ConfigManagerErrorCode:[16] " & _ "このデバイスで使用される一部のリソースを認識できません。" Case 17 msg &= "ConfigManagerErrorCode:[17] " & _ "このデバイスは不明なリソースの種類を要求しています。" Case 18 msg &= "ConfigManagerErrorCode:[18] " & _ "このデバイスのドライバーを再インストールしてください。" Case 19 msg &= "ConfigManagerErrorCode:[19] " & _ "レジストリが壊れている可能性があります。" Case 20 msg &= "ConfigManagerErrorCode:[20] " & _ "VxD ローダーの使用に失敗しました。" Case 21 msg &= "ConfigManagerErrorCode:[21] " & _ "システム エラー: このデバイスのドライバーを変更してみてください。" & _ "うまくいかない場合はハードウェアのマニュアルを参照してください。" & _ "このデバイスは削除されます。" Case 22 msg &= "ConfigManagerErrorCode:[22] " & _ "このデバイスは無効になっています。" Case 23 msg &= "ConfigManagerErrorCode:[23] " & _ "システム障害: このデバイスのドライバーを変更してみてください。" & _ "うまくいかない場合はハードウェアのマニュアルを参照してください。" Case 24 msg &= "ConfigManagerErrorCode:[24] " & _ "このデバイスは存在しないか、正常に動作していないか、" & _ "または一部のドライバーがインストールされていません。" Case 25 msg &= "ConfigManagerErrorCode:[25] " & _ "このデバイスはまだセットアップ処理中です。" Case 26 msg &= "ConfigManagerErrorCode:[26] " & _ "このデバイスはまだセットアップ処理中です。" Case 27 msg &= "ConfigManagerErrorCode:[27] " & _ "このデバイスに有効なログ構成がありません。" Case 28 msg &= "ConfigManagerErrorCode:[28] " & _ "このデバイスのドライバーはインストールされていません。" Case 29 msg &= "ConfigManagerErrorCode:[29] " & _ "このデバイスは、必要なリソースがデバイスのファームウェアから" & _ "提供されなかったため無効になっています。" Case 30 msg &= "ConfigManagerErrorCode:[30] " & _ "このデバイスは、他のデバイスが使用している" & _ "割り込み要求 (IRQ) リソースを使用しています。" Case 31 msg &= "ConfigManagerErrorCode:[31] " & _ "このデバイスは、このデバイスに必要なドライバーを" & _ "読み込めないため正常に動作していません。" Case Else msg &= "ConfigManagerErrorCode:" End Select msg &= vbNewLine 'ConfigManagerUserConfig If mo.Item("ConfigManagerUserConfig") Then msg &= "ConfigManagerUserConfig:[TRUE] " & _ "デバイスがユーザー定義の構成を使用しています。" Else msg &= "ConfigManagerUserConfig:[FALSE] " & _ "デバイスがユーザー定義の構成を使用していません。" End If msg &= vbNewLine 'CreationClassName msg &= "CreationClassName:" & mo.Item("CreationClassName") & vbNewLine 'Description msg &= "Description:" & mo.Item("Description") & vbNewLine 'DeviceID msg &= "DeviceID:" & mo.Item("DeviceID") & vbNewLine 'ErrorCleared If mo.Item("ErrorCleared") Then msg &= "ErrorCleared:[TRUE] " & _ "LastErrorCode プロパティで報告されたエラーが現在解決されています。" Else msg &= "ErrorCleared:[FALSE] " & _ "LastErrorCode プロパティで報告されたエラーが現在解決されていません。" End If msg &= vbNewLine 'ErrorDescription msg &= "ErrorDescription:" & mo.Item("ErrorDescription") & vbNewLine 'HardwareID msg &= "HardwareID:" If mo.Item("HardwareID") IsNot Nothing Then list_HardwareID = mo.Item("HardwareID") For I As Integer = 0 To list_HardwareID.Length() - 1 msg &= list_HardwareID(I) If I <> list_HardwareID.Length() - 1 Then msg &= ", " End If Next End If msg &= vbNewLine 'InstallDate If mo.Item("InstallDate") Is Nothing Then msg &= "InstallDate:" Else dt = mo.Item("InstallDate") msg &= "InstallDate:" & _ String.Format("{0:0000}/{1:00}/{2:00} {3:00}:{4:00}:{5:00}", _ dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second) End If msg &= vbNewLine 'LastErrorCode msg &= "LastErrorCode:" & CStr(mo.Item("LastErrorCode")) & vbNewLine 'Manufacturer msg &= "Manufacturer:" & mo.Item("Manufacturer") & vbNewLine 'Name msg &= "Name:" & mo.Item("Name") & vbNewLine 'PNPDeviceID msg &= "PNPDeviceID:" & mo.Item("PNPDeviceID") & vbNewLine 'PowerManagementCapabilities Select Case mo.Item("PowerManagementCapabilities") Case 0 msg &= "PowerManagementCapabilities:[0] 不明" Case 1 msg &= "PowerManagementCapabilities:[1] サポートされていません" Case 2 msg &= "PowerManagementCapabilities:[2] 無効" Case 3 msg &= "PowerManagementCapabilities:[3] 有効" Case 4 msg &= "PowerManagementCapabilities:[4] 自動省電力モード" Case 5 msg &= "PowerManagementCapabilities:[5] 電源の状態設定可能" Case 6 msg &= "PowerManagementCapabilities:[6] 電源サイクル サポート" Case 7 msg &= "PowerManagementCapabilities:[7] 時刻指定電源オン サポート" Case Else msg &= "PowerManagementCapabilities:" End Select msg &= vbNewLine 'PowerManagementSupported If mo.Item("PowerManagementSupported") Then msg &= "PowerManagementSupported:[TRUE] " & _ "デバイスの電源管理が可能。" Else msg &= "PowerManagementSupported:[FALSE] " & _ "デバイスの電源管理がサポートされていません。" End If msg &= vbNewLine 'Service msg &= "Service:" & mo.Item("Service") & vbNewLine 'Status msg &= "Status:" & mo.Item("Status") & vbNewLine 'StatusInfo Select Case mo.Item("StatusInfo") Case 1 msg &= "StatusInfo:[1]その他の状態" Case 2 msg &= "StatusInfo:[2]不明な状態" Case 3 msg &= "StatusInfo:[3]論理デバイスが有効" Case 4 msg &= "StatusInfo:[4]無効" Case 5 msg &= "StatusInfo:[5]該当なし" Case Else msg &= "StatusInfo:" End Select msg &= vbNewLine 'SystemCreationClassName msg &= "SystemCreationClassName:" & mo.Item("SystemCreationClassName") & vbNewLine 'SystemName msg &= "SystemName:" & mo.Item("SystemName") & vbNewLine msg &= vbNewLine Next '------------------ ' 画面に情報を表示 '------------------ Invoke(txtWMIShow, New Object() {msg}) Catch ex As Exception MessageBox.Show(ex.Message, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation) End Try End Sub End Class
- ■ WndProc () について
-
Windows のデスクトップアプリでは、キーボードでキー入力したりボタンをクリックした時などに
その都度、Windowsメッセージが発生し、それを処理する事でプログラムが動いています。
USBデバイスが抜き差しされた時も例外ではなく、Windowsメッセージが飛んできます。
それを処理する事で、目的のデバイスが現在パソコンにつながっているかどうか確認することができます。
ただし、時間のかかる処理は WndProc () 関数内でしない方がいいです。
なぜなら、Windowsメッセージは常にやり取りされているのですが
1つの処理で時間がかかると次のメッセージを処理するまで待機状態になります。
要するに、プログラムが固まってしまいます。
それを防ぐためにも時間のかかる処理は別スレッドで実行した方がいいでしょう。
- ■ マルチスレッド、WMIに関して
-
VB.NETのマルチスレッドに関しては下記URLに具体的なサンプルがございます。
http://codezine.jp/article/detail/135?p=1
WMIに関しては下記URLを参考にしました。
http://www.wmifun.net/library/win32_pnpentity.html
スポンサーサイト