DOBON.NET DOBON.NETプログラミング掲示板過去ログ

デバイスの有効/無効を知りたいのですが

環境/言語:[環境(Windows, XP) 使用言語(VB6)]
分類:[VB6以前]

お世話になります。

デバイスの有効/無効の切り替えは
有効・無効BATファイルを作成してVB6から
ボタンにして切り替えをしています。

有効化のBATファイル
devcon.exe enable "ハードウェア ID″

無効化のBATファイル
devcon.exe disable "ハードウェア ID″

下記から学びました。
http://tech.ironhearts.com/blog/archives/74

現在のデバイスが(有効)又は(無効)かを知りたいのですが
何か調べる方法はありませんでしょうか。
> 現在のデバイスが(有効)又は(無効)かを知りたいのですが
> 何か調べる方法はありませんでしょうか。

  VB6からですか・・・厄介ですネ!
  APIなら
  CM_Get_DevNode_Status
  SetupDiGetClassInstallParams
  のどちらかで取れたはずです。

  ただ、それを呼ぶまでに結構デバイス呼び出しのAPIを
  コールしてハンドル取らないといけないので・・・

※ DevConのソースあるみたいですので、読まれては?

以上。
2009/06/05(Fri) 11:04:11 編集(投稿者)

オショウ様

返答下さいましてありがとうございました。
CM_Get_DevNode_Status、SetupDiGetClassInstallParams
の情報提供を下さいましてお礼を申し上げます。
>ただ、それを呼ぶまでに結構デバイス呼び出しのAPIを
>コールしてハンドル取らないといけないので・・・
はい、そうですか。簡単にいかないみたのが分かりました。
情報提供を下さいましたAPIでもう少し調べてみます。
> 情報提供を下さいましたAPIでもう少し調べてみます。

  VB.NETでですが・・・
  デバイスの有効化・無効化だけに使用しているAPIは
  DevConのソースから拾えますが、列挙すると

<DllImport("setupapi.dll", EntryPoint:="SetupDiGetClassDevsA", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, PreserveSig:=True, CallingConvention:=CallingConvention.Winapi)> _
Private Shared Function SetupDiGetClassDevs(ByRef ClassGuid As Guid, <MarshalAs(UnmanagedType.LPTStr)> ByVal Enumerator As String, ByVal hWndParent As IntPtr, ByVal Flags As Integer) As IntPtr
End Function
<DllImport("setupapi.dll", EntryPoint:="SetupDiGetClassDevsA", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, PreserveSig:=True, CallingConvention:=CallingConvention.Winapi)> _
Private Shared Function SetupDiGetClassDevs(ByRef ClassGuid As Guid, ByVal Enumerator As IntPtr, ByVal hWndParent As IntPtr, ByVal Flags As Integer) As IntPtr
End Function
<DllImport("setupapi.dll", EntryPoint:="SetupDiEnumDeviceInfo", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, PreserveSig:=True, CallingConvention:=CallingConvention.Winapi)> _
Private Shared Function SetupDiEnumDeviceInfo(ByVal DeviceInfoSet As Integer, ByVal MemberIndex As Integer, ByRef DeviceInfoData As SP_DEVINFO_DATA) As Boolean
End Function
<DllImport("setupapi.dll", EntryPoint:="SetupDiDestroyDeviceInfoList", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, PreserveSig:=True, CallingConvention:=CallingConvention.Winapi)> _
Private Shared Function SetupDiDestroyDeviceInfoList(ByVal DeviceInfoSet As Integer) As Boolean
End Function
<DllImport("setupapi.dll", EntryPoint:="SetupDiSetClassInstallParamsA", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, PreserveSig:=True, CallingConvention:=CallingConvention.Winapi)> _
Private Shared Function SetupDiSetClassInstallParams(ByVal DeviceInfoSet As IntPtr, ByRef DeviceInfoData As SP_DEVINFO_DATA, ByRef ClassInstallParams As SP_CLASSINSTALL_HEADER, ByVal ClassInstallParamsSize As Integer) As Boolean
End Function
<DllImport("setupapi.dll", EntryPoint:="SetupDiCallClassInstaller", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True, PreserveSig:=True, CallingConvention:=CallingConvention.Winapi)> _
Private Shared Function SetupDiCallClassInstaller(ByVal InstallFunction As Integer, ByVal DeviceInfoSet As Integer, ByRef DeviceInfoData As SP_DEVINFO_DATA) As Boolean
End Function

  これだけ使ってます。

参考まで
オショウ様

返答下さいましてありがとうございました。
>VB.NETでですが・・・
>  デバイスの有効化・無効化だけに使用しているAPIは
>  DevConのソースから拾えますが、列挙すると
上記の参考情報を提供頂きましてお礼を申し上げます。
調べてみましたら想像以上に難しいことが分かりました。
特にVB6に関しての情報はほとんど見あたりませんでした。
デバイスの有効/無効の切り替えのように簡単でないことが分かり、
厄介であることが分かりました。
2009/06/05(Fri) 14:48:01 編集(投稿者)

■No24683に返信(amさんの記事)
> 現在のデバイスが(有効)又は(無効)かを知りたいのですが
> 何か調べる方法はありませんでしょうか。

その程度であれば、WMI の CIM_LogicalDevice / Win32_PnPEntity クラスで
事足りるような気がします。
http://msdn.microsoft.com/en-us/library/aa394352.aspx


とりあえず、ID による絞込み無しで、CIM_LogicalDevice を列挙するサンプルです。

'--------------------------------
Dim FNo As Integer
Dim o As Object

On Error Resume Next
FNo = FreeFile()
Open "C:\a.txt" For Output As #FNo
For Each o In GetObject("winmgmts:").InstancesOf("CIM_LogicalDevice")
 Print #FNo, o.Description
 Print #FNo, , "Name="; o.Name
 Print #FNo, , "Caption="; o.Caption
 Print #FNo, , "DeviceID="; o.DeviceID
 Print #FNo, , "PNPDeviceID="; o.PNPDeviceID
 Print #FNo, , "ErrorDescription="; o.ErrorDescription
 Print #FNo, , "Status="; o.Status
 Print #FNo, , "StatusInfo="; o.StatusInfo
Next
Close #FNo
'--------------------------------

これを実行すると、たとえば下記のような結果が得られます。
無効にしたデバイスは、恐らく Status が "Error" になっているかと。


ディスク ドライブ
       Name=\\.\PHYSICALDRIVE0
       Caption=WDC WD1600JS-75NCB3
       DeviceID=\\.\PHYSICALDRIVE0
       PNPDeviceID=IDE\DISKWDC_WD1600JS-75NCB3_____________________10.02E04\5&1C6638A1&0&0.0.0
       ErrorDescription=Null
       Status=OK
       StatusInfo=Null
Microsoft Loopback Adapter
       Name=Microsoft Loopback Adapter
       Caption=Microsoft Loopback Adapter
       DeviceID=ROOT\NET\0000
       PNPDeviceID=ROOT\NET\0000
       ErrorDescription=Null
       Status=Error
       StatusInfo=Null
Vimicro USB2.0 PC Camera(VC0323)
       Name=Vimicro USB2.0 PC Camera(VC0323) #2
       Caption=Vimicro USB2.0 PC Camera(VC0323) #2
       DeviceID=USB\VID_0AC8&PID_0323\5&2586298&0&4
       PNPDeviceID=USB\VID_0AC8&PID_0323\5&2586298&0&4
       ErrorDescription=Null
       Status=Error
       StatusInfo=Null
魔界の仮面弁士 様

返答下さいましてありがとうございます。

情報、プログラム提供して下さいましてお礼を申し上げます。

これから、ご提供下さいましたプログラムにより行ってみます。
結果につきましてはご報告させてもらいます。
済みませんが少しお待ち下さい。
魔界の仮面弁士 様

>無効にしたデバイスは、恐らく Status が "Error" になっているかと。
デバイスの使用状況を有効から無効に替えてみましたら
Statusが
有効 Status=OK
無効 Status=Error
で確認できました。
得られました結果からID による絞込みをして
Statusデータ情報を取得できれば、
デバイスの有効/無効を知ることができると思いました。
ID による絞込み無しで、CIM_LogicalDevice を列挙するサンプルは
宝の様なサンプルプログラムでした。大切にしていきたいと思います。
感謝いたします。本当にありがとうございました。
解決済み!
■No24696に返信(amさんの記事)
> 得られました結果からID による絞込みをして

WQL を用いて、
  SELECT * FROM CIM_LogicalDevice
  WHERE PNPDeviceID='xxxxxxxx'
といった問い合わせをかける方法もあります。


Public Function GetDeviceStatus(ByVal ID As String) As String
 Dim sID As String
 sID = ID
 sID = Replace(sID, "\", "\\")
 sID = Replace(sID, "'", "\'")

 Dim wql As String
 wql = "SELECT Status FROM CIM_LogicalDevice"
 wql = wql & " WHERE DeviceID='" & sID & "'"

 Dim o As Object
 For Each o In GetObject("winmgmts:").ExecQuery(wql)
  GetDeviceStatus = o.Status & ""
 Next
End Function
解決済み!
魔界の仮面弁士 様

返信下さいましてありがとうございました。
先ほどは大変お世話になりました。
申し訳ありません。WQLについて分かりませんでした。
>Public Function GetDeviceStatus(ByVal ID As String) As String
>Dim sID As String



>  GetDeviceStatus = o.Status & ""
> Next
>End Function
以上の記述は標準モジュールに追加しました。

>  SELECT * FROM CIM_LogicalDevice
>  WHERE PNPDeviceID='xxxxxxxx'
以上の2行につきましてはどこに記述すれば良いのか分かりませんでした。
Option Explicitの下に記述しましたら記述が赤くなりました。
申し訳ありません。SELECT * FROM CIM_LogicalDevice
WHERE PNPDeviceID='xxxxxxxx'につきまして
ご教示してもらいますと幸いです。
2009/06/05(Fri) 19:15:37 編集(投稿者)

■No24701に返信(amさんの記事)
> WQLについて分かりませんでした。
WQL とは WMI Query Language の略で、WMI への問い合わせに使われる言語です。

WMI の仕様は MSDN で確認できます。興味があれば調べてみてください。
WMI のサンプルは TechNet などで多く見つけることができます。

なお WMI は、先のように GetObject から呼び出す方法でも充分に利用できますが、
高度な機能(イベント通知などの非同期処理機能など)を使う場合には、参照設定に
「Microsoft WMI Scripting Vx.x Library」を加えて使うことになります。


> >  SELECT * FROM CIM_LogicalDevice
> >  WHERE PNPDeviceID='xxxxxxxx'
> 以上の2行につきましてはどこに記述すれば良いのか分かりませんでした。

先のサンプルでは、「Function GetDeviceStatus」内にある

> > Dim wql As String
> > wql = "SELECT Status FROM CIM_LogicalDevice"
> > wql = wql & " WHERE DeviceID='" & sID & "'"

の部分がそれにあたります。この文字列が WQL です。


----
たとえば下記は、BIOS 情報を列挙するためのサンプルです。

Dim wql As String
wql = "SELECT * FROM Win32_BIOS"

Dim o As Object
Dim p As Object
On Error Resume Next
For Each o In GetObject("winmgmts:").ExecQuery(wql)
 Debug.Print "-----"
 For Each p In o.Properties_
  If Not p.IsArray Then
   Debug.Print p.Name; "="; p.Value
  ElseIf Not IsNull(p.Value) Then
   Debug.Print p.Name; "=>"; Tab(4); "[配列]";
   Dim v As Variant
   For Each v In p.Value
    Debug.Print v; "‖";
   Next
   Debug.Print
  End If
 Next
Next

他の WQL の例を幾つか挙げておきます。

' 物理メモリ情報
wql = "SELECT * FROM Win32_PhysicalMemory"

' プリンタ情報
wql = "SELECT * FROM Win32_Printer"

' CPU 情報 (複数の CPU を登載していれば、それらが列挙される)
wql = "SELECT * FROM Win32_Processor"

' 起動中のプロセス情報 (件数が多いので、Debug.Print よりも Print # の方が良いかも)
wql = "SELECT * FROM Win32_Process"

' 起動中のプロセスのうち、IE だけを列挙
wql = "SELECT * FROM Win32_Process"
wql = wql & " WHERE ExecutablePath LIKE '%\\IExplore.exe'"

' 使用不可状態の Plug & Play デバイス情報を列挙
wql = "SELECT * FROM Win32_PnPEntity WHERE Status = 'Error'"
魔界の仮面弁士 様

返答下さいましてありがとうございます。
>WQL とは WMI Query Language の略で、WMI への問い合わせに使われる言語です。
 WQLの説明を詳細にして頂きましてお礼を申し上げます。
>ID による絞込み無しで、CIM_LogicalDevice を列挙するサンプルです。
 によりましてDeviceID="XXXXXX" → Status=OKを検索する事ができました。
 それによりデバイスの使用状況(有効/無効)が確認できるようになりました。
 お陰様で目的が達成でき解決に至ることができました。
 本当にお手数をお掛けしました。深く感謝申し上げます。
 別の方法でありますWQL につきましては勉強する必要があります。
 BIOS 情報を列挙するためのサンプルを参考にして調べていきます。
 
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板