コムセント 技術情報

  1. TOP
  2. コムセント 技術情報
  3. VB.NETでPDFファイルをAcrobatを使用して非同期印刷する

VB.NETでPDFファイルをAcrobatを使用して非同期印刷する

作成日:2023/05/31
最終更新日:2023/05/31

環境

エディター:Visual Studio Community 2022 17.4.4
ターゲットフレームワーク:.NET Framework 4.7.2
Adobe Acrobat Pro:2023.001.20174
(検証はできていませんが、Proではなくてもおそらく可能)

はじめに

今回は、VB.NETを使って複数のPDFファイルを非同期に印刷する方法をご紹介します。
印刷する部分を非同期のTaskで作成しているため、印刷中も他の処理をすることが可能です。
例えば、タスクトレイにアイコンを表示し、そのメニューからプログラムを終了させたりすることも可能です。

本体の印刷するプログラムはモジュールで作成しています。

初期設定

printerName = 印刷するプリンター名
acrobatPath = Acrobatのexeファイルへのパス
filePathList = 印刷するPDFファイルへのパスのList
processList As List(Of ProcessInfo)
'ProcessInfoクラス 複数の process を管理するため作成
Private Class ProcessInfo
        Public Property Process As Process
        Public ReadOnly Property Filename As String
        Public Property HasExited As Boolean
        Public Property ErrorMsg As String
    Public Sub New(process As Process, filename As String)
        Me.Process = process
        Me.Filename = filename
        
        HasExited = False
    End Sub
End Class

プリンター存在確認

設定された printerName のプリンターが、PCと接続されているかの確認をします。

'Module1.main
Dim printerSettings As New PrinterSettings()
For Each printer As String In PrinterSettings.InstalledPrinters
    If printer = printerName Then
        Return True
    End If
Next
Return False

PDFファイルの数ぶんループ

'Module1.main
For Each filePath As String In filePathList
    'すこしsleepする
    Thread.Sleep(1000)
    PrintPdfAsync(filePath)
Next

非同期処理中、アプリケーションが終了しないように待機

'Module1.main
'Imports System.Windows.Forms
Application.Run()

Taskで印刷処理を開始

'Module1
Private Sub PrintPdfAsync(filePath As String)
    Task.Run(Sub()
        Dim result = PrintPdfClass.PrintPdf(filePath)
        If Not result Then
            ' PrintPdfがFalseを返した場合、アプリケーションを終了する
            PrintPdfClass.Dispose()
            Environment.Exit(0)
        End If
    End Sub)
End Sub

Acrobatを開き、印刷する

エラーハンドリング等省略していますが、失敗した場合に false を返すことでアプリケーションが終了します。

'PrintPdfClass
Public Function PrintPdf(filePath As String) As Boolean
    Dim printArgs As String = String.Format("/h /t ""{0}"" ""{1}""", filePath,    printerName)
    ' Acrobat Readerを起動してPDFファイルを印刷する
    Dim processInfo As New ProcessStartInfo(acrobatPath, printArgs)
    processInfo.CreateNoWindow = True
    processInfo.WindowStyle = ProcessWindowStyle.Hidden
    Dim process = New Process With {
        .EnableRaisingEvents = True,
        .StartInfo = processInfo
    }
    AddHandler process.Exited, AddressOf ProcessExited
    Dim processInfoClass As New ProcessInfo(process, filePath)
    processList.Add(processInfoClass)
    process.Start()
    Return True
End Function

processがexitedのとき、終了処理を行う

'PrintPdfClass
'Acrobatのウィンドウを閉じるときに使用する
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Private Const WM_SYSCOMMAND As Integer = &H112
Private Const SC_CLOSE As Integer = &HF060
Private Sub ProcessExited(sender As Object, e As EventArgs)
    Dim exitedProcess As Process = CType(sender, Process)
    exitedProcess.Dispose()
    'すべてのプロセスが終了した場合のIf内で
    ' Acrobat Readerのウィンドウを閉じる処理を非同期に実行する
    Task.Run(
        Sub()
            ' Acrobat Readerのウィンドウを探す
            Dim adobeWindowHandle As IntPtr = IntPtr.Zero
            Do Until adobeWindowHandle <> IntPtr.Zero
                adobeWindowHandle = FindWindow("AcrobatSDIWindow", vbNullString)
            Loop
          ' Acrobat Readerのウィンドウを閉じる
            SendMessage(adobeWindowHandle, WM_SYSCOMMAND, SC_CLOSE, 0)
        End Sub
    )
End Sub

Disposeですべてのprocessを終了する

Public Sub Dispose()
    For Each processInfo In processList
        processInfo.Process.Dispose()
    Next
End Sub

以上のコードで、ローカルのPDFファイルを印刷することが可能です。
これらを使用することで、あるディレクトリにあるPDFを全て印刷したり、Windowsのタスクスケジューラで定期的に実行することで印刷の自動化が可能になります。
使用用途に合わせて改変してください。

最後に

高校生のときにVisual Basicでアナログ時計を作ったりした経験はありましたが、本格的なプログラムは初めてでした。
すんなりとはいきませんでしたが、形になってとてもうれしかったです。

プログラマー/A.A

このメンバーの記事一覧へ

おすすめ記事