Windowsメールで指定フォルダーのメールを一括で印刷するWindows PowerShellスクリプト

Windowsメールを一括で印刷したいニーズはたまにある。例えば、メールをPDFファイルとしてバックアップしたい場合だ。PDF作成ツールはたいていプリンタードライバーとして実装されているため、印刷によってPDFファイルを作成することになる。

しかし、Windowsメールには一括印刷機能がない。Adobe AcrobatにはOfficeに付属しているOutlookのメールを一括でPDFに変換する機能があるが、Windowsメールを一括でPDF変換する機能は搭載されていない。WindowsメールをOutlookにインポートしてからAcrobatの変換機能を使う手もあるが、HTMLメールが再現されないという問題がある。

私の場合、ケータイ(携帯電話)のメールをバックアップするためにドコモケータイdatalinkというソフトウェアでメールをPCに取り込んでバックアップを試みたが、デコメールが再現されない。彼女や女性の友人にデコメールを使うなとは言えない。デコメール、HTMLメールをPDFに変換しても再現されるWindowsメールでバックアップし、一括で印刷しPDFに変換できれば問題ない。

そこで、Windows PowerShellで印刷を自動化するスクリプトを書いて手間を省いた。使い方は次の通りだが、最初は少ない件数でテストしてみてから本番を行うといいだろう。実行中はPCは操作しないほうがいいので、寝る前や入浴前、食事前に実行をかけておくと時間を有効に使うことができる。

  1. Windows メールを起動する。
  2. 保存するメールがあるフォルダを開く。
  3. スクリプトの $windowTitle にそのときの Windows メールのタイトルを入力しておく。
  4. スクリプトの $printCount に処理するメールの件数を入力しておく。
  5. スクリプトの $printerName のプリンター名を確認する。
  6. プリンターの設定で結果ファイルを表示しないようにに設定する。
  7. Windows メールが起動して、最小化されていなくて、保存するメールがあるフォルダが開かれているかの最終確認。
  8. スクリプトを実行!
  9. コーヒーブレイク、またはお風呂、または食事、または寝る!
# メールソフトのウィンドウタイトル
$windowTitle = "受信トレイ - Windows メール"

# 処理する件数
$printCount = 3

# プリンター名
$printerName = "Adobe PDF"

[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Reflection.Assembly]::LoadWithPartialName("System.Printing")

# プリンターのスプーラージョブが 0 件になるまで待機する関数
function WaitingPrintout([string]$printerName)
{
    $printServer = New-Object System.Printing.LocalPrintServer
    $printQueues = $printServer.GetPrintQueues()

    foreach ($queue in $printQueues)
    {
        if ($queue.Name -eq $printerName)
        {
            $currentQueue = $printServer.GetPrintQueue($queue.Name)

            $jobCount = 0
            $jobs = $currentQueue.GetPrintJobInfoCollection()

            foreach ($job in $jobs)
            {
                $jobCount++
            }

            while ($jobCount -ne 0)
            {
                [System.Threading.Thread]::Sleep(5000)

                $jobs = $currentQueue.GetPrintJobInfoCollection()
                $jobCount = 0

                foreach ($job in $jobs)
                {
                    $jobCount++
                }
            }
        }
    }
}

$windowsScriptingHost = New-Object -com WScript.Shell
$windowsScriptingHost.AppActivate($windowTitle)

for ($i = 0; $i -lt $printCount; $i++)
{
    [System.Threading.Thread]::Sleep(1000)

    # ファイル -> 印刷 -> 印刷ボタン -> Acrobat PDF プリンターの名前入力
    [System.Windows.Forms.SendKeys]::SendWait("%")
    [System.Windows.Forms.SendKeys]::SendWait("F")
    [System.Windows.Forms.SendKeys]::SendWait("P")
    [System.Windows.Forms.SendKeys]::SendWait("{Enter}")
    [System.Threading.Thread]::Sleep(1000)
    [System.Windows.Forms.SendKeys]::SendWait("%P")
    [System.Threading.Thread]::Sleep(1000)
    [System.Windows.Forms.SendKeys]::SendWait($i + 1)
    [System.Windows.Forms.SendKeys]::SendWait("{Enter}")

    [System.Threading.Thread]::Sleep(2000)

    WaitingPrintout $printerName

    # 次のメールを選択 表示 -> 次へ -> 次のメッセージ
    [System.Threading.Thread]::Sleep(3000)
    $windowsScriptingHost.AppActivate($windowTitle)
    [System.Threading.Thread]::Sleep(1000)
    [System.Windows.Forms.SendKeys]::SendWait("%")
    [System.Windows.Forms.SendKeys]::SendWait("V")
    [System.Windows.Forms.SendKeys]::SendWait("N")
    [System.Windows.Forms.SendKeys]::SendWait("N")
}

Follow me!

Feedlyで新着記事をチェックしよう!

Feedlyでフォローしておけば、新着記事をチェックすることができます。ぜひ、この機会にFeedlyに追加しておきましょう。