WMIのWin32_Printerクラス
WMIのWin32_Printerクラス
VBAでプリンタまわりを操作したいなあと思って、あれこれ調べていると、「WMI(Windows Management Instrumentation)」というものを使うという道があることがわかった。
そうしょっちゅう使うわけでもないが、覚書として記しておくことにする。
ちなみに、Shell
を使う方法については、
コチラをどうぞ。
目次
お世話になったサイト
いろいろ調べているうちにたどり着いたのは、
こちら。
このページには、次のサンプルコードが掲載されている。
Option Explicit 'WMIにて使用する各種オブジェクトを定義・生成する。' Dim oClassSet Dim oClass Dim oLocator Dim oService Dim sMesStr 'ローカルコンピュータに接続する。' Set oLocator = WScript.CreateObject("WbemScripting.SWbemLocator") Set oService = oLocator.ConnectServer 'クエリー条件を WQL にて指定する。' Set oClassSet = oService.ExecQuery("Select * From Win32_Printer") 'コレクションを解析する。' For Each oClass In oClassSet sMesStr = sMesStr & "プリンタの名前: " & oClass.Caption & vbCrLf & _ "プリンタのドライバー名: " & oClass.DriverName & vbCrLf & _ "プリンタのポート: " & oClass.PortName & vbCrLf & _ "デフォルトプリンタか?: " & CStr(oClass.Default) & vbCrLf & vbCrLf Next MsgBox "プリンタに関する情報です。" & vbCrLf & vbCrLf & sMesStr '使用した各種オブジェクトを後片付けする。' Set oClassSet = Nothing Set oClass = Nothing Set oService = Nothing Set oLocator = NothingWMI Fun!! 様より
詳しいことはよくわからんが、WbemScripting
というライブラリにあるSWbemLocator
クラス(?)から順に下位のクラスを取得していっている模様。
上掲ソースコードはVBSのものだが、VBEで[ツール]→[参照設定]で、Microsoft WMI Scripting V1.2 Library
にチェックを入れれば、オブジェクト ブラウザーである程度まで中身を見ることができる。
上掲コードの
Set oLocator = WScript.CreateObject("WbemScripting.SWbemLocator")
で変数oLocator
にぶち込まれるのは、たぶん、
このWbemScripting.SWbemLocator
クラスのインスタンス。
んで、
Set oService = oLocator.ConnectServer
こいつによって変数oService
にぶち込まれるのは、たぶん、
このSWbemServices
オブジェクト。
さらに。
Set oClassSet = oService.ExecQuery("Select * From Win32_Printer")
で、SWbemServices
オブジェクトのExecQuery
メソッドによってWin32_Printer
というオブジェクトを取得し、変数oClassSet
にぶち込んでいる(のだと思う)。
変数の名前からして、こいつは、
SWbemObjectSet
というオブジェクトだと思う。
あとは、For ~ Each
を使ってSWbemObjectSet
からSWbemObject
(インストールされているプリンタ一つ一つに対応)を取り出して、そのプロパティの値を取得している(のだと思う)。
んで、このとき一つ一つ取り出されるオブジェクトは、
SWbemObject
だろう。
VBAに移植する
先に引用したコードを、VBA向けに移植する。
せっかくMicrosoft WMI Scripting V1.2 Library
を参照設定済みなので、アーリー・バインディング方式でコーディングすることとしよう。
上掲コードではメッセージボックスに表示するようにしているが、うっとうしいので、イミディエイト・ウィンドウに出力するようにしているので、あしからず。
リスト1 標準モジュール
Private Sub test01() Dim currLocator As WbemScripting.SWbemLocator Dim tgtServices As WbemScripting.swbems Dim tgtClassSet As WbemScripting.SWbemObjectSet 'ローカルコンピュータに接続する。' Set currLocator = New WbemScripting.SWbemLocator Set tgtServices = currLocator.ConnectServer 'クエリー条件を WQL にて指定する。' Set tgtClassSet = tgtServices.ExecQuery("SELECT * FROM Win32_Printer") Dim tgtClass As WbemScripting.SWbemObject Dim tmp As String 'コレクションを解析する。' For Each tgtClass In tgtClassSet With tgtClass tmp = "プリンタの名前: " & .Caption & vbCrLf & _ "プリンタのドライバー名: " & .DriverName & vbCrLf & _ "プリンタのポート: " & .PortName & vbCrLf & _ "デフォルトプリンタか?: " & CStr(.Default) & vbCrLf & vbCrLf End With Debug.Print tmp Next '使用した各種オブジェクトを後片付けする。' Set tgtClass = Nothing Set tgtClassSet = Nothing Set tgtServices = Nothing Set currLocator = Nothing End Sub
残された課題
さて。上掲リスト1を実際にVBEで入力してみるとわかることなのだが、For ~ Each
ループの中、すなわち、個別のプリンタを指し示すオブジェクト(変数tgtClass
にぶち込まれている)については、入力補完が効かない。
もし、これが不便だと感じるのならば、たとえばSWbemObject
をラップしたクラスを作って、Win32_Printer
クラスのプロパティ・メソッドを自力で実装する、という手もあるかも知れない。
ここを見たらできるはず。
おわりに
まあ、WMIを以てしても、プリンタ名の「on ~
」の部分は取得できないっぽいので、そこまでムキになることもないかな。
写経の一環としてやってみたら面白いかも知れませんけど。