misc.log

日常茶飯事とお仕事と

プリンタ情報取得

ネットワークプリンタのIPアドレスをとりたいのだが...

とりあえずポート名は以下の処理で取れる(一部、Dobonさんのページ http://dobon.net/vb/dotnet/graphics/printerport.html にあるサンプルソースを転用)。

    Private Sub GetPrinters_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GetPrinters.Click

        Dim printer As New PrinterSettings

        For Each printerObj As String In printer.InstalledPrinters
            printerList.Items.Add(printerObj.ToString)
        Next

    End Sub

    Private Sub printerList_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles printerList.SelectedIndexChanged

        Dim printerInfo As PRINTER_INFO_2

        printerInfo = GetPrinterInfo(printerList.SelectedItem)

        PortNameLabel.Text = printerInfo.pPortName
        DriverNameLabel.Text = printerInfo.pDriverName

    End Sub


    Public Shared Function GetPrinterInfo(ByVal printerName As String) As PRINTER_INFO_2

        'プリンタのハンドルを取得する
        Dim hPrinter As IntPtr
        If Not OpenPrinter(printerName, hPrinter, IntPtr.Zero) Then
            Throw New Win32Exception(Marshal.GetLastWin32Error())
        End If

        Dim pPrinterInfo As IntPtr = IntPtr.Zero
        Try
            '必要なバイト数を取得する
            Dim needed As Integer
            GetPrinter(hPrinter, 2, IntPtr.Zero, 0, needed)
            If needed <= 0 Then
                Throw New Exception("失敗しました。")
            End If
            'メモリを割り当てる
            pPrinterInfo = Marshal.AllocHGlobal(needed)

            'プリンタ情報を取得する
            Dim temp As Integer
            If Not GetPrinter(hPrinter, 2, pPrinterInfo, needed, temp) Then
                Throw New Win32Exception(Marshal.GetLastWin32Error())
            End If

            'PRINTER_INFO_2型にマーシャリングする
            Dim printerInfo As PRINTER_INFO_2 = _
                CType(Marshal.PtrToStructure( _
                pPrinterInfo, GetType(PRINTER_INFO_2)), PRINTER_INFO_2)

            '結果を返す
            Return printerInfo
        Finally
            '後始末をする
            ClosePrinter(hPrinter)
            Marshal.FreeHGlobal(pPrinterInfo)
        End Try
    End Function

これでポート名を取り、それを元にレジストリを検索すると、

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers

に上記コードにあるPRINTER_INFO_2の内容が置いてあるのを発見。でもIPアドレスは無い。

さらに検索をすすめると、以下のキーに、ポートのIPアドレスが記載されているのを発見。

HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Print\Monitors\Standard TCP/IP Port\Ports

これにアクセスするAPIを探せば良いのね。