「新しいPCに入れたら、いつものプリンター名ではなく別の名前のキューができていて、アプリが印刷先を見つけられない」「保存していた用紙とトレイの設定が復元されない」「ラベルプリンターが一覧から消えた」── 2026年以降、こうした症状が出たときに最初に疑うべき背景が一つ増えました。Microsoftが2023年9月に発表した、サードパーティ製プリンタードライバー(v3/v4)の提供終了計画です。1
この計画は段階的で既存ドライバーを止めるものでもなく、「ある日いきなり印刷できなくなる」類のものではありません。けれども業務アプリの印刷は、ドライバーが返す用紙一覧・トレイ・独自機能に気づかないうちに依存していることが多く、ドライバーが同梱のIPPクラスドライバーに置き換わった瞬間に、その依存が表に出ます。本記事は、Windows業務アプリの印刷とPDF出力の続編として、何が決まったのか、何が消えるのか、既存アプリのどこを見ればよいのかを整理します。対象読者は、帳票・伝票・ラベルを印刷する業務アプリを保守しているWinForms / WPF開発者と、納品先の印刷環境を管理する担当者です。前提環境はWindows 11(Windows protected print modeの検証は24H2以降)で、コードはPowerShell 5.1以降(PrintManagementモジュール)と、C#(.NET 6以降または.NET Framework 4.x、System.Drawing.Printing / System.Printing)で示します。難易度は中級です。
1. まず結論
読後に残してほしい一文です。
プリンタードライバーの終了は「印刷できなくなる話」ではなく「ドライバーが提供していた機能と名前が、ある日IPPクラスドライバーのものに置き換わる話」である。業務アプリはドライバー固有の何かに依存していないかを棚卸しし、依存している箇所だけ経路を変える。
- 段階は3つです。 2026年1月15日に新規ドライバーのWindows Update掲載が停止、2026年7月1日にドライバーの順位付けが常にIPP同梱クラスドライバーを優先する形に変更、2027年7月1日にセキュリティ修正以外のドライバー更新が停止します。対象はWindows 11以降とWindows Server 2025以降です。1
- 既存ドライバーは消えません。 既存のドライバーは提供終了後もインストールでき、メーカー提供のインストーラーからの導入も引き続き許されます。v3/v4ドライバーの機能を無効化する計画はないと明記されています。1
- 本当に環境が変わるのは、Windows protected print modeが有効になったときです。 有効化すると第三者ドライバーを使うプリンターがアンインストールされ、ドライバーはドライバーストアから削除されます。XPS Document WriterとFAXも削除されます。2
- Windows protected print modeは執筆時点では既定で無効ですが、将来は既定で有効になるとMicrosoftは明言しています。34
- アプリ側で見るべきは4か所です。 ドライバー固有設定の保存・復元、プリンター名やキュー名への依存(メーカーSDKや帳票ライブラリが内部で呼ぶキュー・ドライバーを含む)、仮想プリンター(XPS/PDF/独自ポートモニター)への依存、RAWデータのスプーラー経由送信。この4つ以外の「描画しているだけ」のコードは検証対象です。ただし前提として、印刷先のプリンターがWindows Ready Printで再登録できる機種かを先に確かめます。
flowchart TB
accTitle: ドライバー終了で変わるものと変わらないもの
accDescr: プリンタードライバーの提供終了そのものではアプリの描画APIの入口と既存ドライバーは変わらず、新規導入や再検出で別のドライバーが選ばれたときに初めてドライバーが返す用紙一覧や独自機能、キュー名が置き換わり、仮想プリンターの削除を含むWindows protected print modeの有効化による変化は別の仕組みとして4章で扱う
eos["プリンタードライバーの提供終了"]
eos --> keep["変わらないもの"]
eos --> cond["新規導入・再検出で別ドライバーが選ばれたとき"]
cond --> change["置き換わるもの"]
keep --> api["描画APIの入口"]
keep --> drv["既存ドライバー"]
change --> caps["用紙・トレイ・独自機能"]
change --> qname["キュー名"]
図1: 提供終了だけでは何も変わらず、別のドライバーが選ばれたときにドライバーが提供していた情報と名前が置き換わる。仮想プリンターの削除を含むWPPの有効化による変化は別の仕組みである(4章)。
flowchart TB
accTitle: 業務アプリで棚卸しする4か所
accDescr: 業務アプリの印刷コードのうち、ドライバー固有設定の保存、キュー名依存(SDKやライブラリ内部のものを含む)、WPPでサポートされない仮想プリンターへの依存、WPPで残らないキューへのRAW送信の4か所は改修対象で、描画しているだけのコードは検証対象になる
app["業務アプリの印刷コード"]
app --> deps["4つの依存を棚卸し"]
app --> d0["描画だけ"]
deps --> d1["固有設定の保存"]
deps --> d2["キュー名への依存"]
deps --> d3["仮想プリンター依存"]
deps --> d4["RAW送信"]
d2 -.-> d2n["SDK内部も含む"]
d3 -.-> d3n["WPP非対応のもの"]
d4 -.-> d4n["残らないキュー向け"]
d1 --> fix["改修する"]
d2 --> fix
d3 --> fix
d4 --> fix
d0 --> verify["検証する"]
図2: 4つの依存だけが改修対象で、描画しかしていないコードは検証に回す。
判断表 ── プリンター種別 × いま取るべき手
| プリンターの種類 | 2026〜2027年に起きること | 業務アプリ側の手 |
|---|---|---|
| Mopria認証済みのオフィス複合機・レーザー・インクジェット(ネットワーク接続) | 新規PCではIPPクラスドライバーが選ばれやすくなる。Windows protected print modeを有効にすると、メーカー製ドライバーで導入済みのキューは一度削除され、Windows Ready Printでの再登録が必要になる | 検証。現在のドライバー種別を確認し、再登録後に用紙・トレイ・両面などPrintCapabilitiesの差分を確認して、ドライバー固有設定の保存を捨てる |
| 同上(USB接続) | IPP over USBモードでないとIPPで扱えない | 検証。プリンター側のUSB動作モードを確認する1 |
| Mopria認証を取れないプリンター(ラベル・レシート・特殊機など) | メーカー製ドライバーの署名は例外的に続く可能性がある。ただしWindows protected print modeでは使えない | 経路を変える。装置と直接TCP/USB/シリアルで通信するメーカーSDK、またはプリンター言語の直接送信(TCP/シリアル/USB)を用意する。内部でWindowsのキューを呼ぶSDKは逃げ道にならない(6章) |
| 仮想プリンター(XPS Document Writer、ポートモニターDLL型などWPP非対応と確認できた第三者製PDFプリンター) | Windows protected print modeで削除・無効化される。WPP対応の経路へ更新済みの第三者製仮想プリンターは削除対象ではなく検証対象 | 経路を変える。PDFライブラリでの直接生成に寄せる |
| Universal Print経由のクラウド印刷 | Windows Ready Printの一部として位置づけられている | 検証。既存のキュー名依存を外す |
この記事の知識マップ
サードパーティ製プリンタードライバー(v3/v4)の提供終了計画は既存ドライバーを無効化しないが、プリンタードライバーの順位付けを常にIPPクラスドライバー優先へ変えることで、PCの入れ替えやプリンターの再検出のたびに意図しないドライバーの入れ替わりを起こし得る。Windows Ready Printはその後継で、Windows 10 21H2以降に同梱されるMicrosoft IPP Class DriverがIPPでMopria認証済みプリンターと通信する(USB接続機はIPP over USBモードが前提)。ただしWindows Ready Printでもアプリの描画命令は印刷スプーラーを通る。Windows protected print modeはWindows Ready Printだけを使う動作モードで、Windows 11 24H2以降でグループポリシーやIntuneから構成でき、有効かどうかはWindowsProtectedPrintInfo.IsProtectedPrintEnabledで確認できる。有効化すると第三者ドライバー、サポートされないソフトウェアプリンター、XPS Document Writer、Point and Printによる第三者ドライバー配布が排除され、メーカー製ドライバーで導入済みのキューはMopria認証済みでも一度削除されて再登録が要る。Mopria認証を取れないラベル・レシートプリンターと、WPPで残らないキュー(メーカー製ドライバーのキューなど)へのRAW送信は、このモードと両立しない。DEVMODEの非公開部分やPrintTicketの私的拡張を含むドライバー固有設定の保存はドライバーの入れ替わりと両立せず、意図だけを保存して印刷直前に能力を照会・検証する設計が推奨される。キュー名への依存やドライバーの入れ替わりは印刷先キューの消失を招くため、起動時の存在確認と通知が推奨され、既定プリンターへの無言のフォールバックは推奨されない。仮想プリンターへの依存にはPDF生成ライブラリ、ラベル・レシートプリンターにはスプーラーに依存しない出力経路が推奨される。System.Printing名前空間はWindowsサービスと両立しない。ドライバーの種別はPrintManagementモジュールで確認でき、印刷先のキューがWindows protected print modeで残るか、物理プリンターがWindows Ready Printで再登録できるかの判定は印刷コードの依存の棚卸しより先に行い、Windows protected print modeを使う環境では有効にした検証で、使わない環境では物理のIPP対応機をWPPを無効にしたまま再検出する検証で備えを確かめる。
flowchart LR
accTitle: プリンタードライバー終了と業務アプリ印刷の知識マップ
accDescr: サードパーティ製プリンタードライバーの提供終了計画が順位付けの変更を通じてドライバーの入れ替わりを引き起こし、Windows Ready PrintがIPPクラスドライバーでMopria認証済みプリンターと通信する後継となり、Windows protected print modeが第三者ドライバー・仮想プリンター・XPS Document Writer・Point and Print配布を排して既存キューの再登録を要求すること、ドライバー固有設定の保存やキュー名依存・仮想プリンター依存・RAW送信が入れ替わりと両立せず、能力照会と検証・存在確認と通知・PDFライブラリ・スプーラーに依存しない経路が推奨されること、印刷先のキューがWPPで残るか・プリンターを再登録できるかの判定をコードの棚卸しより先に行うことまでを示す関係図
third_party_printer_driver_end_of_servicing["サードパーティ製プリンタードライバーの提供終了計画"]
windows_protected_print_mode["Windows protected print mode"]
windows_ready_print["Windows Ready Print"]
driver_specific_setting_persistence["ドライバー固有設定の保存・復元"]
printer_driver_ranking["プリンタードライバーの順位付け"]
unexpected_driver_replacement["意図しないプリンタードライバーの入れ替わり"]
v3_v4_printer_driver["サードパーティ製プリンタードライバー(v3 / v4)"]
microsoft_ipp_class_driver["Microsoft IPP Class Driver"]
print_spooler["印刷スプーラー"]
ipp["IPP(Internet Printing Protocol)"]
mopria_certified_printer["Mopria認証済みプリンター"]
ipp_over_usb["IPP over USB"]
unsupported_software_printer["サポートされないソフトウェアプリンター(仮想プリンター)"]
xps_document_writer["Microsoft XPS Document Writer"]
point_and_print_driver_distribution["Point and Printによるドライバー配布"]
group_policy["グループポリシー"]
intune["Microsoft Intune"]
windows_11_24h2_client["Windows 11 バージョン24H2(クライアント)"]
windows_protected_print_info["WindowsProtectedPrintInfo.IsProtectedPrintEnabled"]
label_receipt_printer["ラベル・レシートプリンター"]
raw_print_data["RAW送信(RAWデータ種別でのスプーラー経由送信)"]
devmode_private_data["DEVMODEの非公開部分"]
print_ticket_private_extension["PrintTicketの私的拡張"]
print_capabilities_validation["印刷直前の能力照会と検証(GetPrintCapabilities / MergeAndValidatePrintTicket)"]
print_queue_name_dependency["プリンター名・キュー名への依存"]
missing_print_queue["印刷先キューの消失"]
printer_existence_check["起動時のプリンター存在確認と通知"]
silent_default_printer_fallback["既定プリンターへの無言のフォールバック"]
virtual_printer_dependency["仮想プリンターへの依存"]
pdf_generation_library["PDF生成ライブラリ"]
spooler_independent_print_path["スプーラーに依存しない出力経路"]
system_printing["System.Printing名前空間"]
windows_service["Windowsサービス"]
printmanagement_module["PrintManagementモジュール(Get-Printer / Get-PrinterDriver)"]
ready_print_reregistration_check["印刷先キューのWPP互換性の判定"]
print_code_dependency_review["印刷コードの依存の棚卸し"]
wpp_enabled_verification["Windows protected print modeを有効にした検証"]
wpp_off_redetection_verification["WPPを無効にしたままの再検出検証"]
third_party_printer_driver_end_of_servicing -->|"利用する"| printer_driver_ranking
third_party_printer_driver_end_of_servicing -.->|"原因になり得る"| unexpected_driver_replacement
printer_driver_ranking -.->|"原因になり得る"| unexpected_driver_replacement
windows_ready_print -->|"の後継"| v3_v4_printer_driver
windows_ready_print -->|"利用する"| microsoft_ipp_class_driver
windows_ready_print -->|"利用する"| print_spooler
microsoft_ipp_class_driver -->|"利用する"| ipp
windows_protected_print_mode -.->|"前提とする"| mopria_certified_printer
mopria_certified_printer -.->|"前提とする"| ipp_over_usb
windows_protected_print_mode -->|"利用する"| windows_ready_print
windows_protected_print_mode -->|"防止する"| v3_v4_printer_driver
windows_protected_print_mode -->|"防止する"| unsupported_software_printer
windows_protected_print_mode -->|"防止する"| xps_document_writer
windows_protected_print_mode -->|"防止する"| point_and_print_driver_distribution
windows_protected_print_mode -.->|"原因になり得る"| unexpected_driver_replacement
windows_protected_print_mode -->|"で構成できる"| group_policy
windows_protected_print_mode -->|"で構成できる"| intune
windows_protected_print_mode -->|"前提とする"| windows_11_24h2_client
windows_protected_print_mode -->|"で確認できる"| windows_protected_print_info
windows_protected_print_mode -.->|"両立しない"| label_receipt_printer
windows_protected_print_mode -.->|"両立しない"| raw_print_data
driver_specific_setting_persistence -.->|"利用する"| devmode_private_data
driver_specific_setting_persistence -.->|"利用する"| print_ticket_private_extension
driver_specific_setting_persistence -->|"両立しない"| unexpected_driver_replacement
print_capabilities_validation -->|"推奨される対応"| driver_specific_setting_persistence
print_queue_name_dependency -.->|"原因になり得る"| missing_print_queue
unexpected_driver_replacement -.->|"原因になり得る"| missing_print_queue
printer_existence_check -->|"推奨される対応"| missing_print_queue
silent_default_printer_fallback -->|"用いるのは非推奨"| missing_print_queue
virtual_printer_dependency -.->|"利用する"| unsupported_software_printer
virtual_printer_dependency -.->|"利用する"| xps_document_writer
pdf_generation_library -->|"推奨される対応"| virtual_printer_dependency
raw_print_data -->|"利用する"| print_spooler
spooler_independent_print_path -->|"推奨される対応"| label_receipt_printer
system_printing -->|"両立しない"| windows_service
v3_v4_printer_driver -->|"で確認できる"| printmanagement_module
ready_print_reregistration_check -->|"より先に行うべき"| print_code_dependency_review
wpp_enabled_verification -.->|"推奨される対応"| unexpected_driver_replacement
wpp_off_redetection_verification -.->|"推奨される対応"| unexpected_driver_replacement
図の実線は常に成り立つ関係、破線は条件付きの関係です(成立条件は詳細ページの各関係の説明に記載)。関係すべての一覧(全39件、根拠・確度つき)と主要概念の定義は知識マップ詳細ページにまとめています。データ: JSON-LD / Turtle
2. 何が決まったのか ── 3段階のタイムライン
Microsoft Learnの「End of servicing plan for third-party printer drivers on Windows」が一次ソースです。2025年5月に日付が見直され、執筆時点の計画は次の表のとおりです。1
| 時期 | 内容 |
|---|---|
| 2023年9月 | 提供終了計画を発表 |
| 2026年1月15日 | Windows 11以降とWindows Server 2025以降を対象に、新しいプリンタードライバーをWindows Updateに掲載しない。既存ドライバーの更新は個別審査で可 |
| 2026年7月1日 | プリンタードライバーの順位付けを、常にWindows同梱のIPPクラスドライバーを優先するよう変更 |
| 2027年7月1日 | セキュリティ関連の修正を除き、サードパーティ製ドライバーの更新を受け付けない。既存ドライバーはWindows Updateまたはメーカー提供パッケージからインストール可能 |
同じページのFAQに、業務アプリの担当者が押さえるべき条件が並んでいます。1
- 署名の例外。2026年1月15日以降も署名が認められるのは、Mopria認証を取れないプリンター、Windows 10以下を上限に指定したパッケージ、ネイティブARM64ドライバーの3条件です。パートナーセンターへの提出自体も、この日から既定でブロックされ、正当化文書を添えた個別審査になりました。5
- 既存ドライバーの扱い。提供終了後も既存ドライバーはインストールでき、メーカーのインストーラーからの導入も続きます。v3/v4ドライバーが担っている印刷機能を無効化する計画はありません。
- 多機能機。ネットワーク機はIPP(印刷)・IPP Fax Out(FAX)・eSCL/WS-Scan(スキャン)で動きます。USB機は、USBインターフェースがIPP over USBモードのときだけ各機能を使えます。
flowchart TB
accTitle: 2026年1月15日以降もドライバー署名が認められる条件
accDescr: メーカーからのドライバー提出は既定でブロックされ、Mopria認証を取れないプリンター、Windows 10以下を上限にしたパッケージ、ネイティブARM64ドライバーの3条件のいずれかに当てはまるものだけが例外申請を個別審査に載せられるが、審査を経て承認される場合があるだけで署名されることは保証されない
submit["メーカーのドライバー提出"]
submit --> block["既定でブロック"]
block --> c1["Mopria認証を取れない機種"]
block --> c2["Windows 10以下が上限"]
block --> c3["ネイティブARM64"]
c1 --> apply["例外申請が可能"]
c2 --> apply
c3 --> apply
apply --> review["個別審査"]
review --> maybe["承認される場合がある(保証はない)"]
図3: 条件に当てはまっても審査に載せられるだけで、署名されるかどうかは保証されない。
flowchart TB
accTitle: 多機能機がWindows Ready Printで動く条件
accDescr: ネットワーク接続の多機能機は、印刷はIPP、FAXはIPP Fax Out、スキャンはeSCLまたはWS-Scanで動くが、いずれもその機器が機能を搭載し対応するプロトコルを実装している場合に限り、USB接続機はさらにUSBインターフェースがIPP over USBモードのときだけ各機能を使える
mfp["多機能機"]
mfp --> net["ネットワーク接続"]
mfp --> usb["USB接続"]
net --> p["印刷:IPP対応なら"]
net --> f["FAX:搭載しIPP Fax Out対応なら"]
net --> s["スキャン:eSCL / WS-Scan対応なら"]
usb --> mode["IPP over USBモードのときだけ"]
mode --> p
mode --> f
mode --> s
図4: 各機能はその機器が搭載し対応するプロトコルを実装している場合に限り、USB接続の機種はさらに動作モードが前提条件になる。
各機能は、その機器が機能を搭載し、対応するプロトコルを実装している場合に限ります。Mopriaの印刷対応だけを確認して、FAXやスキャンもWindows Ready Printへ移せると判断しないでください。
つまり、この計画は供給側の蛇口を段階的に閉めるものです。現場のPCに入っているドライバーがある日無効になることは、この計画の中には書かれていません。にもかかわらず現場で「変わった」と感じるのは、次の2つの経路でドライバーが入れ替わるからです。
- 新規インストール時の順位付け。Windowsは同じデバイスに複数のドライバーパッケージが合致するとき、各パッケージに順位(rank)を付け、最も良い順位のものを選びます。6 2026年7月1日の変更は、この順位付けでIPPクラスドライバーを常に優先させるものです。その機器にIPPクラスドライバーも合致する(プリンターがIPPに対応している)場合、PCの入れ替え、OSの再インストール、プリンターの再検出で、以前と違うドライバーが選ばれます。IPPクラスドライバーが候補にならない機器では、既存のメーカー製パッケージが引き続き選ばれ得ます。なお、IPPクラスドライバーへの適合(IPP対応)とMopria認証は別の条件です。Mopria認証は主にWPPで再登録できるかを決める条件で(4章。ネットワーク接続ならプリンター側でIPPが有効で到達できること、USB接続ならIPP over USBモードであることも要ります7)、Mopria認証を持たないIPP対応機でも、順位付けの変更でドライバーが入れ替わることはあり得ます。
- Windows protected print modeの有効化。次章で扱います。
flowchart TB
accTitle: IPPクラスドライバーへの適合とMopria認証は別の条件
accDescr: プリンターがIPPに対応していれば順位付けの変更でIPPクラスドライバーが選ばれてドライバーが入れ替わり得る一方、Mopria認証済みかどうかは別の条件としてWindows protected print modeで再登録できるかを決め、ネットワーク接続機ではIPPが有効で到達できること、USB接続機ではIPP over USBモードであることが要る
printer["プリンター"]
printer --> q1{"IPP対応か"}
q1 -->|"はい"| rank["入れ替わり得る"]
q1 -->|"いいえ"| keep["メーカー製のまま"]
printer --> q2{"Mopria認証済みか"}
q2 -->|"いいえ"| ng["WPPで再登録できない"]
q2 -->|"はい"| q3{"USB接続か"}
q3 -->|"いいえ"| q5{"IPPが有効で届くか"}
q5 -->|"はい"| ok["WPPで再登録できる"]
q5 -->|"いいえ"| ng
q3 -->|"はい"| q4{"IPP over USBモードか"}
q4 -->|"はい"| ok
q4 -->|"いいえ"| ng
図5: 順位付けの影響はIPP対応で、WPPで残れるかはMopria認証に加えてIPPが有効で到達できること(USB接続ならIPP over USBモード)で決まる。
flowchart TB
accTitle: 現場でドライバーが入れ替わる2つの経路
accDescr: IPPクラスドライバーが合致する機器では、PCの入れ替え・OS再インストール・プリンター再検出のときに順位付けでIPPクラスドライバーが選ばれてドライバーが入れ替わり、Windows protected print modeを有効化したときは第三者ドライバーのプリンターが削除され、Windows Ready Printで再登録できる機種ならドライバーが入れ替わり、再登録できない機種では印刷先が消失する
site["現場のPC"]
site --> r1["PC入替・OS再インストール・再検出"]
site --> r2["Windows protected print mode有効化"]
r1 --> rank["IPPクラスドライバーが合致する機器で優先"]
r2 --> del["第三者ドライバーのプリンターを削除"]
rank --> swap["ドライバーが入れ替わる"]
del --> re{"Ready Printで再登録できるか"}
re -->|"はい"| swap
re -->|"いいえ"| lost["印刷先が消失する"]
図6: 計画自体は既存ドライバーを止めないが、この2つの経路で現場のドライバーは入れ替わり、再登録できない機種では印刷先そのものが消える。
3. 仕組み ── 従来のドライバー経路とWindows Ready Print
Windowsの印刷は、アプリが描画命令を出し、スプーラーがそれをスプールし、プリンタードライバーがプリンターの言語(PDL)へ変換して送る、という構成でした。前回記事の2章で書いたGDI印刷パスとXPS印刷パスは、どちらもこの「ドライバーが変換する」構造の上にあります。8
flowchart TB
accTitle: 従来のドライバー経路
accDescr: 業務アプリのGDIまたはXPSの描画命令をSYSTEM権限のスプーラーがスプールし、第三者製のv3またはv4ドライバーが、ドライバー分離なしならスプーラー本体の中で、共有または分離ならスプーラーとは別のプロセスで独自のPDLへ変換してプリンターへ送る
app["業務アプリ(GDI / XPS)"] --> spooler["スプーラー(SYSTEM権限)"]
spooler --> iso{"ドライバー分離は"}
iso -->|"なし"| inproc["スプーラー本体の中で第三者ドライバー"]
iso -->|"共有 / 分離"| host["別プロセスで第三者ドライバー"]
inproc --> pdl["独自PDLへ変換"]
host --> pdl
pdl --> printer["プリンター"]
図7: 従来の経路では、分離の有無でプロセスは変わるが、印刷スタックの中で第三者のコードがPDLへの変換を担う構造は同じである。
第三者ドライバーが動くプロセスは、プリンタードライバー分離の設定で変わります。分離モードは「なし」(スプーラー本体の中で動く)、「共有」(スプーラーとは別の、他のドライバーと共有するプロセスで動く)、「分離」(ドライバー専用の別プロセスで動く)の3つです。INFでDriverIsolation=2を宣言していないドライバーは既定でスプーラー本体の中で動き、管理者は印刷の管理コンソールやグループポリシーで上書きできます。9 どの分離モードでも、第三者のコードがスプーラーの起動する印刷スタックの中で動く点は変わりません。
flowchart TB
accTitle: 第三者ドライバーが動くプロセスの決まり方
accDescr: INFでDriverIsolation=2を宣言したドライバーは既定でスプーラーとは別の共有プロセスで動き、宣言の無いドライバーは既定でスプーラー本体の中で動き、管理者は印刷の管理コンソールやグループポリシーで、共有・スプーラー本体の中・ドライバー専用の別プロセス(分離)のいずれかへ上書きできる
inf{"INFでDriverIsolation=2を宣言"}
inf -->|"はい"| shared["別の共有プロセスで動く(既定)"]
inf -->|"いいえ"| inproc["スプーラー本体の中で動く(既定)"]
admin["管理者の設定やポリシーで上書き"] -.-> shared
admin -.-> inproc
admin -.-> isolated["専用の別プロセスで動く(分離)"]
図8: 分離モードはINFの宣言と管理者の設定で決まり、宣言の無い古いドライバーは既定でスプーラー本体の中で動く。
Microsoftがこの構造を変えたい理由は、セキュリティです。Microsoft Learnの解説によれば、印刷まわりの不具合は過去3年間にMSRC(Microsoft Security Response Center)へ報告された事例の9%を占め、スプーラーはSYSTEM権限で動き、標準ユーザーからも広く到達でき、しかも第三者のコードをオンデマンドで読み込みます。何十年も前に作られたドライバーはCFGやCETといった現代の緩和策と互換性がなく、それらは「全部の参加者が対応して初めて効く」ため、ドライバーを読み込む限りスプーラーに適用できませんでした。10
flowchart TB
accTitle: 第三者ドライバーを読み込む限り緩和策が効かない理由
accDescr: SYSTEM権限のスプーラーが第三者コードを読み込み、古いドライバーがCFGやCETなどの緩和策と互換性がないため、全参加者の対応が必要な緩和策をスプーラーに適用できず、脆弱性が悪用されやすくなる
sys["スプーラーはSYSTEM権限"]
load["第三者コードをオンデマンドで読み込む"]
old["古いドライバーは緩和策と非互換"]
sys --> risk["脆弱性が悪用されやすい"]
load --> nomit["緩和策(CFG / CET / ACG)を適用できない"]
old --> nomit
nomit --> risk
図9: 緩和策は全参加者が対応して初めて効くため、ドライバーを外さない限りスプーラーを守り切れない。
代わりに用意されたのがWindows Ready Printです。IPP(Internet Printing Protocol)による印刷、eSCLによるスキャン、Universal Printを束ねた呼び名で、第三者ドライバーを必要としません。Mopria認証済みプリンターで動くよう設計されており、CPUアーキテクチャに依存しないことも利点として挙げられています。11 Windows 10 21H2以降には、Mopria準拠のプリンターをネットワークとUSBの両方で扱うMicrosoft IPP Class Driverが同梱されています。1
IPPはHTTPベースのプロトコルで、プリンターはipps://printer.example.com/ipp/printのようなURIで識別されます。ドライバーレス印刷が扱うPDLはPWG RasterやPDFなど公開標準に基づく少数に限られ、最終的な文書はクライアント側でレンダリングされます。10 Universal Printのクラウドキューも同梱のUniversal Print Class Driverを使い、スプーラーがIPP over HTTPSでジョブをサービスへ送ります。12
flowchart TB
accTitle: Windows Ready Printの経路
accDescr: 業務アプリの描画命令をスプーラーが受け、同梱のMicrosoft IPP Class DriverがクライアントでPWG RasterまたはPDFへレンダリングしてIPPでMopria認証済みプリンターへ送るか、同梱のUniversal Print Class DriverがIPP over HTTPSでUniversal Printサービスへ送り、Windows protected print modeはこのWindows Ready Printの経路だけを許す
app["業務アプリ(GDI / XPS)"] --> spooler["スプーラー"]
spooler --> ipp["Microsoft IPP Class Driver"]
ipp --> render["PWG Raster / PDFへレンダリング"]
render --> printer["Mopria認証済みプリンター(IPP)"]
spooler --> up["Universal Print Class Driver"]
up --> cloud["Universal Printサービス(IPP over HTTPS)"]
wpp["Windows protected print mode"] -.->|"Ready Printの経路だけを許す"| ipp
wpp -.-> up
図10: Windows Ready Printでも入口はスプーラーのままで、変換を担うのが同梱のクラスドライバー(IPPクラスドライバーかUniversal Print Class Driver)に変わる。
ここで大事なのは、アプリから見た入口は変わっていないことです。GDIやXPSで描画するアプリは、どちらの経路でも同じAPIを呼びます。変わるのは、その先で「誰が用紙一覧を返し、誰が独自機能を提供し、誰がPDLへ変換するか」です。だから、描画しかしていないアプリは影響が小さく、ドライバーの返す情報に依存しているアプリは影響を受けます。
4. Windows protected print modeで何が消えるか
Windows protected print mode(以下WPP)は、Windows Ready Printだけを使う動作モードです。Windows 11 24H2で導入され、設定アプリの「プリンターとスキャナー」、グループポリシーの「コンピューターの構成 > 管理用テンプレート > プリンター > Configure Windows protected print」、IntuneのOMA-URI ./Device/Vendor/MSFT/Policy/Config/Printers/ConfigureWindowsProtectedPrintのいずれかで有効化します。既定では無効で、無効のあいだはドライバーのインストールにも印刷機能にも制限はありません。13143 グループポリシーで有効化した場合、利用者本人は管理者に連絡しないと解除できません。2 IntuneのOMA-URIも同じADMXベースのデバイスポリシーを管理者側から適用する経路なので、3 本人が設定アプリから戻せるのは、本人が設定アプリで有効化した場合だけと考えておきます。
flowchart TB
accTitle: Windows protected print modeを有効化する3つの経路
accDescr: 設定アプリ、グループポリシー、IntuneのOMA-URIのいずれかでWindows protected print modeを有効化でき、本人が設定アプリから戻せるのは本人が設定アプリで有効化した場合だけで、グループポリシーやIntuneのポリシーで配った場合は管理者側でポリシーを変えないと解除できない
s["設定アプリ(本人が有効化)"] --> wpp["Windows protected print mode有効"]
g["グループポリシー"] --> wpp
i["Intune(OMA-URI)"] --> wpp
s -.->|"本人が設定アプリから戻せる"| off["解除"]
g -.->|"本人では戻せない"| adm["解除は管理者側のポリシー変更"]
i -.->|"本人では戻せない"| adm
図11: 有効化の経路は3つあり、本人が戻せるのは設定アプリから本人が有効化した場合だけである。
有効化すると何が起きるかは、Microsoftの概要ページに具体的に書かれています。2
- 第三者ドライバーを使うプリンターはアンインストールされ、ドライバーはドライバーストアから削除されます。 WPPが有効なあいだ、そのドライバーは使えません。
- Mopria認証済みでも、第三者ドライバーで導入されていたプリンターは一度アンインストールされます。 再インストールするとWindows Ready Printで動きますが、ネットワーク接続の機種はIPPが有効で到達できること、USB接続の機種はIPP over USBモードにしてあることが条件です(図12)。WPPを無効に戻しても、Windows Ready Printで入れ直したプリンターはそのままです。
- サポートされないソフトウェアプリンター(仮想プリンター)は削除されます。 例として「OneNote (Desktop)」が挙げられ、OneNote側には「Protected virtual printer」という新しい仮想プリンターが用意されました。
- Microsoft XPS Document WriterとFAXの仮想プリンターは削除されます。 WPPを無効に戻したあと、XPSは「Windowsの機能」から、FAXは「Windows FAXとスキャン」のオプション機能から手動で入れ直す手順が案内されています。
flowchart TB
accTitle: Windows protected print mode有効化時にプリンターに起きること
accDescr: 有効化すると第三者ドライバーで導入されたプリンターと、サポートされない仮想プリンター・XPS Document Writer・FAXの仮想プリンターは削除され、Mopria認証済みで、ネットワーク接続ならIPPが有効で到達でき、USB接続ならIPP over USBモードの機種はWindows Ready Printで再登録でき、非対応機は有効なあいだ使えない
on["WPPを有効化"]
on --> third["第三者ドライバーのプリンターを削除"]
on --> soft["非対応の仮想プリンターを削除"]
soft --> xps["XPS Document Writer・FAXも削除"]
third --> mopria{"Mopria認証済みか"}
mopria -->|"はい"| conn{"接続は"}
conn -->|"ネットワーク"| ipp{"IPPが有効で到達できるか"}
conn -->|"USB"| usb{"IPP over USBモードか"}
ipp -->|"はい"| re["Windows Ready Printで再登録"]
usb -->|"はい"| re
ipp -->|"いいえ"| no["有効なあいだ使えない"]
usb -->|"いいえ"| no
mopria -->|"いいえ"| no
図12: メーカー製ドライバーで入っていたキューは、Mopria認証済みでも一度消えて再登録が要る。
スプーラーの内部も変わります。ポートモニターがDLLであることを悪用した攻撃が成立しなくなり、AddPrintProvidorW(Microsoft Learnの解説ではAddPrintProviderWと表記されている、winspool.hの歴史的な綴りのAPI)のようなモジュール読み込みAPIは新しいモジュールを読み込めなくなり、IPPに必要なMicrosoft署名のバイナリだけが読み込まれます。XPSのレンダリングはSYSTEMではなくユーザー権限で動き、新しいスプーラーワーカープロセスはSeTcbPrivilegeなどを外した制限トークンで動作し、子プロセスの生成が禁止され、CFG/CET/ACGが有効になります。Point and Printも、IPP構成は残るものの第三者ドライバーのインストールは決して行わなくなります。10
flowchart TB
accTitle: Windows protected print modeでのスプーラーの変化
accDescr: 第三者バイナリを読み込まなくなることで、モジュール読み込みの制限、ユーザー権限でのXPSレンダリング、制限トークンのワーカープロセス、子プロセス生成の禁止、CFG・CET・ACGの有効化が可能になる
nodrv["第三者バイナリを読み込まない"]
nodrv --> r["読み込みの制限"]
nodrv --> l["権限の縮小"]
nodrv --> m["緩和策の有効化"]
r --> r2["Microsoft署名バイナリだけ"]
l --> l2["ユーザー権限XPS・制限トークン"]
m --> m2["子プロセス禁止・CFG / CET / ACG"]
図13: 図9で効かなかった緩和策は、第三者バイナリを外すことで初めて有効にできる。
業務アプリの目線で言い換えると、WPPが有効な環境では次のものが存在しなくなります。
| 消えるもの | 依存しがちなアプリのコード |
|---|---|
| メーカー製ドライバー(v3/v4)と、それが返す用紙・トレイ・独自機能 | PrinterSettings.PaperSizesやPrintCapabilitiesから特定の名前を探すコード、ドライバー固有の設定を保存するコード |
| ポートモニターDLL型の仮想プリンター(第三者製PDFプリンターの一部) | 「PDFプリンターに印刷して保存先を監視する」帳票アーカイブ |
| Microsoft XPS Document Writer | XPS Document Writerへ印刷して中間ファイルを作る処理(XpsDocumentなどでXPSファイルを直接生成する処理は仮想キューに依存しないため対象外) |
| 第三者ドライバーのPoint and Printによる自動配布 | 「プリントサーバーに接続すればドライバーが降ってくる」前提のキッティング手順 |
WPPが有効かどうかは、Windows 11 24H2以降のWinRT API Windows.Graphics.Printing.ProtectedPrint.WindowsProtectedPrintInfo.IsProtectedPrintEnabledで問い合わせられます。15 グループポリシーで有効化された場合のレジストリ値はHKLM\Software\Policies\Microsoft\Windows NT\Printers\WPP配下のWindowsProtectedPrintGroupPolicyStateです。3
なお、WPPを有効にしたクライアントからは、WPPが無効なプリントサーバーを印刷管理で管理できません。14 プリントサーバーの管理が必要な担当者には、WPPを無効にした管理用のクライアントを別に用意しておきます。
5. 既存アプリの棚卸し ── 見るべき4か所
5.1 まず現場のドライバー一覧を取る
改修の要否は、現場に何が入っているかを見ないと決まりません。PowerShellのPrintManagementモジュールは、管理者権限なしでプリンターとドライバーの一覧を返します。16
# キューごとに、ドライバー名・メジャーバージョン(3 = v3, 4 = v4)・提供元・INFファイル名を並べる
Get-Printer |
Select-Object Name, DriverName, PortName,
@{ Name = "DriverMajorVersion"; Expression = { (Get-PrinterDriver -Name $_.DriverName).MajorVersion } },
@{ Name = "Manufacturer"; Expression = { (Get-PrinterDriver -Name $_.DriverName).Manufacturer } },
@{ Name = "InfName"; Expression = { Split-Path -Leaf (Get-PrinterDriver -Name $_.DriverName).InfPath } } |
Sort-Object DriverName |
Format-Table -AutoSize
# 第三者のドライバーパッケージだけを、公開名(oemN.inf)・元のINF名・提供元とともに列挙する(管理者権限が要る)
pnputil /enum-drivers /class Printer
MajorVersionでv3とv4を見分ける方法はMicrosoft Learnのトラブルシューティングにも載っています。17 IPPクラスドライバーで入っているキューはDriverNameが「Microsoft IPP Class Driver」になるので、この列で、IPPクラスドライバーのキューとUniversal Printのキュー(同梱のUniversal Print Class Driverを使います12)は名前で分かります。それ以外の同梱とメーカー製は名前だけでは確実に分けられません。Get-PrinterDriverのInfPathはドライバーストア内のINFへのパスで、公開名を返す保証はないので、第三者のパッケージかどうかは、第三者のドライバーパッケージだけを列挙するpnputil /enum-driversの一覧(公開名oemN.inf・元のINF名・提供元)とInfPathのファイル名やManufacturerを突き合わせて判定します。同梱のパッケージはこの一覧に出ません。1819 pnputilには管理者権限が要ります。この4分類のうち、Universal PrintのキューはWindows Ready Printの一部なのでWPP互換側、メーカー製ドライバーのキューが入れ替わる候補です。それ以外の同梱ドライバーのキューは一律には扱えません。XPS Document WriterとFAXは削除されると明記され(4章)、Generic / Text OnlyのようなIPPクラスドライバー以外の物理プリンター向けドライバーのキューは残ることを前提にできず(5.4)、Microsoft Print to PDFは削除対象として挙げられていないので、キューごとに4章の表と照らして判定します。ただしDriverNameがIPPクラスドライバーでも、Mopria非認証機、IPPが無効か到達できないネットワーク機、IPP over USBモードでないUSB機はあり得るので、WPPで残るかは図5のとおりMopria認証・IPPの到達性・USBの動作モードを別に確認します。
flowchart TB
accTitle: 現場のプリンター一覧を棚卸しする手順
accDescr: PowerShellでキューとドライバーの一覧を取り、DriverNameと、Manufacturerおよびpnputilの第三者パッケージ一覧との突き合わせでIPPクラスドライバーのキュー、Universal Printのキュー(WPP互換)、それ以外の同梱ドライバーのキュー(XPS・FAXは削除、Generic / Text Onlyは残る前提にできず、Microsoft Print to PDFは削除対象に挙げられていないため個別に判定)、メーカー製ドライバーのキュー(入れ替わる候補)に分け、IPPクラスドライバーのキューはMopria認証・ネットワーク接続ならIPPが有効で到達できること・USB接続ならIPP over USBモードを別に確認したうえで、どちらのキューもアプリの設定や印刷コードが指しているキューと突き合わせて判定する
list["Get-Printer / Get-PrinterDriverで一覧を取る"]
list --> cls{"DriverNameと提供元は"}
cls -->|"IPP Class"| ipp["IPPクラスドライバーのキュー"]
cls -->|"Universal Print Class"| up["Universal Printのキュー"]
cls -->|"その他の同梱"| inbox["残るかを4章の表で個別に判定"]
cls -->|"メーカー製"| vendor["入れ替わる候補"]
ipp --> mop["Mopria・IPP到達・USBを確認"]
mop --> match["アプリの設定・コードと突き合わせる"]
up --> match
inbox --> match
vendor --> match
match --> judge["判断表で振り分ける"]
図14: 一覧を取って名前で分けるところまでは管理者権限なしで済み、提供元の突き合わせにはpnputilの管理者権限が要る。
同じことをアプリ内から確認したければ、WPFのSystem.PrintingでPrintQueue.QueueDriver.Nameを読みます。20 ただしSystem.Printing名前空間はWindowsサービスからの利用がサポートされていません。21 常駐サービスで印刷しているなら、この診断はサービスではなく管理ツール側に置いてください。サービスからの印刷そのものの制約はWindowsサービスの作り方と運用と前回記事の7章を参照してください。
using System.Printing;
// 管理ツールやデスクトップアプリから、各キューのドライバー名を列挙する
using var server = new LocalPrintServer();
foreach (PrintQueue queue in server.GetPrintQueues(
new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections }))
{
Console.WriteLine($"{queue.Name}\t{queue.QueueDriver?.Name}\t{queue.QueuePort?.Name}");
}
5.2 ドライバー固有の設定を保存・復元していないか
最も見つけにくく壊れやすいのがここです。Win32のDEVMODE構造体は、公開メンバーの直後にドライバー定義の非公開データを持てます。そのサイズはdmDriverExtraで示され、非公開部分はそのドライバーだけが解釈できます。Windowsが検証するのは公開部分だけで、非公開部分の壊れたデータはアプリやスプーラーのプロセスでドライバーをクラッシュさせ得ると、Microsoft Learnは警告しています。22
flowchart TB
accTitle: DEVMODEの公開部分と非公開部分
accDescr: DEVMODE構造体は公開メンバーの後ろにdmDriverExtraで示されるドライバー定義の非公開データを持ち、公開部分だけがWindowsに検証され、非公開部分はそのドライバーだけが解釈できるため、丸ごと保存するとドライバーが変わったときに意味を失う
dm["DEVMODE構造体"]
dm --> pub["公開部分(dmSize)"]
dm --> priv["非公開部分(dmDriverExtra)"]
pub --> chk["Windowsが検証する"]
priv --> only["そのドライバーだけが解釈できる"]
only --> lost["ドライバーが変わると意味を失う"]
図15: 丸ごと保存した設定のうち、壊れるのは非公開部分である。
ドライバー固有の状態を持ち歩く実装は二種類あり、壊れ方が違います。一つはDEVMODEの非公開部分を保存する実装です。DocumentPropertiesで表示したダイアログの結果やPrinterSettings.GetHdevmodeが返すバッファをdmDriverExtraのぶんまで丸ごとファイルに書き、次回SetHdevmodeで戻す形が典型で、図15の非公開部分をそのまま持ち歩いています。印刷ダイアログの結果などをSetHdevmodeで受け取ったPrinterSettingsは、dmDriverExtraのぶんの非公開領域を内部に複写して持っており、23 Serializableな型のバイナリシリアライズは既定でprivateフィールドも書き出すので、24 .NET Frameworkで印刷ダイアログ後のPrinterSettingsを丸ごとシリアライズする実装もこちら側です。ドライバーがIPPクラスドライバーに変わった瞬間、保存していた非公開データは意味を失います。
もう一つはPrinterSettingsやPageSettingsの公開プロパティの値を独自形式で保存する実装です。PaperSize・PaperSource・PrinterResolution・Duplexなどを個別に書き出す形で、.NET版のPrinterSettingsにはSerializable属性が無いので.NETではこの形になります。25 ここで保存されるのは公開プロパティの値であって、ネイティブのDEVMODEバッファやdmDriverExtra領域は含まれません。こちらが壊れる理由は別で、保存したPaperSizeやPaperSourceの値のうちドライバー依存のものが、メーカー製ドライバーの返した一覧に対する番号だからです。RawKindは、標準用紙ならPaperKind、標準給紙元ならPaperSourceKindに対応する安定した値で、ドライバーが変わっても意味を保ちます。2627 保証がないのはCustomやメーカー固有の値で、IPPクラスドライバーがその番号を同じ用紙やトレイと解釈するとは限りません。
flowchart TB
accTitle: DEVMODEの保存とマネージド値の保存は壊れ方が違う
accDescr: DEVMODEバッファを丸ごと保存する実装と、SetHdevmodeで非公開領域を受け取った後のPrinterSettingsを丸ごとシリアライズする実装は、非公開部分ごと持ち歩くためドライバーが変わると意味を失い、公開プロパティの値を保存する実装はCustomやメーカー固有の用紙・トレイの番号がメーカー製ドライバーの一覧に対する値のためIPPクラスドライバーで同じ意味になる保証がなく、どちらも意図だけを保存する設計へ置き換える
a["DEVMODEを丸ごと保存"]
a --> a1["非公開部分ごと持ち歩く"]
s["SetHdevmode後の丸ごと保存"] --> a1
a1 --> a2["ドライバーが変わると意味を失う"]
b["公開プロパティの値を保存"]
b --> b1["カスタム用紙・トレイの番号を持ち歩く"]
b1 --> b2["新ドライバーで同じ意味の保証がない"]
a2 --> c["どちらも意図だけの保存へ"]
b2 --> c
図16: SetHdevmode後のオブジェクトの丸ごと保存は非公開部分の側に入り、壊れ方は違ってもどちらもドライバーの状態を持ち歩いている。
flowchart TB
accTitle: 保存した用紙・トレイの値のうち壊れるもの
accDescr: RawKindのうちA4などの標準用紙(PaperKind)やUpper・Lowerなどの標準給紙元(PaperSourceKind)に対応する値はドライバーが変わっても意味を保ち、Customやメーカー固有の値はメーカー製ドライバーの一覧に対する番号なのでIPPクラスドライバーが同じ用紙・トレイと解釈する保証がない
raw["保存したRawKind"]
raw --> std["標準値(PaperKind等)"]
raw --> cus["Custom・メーカー固有の値"]
std --> keep["ドライバーが変わっても意味を保つ"]
cus --> lost["同じ用紙・トレイと解釈される保証がない"]
図17: 壊れるのは標準値ではなく、メーカー製ドライバーの一覧に対するカスタム値である。
XPS印刷パスのPrintTicketも同じ問題を抱えられます。PrintTicketはDEVMODEの後継として設計され、公開キーワードはpsk名前空間で定義されますが、デバイス固有のPrintTicketは私的な拡張を含んでよく、第三者の要素は「その第三者に明確に関連付けられた名前空間」に置くと規定されています。2829 保存したPrintTicket XMLの中にメーカーの名前空間が混ざっているなら、それはドライバー固有設定です。
保存するのは「意図」だけにし、ドライバーの状態を保存しない。 用紙サイズ・向き・両面・部数・トレイの選択を自分の設定ファイルに公開キーワードで持ち、印刷直前にPrintQueue.GetPrintCapabilitiesで現在のプリンターの能力を取り、意図をPrintTicketにしてMergeAndValidatePrintTicketに通してから使います。30 MergeAndValidatePrintTicketは、要求が能力に無いときに失敗するのではなく、ドライバーが競合を解決した(通常は既定値へ置き換えた)有効なチケットをValidationResultとして返します。戻り値のConflictStatusがConflictResolvedなら何かが置き換えられているので、ValidatedPrintTicketの両面やトレイを要求と突き合わせて差分をログに残し、ユーザーに通知します。31WinFormsならPrinterSettings.PaperSizesから名前ではなくKindや寸法で選び直します。トレイ(PaperSources)は注意が要ります。KindがUpperやLowerのように一意な標準値ならそれで再利用できますが、メーカー固有のトレイは複数がまとめてPaperSourceKind.Customとして返ることがあり、PaperSourceには用紙寸法もありません。27 その場合はKindだけでは特定できないので、現在のプリンターの能力に対して明示的に再マッピングするか、ユーザーに選び直してもらいます。ドライバーが変わっても「A4・縦・両面」という意図は残り、能力に無ければConflictStatusの時点で分かります。
flowchart TB
accTitle: 意図だけを保存して印刷直前に能力と突き合わせる設計
accDescr: 設定ファイルには用紙・向き・両面・部数・トレイの意図だけを公開キーワードで持ち、印刷直前にGetPrintCapabilitiesで現在のプリンターの能力を取り、MergeAndValidatePrintTicketに通し、ConflictStatusがNoConflictならそのまま印刷し、ConflictResolvedなら置き換えられた項目を要求と突き合わせてログと通知に回す
cfg["設定ファイル:意図だけ(用紙・向き・両面・部数)"]
cfg --> caps["印刷直前にGetPrintCapabilities"]
caps --> merge["MergeAndValidatePrintTicket"]
merge --> st{"ConflictStatusは"}
st -->|"NoConflict"| print["印刷"]
st -->|"ConflictResolved"| tell["要求との差分をログと通知"]
図18: ドライバーの状態ではなく意図を持てば設定は生き残り、置き換えられた項目はConflictStatusで捕まえられる。
5.3 プリンター名・キュー名に依存していないか
前回記事の7章で設定ファイルにプリンター名を持つことを勧めました。今回加えるのは、キュー名はドライバーの入れ替えで変わり得るという前提です。プリンターが再検出されて別のドライバーで入り直したとき、キューが以前と同じ名前で作られる保証はありません。旧キューを指した設定は空振りします。
依存はアプリのコードや設定ファイルだけにあるとは限りません。メーカーSDKや帳票ライブラリが内部でキュー名やドライバーを固定して呼んでいる製品があり、6章の表の「内部でWindowsのキュー・ドライバーを呼ぶ型」がそれです。自分のコードにキュー名が無くても、SDKのドキュメントと5.1の一覧で内部の依存を確かめます。
flowchart TB
accTitle: キュー名への依存が潜む3つの場所
accDescr: キュー名への依存は設定ファイルの固定名、コードに直書きした固定名、メーカーSDKや帳票ライブラリが内部で呼ぶキュー・ドライバーの3か所に潜み、前二者はコードと設定の検索で、後者はSDKのドキュメントと5.1の一覧で確かめる
dep["キュー名への依存"]
dep --> cfg["設定ファイルの固定名"]
dep --> code["コードに直書きした固定名"]
dep --> sdk["SDK・ライブラリ内部の固定"]
cfg --> grep["コードと設定を検索して見つける"]
code --> grep
sdk --> doc["SDKのドキュメントと5.1の一覧で確かめる"]
図19: 自分のコードにキュー名が無くても、SDKやライブラリの内部に依存が残っていることがある。
対処は、設定画面でユーザーが選び直せるようにしておくこと、起動時に設定のプリンター名がPrinterSettings.InstalledPrintersに存在するかを検証して、無ければログを残してユーザーに通知することです。黙って既定プリンターへフォールバックする実装は、伝票が別の部署のプリンターから出る事故を隠します。
flowchart TB
accTitle: 起動時のプリンター名の検証
accDescr: 起動時に設定ファイルのプリンター名がInstalledPrintersに存在するかを確認し、あれば印刷し、なければログを残してユーザーに通知して選び直させ、既定プリンターへ黙ってフォールバックしない
start["起動時:設定のプリンター名"]
start --> exists{"InstalledPrintersにあるか"}
exists -->|"はい"| print["そのキューへ印刷"]
exists -->|"いいえ"| log["ログを残してユーザーに通知"]
log --> pick["設定画面で選び直す"]
exists -.->|"やってはいけない"| silent["既定プリンターへ黙ってフォールバック"]
図20: 見つからないときに黙って別のプリンターへ出す実装が、いちばん発見の遅い事故を作る。
5.4 仮想プリンターとRAW送信
仮想プリンターへの依存は、WPPで最初に壊れます。ポートモニターDLL型などWPPでサポートされない第三者製PDF仮想プリンターに印刷して出力フォルダーを監視する帳票アーカイブ、XPS Document Writerで中間ファイルを作る処理は、4章の表のとおり存在しなくなります。WPPが削除するのはサポートされないソフトウェアプリンターで、OneNoteのようにWPP対応の仮想プリンターへ更新済みの製品は残るので、使っている製品がどちらかは7章の手順3の削除一覧で確かめます。前回記事の5章で書いたとおり、PDFが欲しいならPDFライブラリで直接生成する構成に寄せるのが、印刷スタックの変化から最も遠い位置です。
RAW送信は、OpenPrinterからStartDocPrinter(データ種別「RAW」)、WritePrinter、EndDocPrinterと呼んで、プリンターの言語で書かれたデータをスプーラー経由でそのまま流す方式です。この場合、文書はハードウェアの言語で印刷設定を完全に記述している必要があり、DEVMODEの設定は使われません。3233 ラベルプリンターやレシートプリンターの制御では定番の経路で、ドライバーは実質「ポートへの通り道」として使われています。
flowchart TB
accTitle: RAW送信の経路とWPPで消える箇所
accDescr: アプリがOpenPrinter・StartDocPrinter・WritePrinterでプリンター言語のデータをスプーラーへ流し、WPPで残らないキュー(メーカー製ドライバーのキューなど)が通り道になってポートからプリンターへ届くため、WPPでそのキューが消えると通り道がなくなる
app["アプリ:StartDocPrinter(RAW)・WritePrinter"]
app --> spooler["スプーラー"]
spooler --> queue["WPPで残らないキュー(通り道)"]
queue --> port["ポート"]
port --> printer["ラベル・レシートプリンター"]
wpp["WPP有効化"] -.->|"キューが消える"| queue
図21: RAW送信はドライバーを通り道としてしか使っていないが、通り道そのものが消える。
ここで確認すべきは、RAW送信がどのドライバーとポートの組み合わせで通っているかです。通り道の準備が要るのは、WPPで残らないキューにRAWを流している場合です。メーカー製ドライバーのキューだけでなく、「Generic / Text Only」のようなIPPクラスドライバー以外の物理プリンター向けWindows同梱ドライバーのキューも、WPPで残らないことを7章の手順3の削除一覧で確認できたなら同じ側です。WPPが許可する同梱ドライバーの一部にIPPクラスドライバー以外が含まれるとはMicrosoft Learnに書かれていません。3 消えたあとの通り道は自分で用意しなければなりません。IPPクラスドライバーのキューに独自PDLをRAWで流せるかどうかはMicrosoft Learnに記述がなく、プリンター側のIPP実装が受け付けるPDLに依存します。
6. ラベル・レシートプリンターの逃げ道
Mopria認証を取れないプリンターにはドライバー署名の例外がある、と2章で書きました。1 とはいえ、この例外は個別審査の対象になれることを示すだけで、メーカーの提出もMicrosoftの承認も保証しません。ドライバーが手に入り続けたとしても、WPPが有効な環境で使えるわけではありません。Microsoftの印刷トラブルシューティングにも、2021年の更新後にUSB接続のレシート・ラベルプリンターで印刷できなくなりKnown Issue Rollbackで解消した事例があります。34
小村ソフトが勧めているのは、ラベル・レシートの出力経路を「スプーラーに依存するもの」と「依存しないもの」に分けて把握し、後者を少なくとも一つ持つことです。経路の名前だけでは依存の有無は決まりません。IPPクラスドライバー経由の通常の印刷は、3章の図10のとおりスプーラーを通り、WPPと互換ではあってもスプーラーの外には出ていません。メーカーSDKも、内部でWindowsのキューやドライバーを呼んでいる製品があり、その場合は第三者ドライバーが消えれば同じように止まります。SDKが直接TCP/USB/シリアルで装置と話しているのか、Windowsのキューを経由しているのかは、SDKのドキュメントと5.1の一覧で確認します。Universal Printのクラウドキューは、Windows Ready Printの一部として位置づけられている(1章の判断表)ので、WPP互換の側に置きます。IPPクラスドライバーでもUniversal Printでもないキューは、第三者ドライバーのキューと4章の表で削除されると分かるもの(XPS・FAX)はWPPで止まり、Microsoft Print to PDFのように削除対象に挙げられていない同梱のキューは5.1のとおり個別に判定します。
| 経路 | スプーラー依存 | 向いている場面 | 注意点 |
|---|---|---|---|
| メーカーSDK(直接TCP/USB/シリアルで装置と通信する型) | しない | メーカーが長期にSDKを保守している機種 | SDKのビット数・依存ランタイム・署名の更新を追う必要がある |
| メーカーSDK(内部でWindowsのキュー・ドライバーを呼ぶ型) | する | 既存資産として残す場合のみ | WPPで第三者ドライバーが消えると同じように止まる。逃げ道にはならない |
| TCPソケットでプリンター言語を直接送る | しない | ネットワーク接続のラベルプリンター | 接続断・再送・タイムアウトの設計が要る。シリアル通信アプリの落とし穴の再接続設計がそのまま使える |
| シリアル(仮想COM)/ USBで直接送る | しない | レシートプリンター、据え置きの計測装置併設機 | WindowsアプリでUSB機器を扱う方法で整理した仮想COM・HID・WinUSBの選択が前提になる |
| IPPクラスドライバー経由で印刷する(IPP over USB / IPP) | する(WPP互換) | Mopria認証済みでIPPを有効化できる機種 | スプーラー経由のまま。プリンターによってはIPPが既定で無効で、設定で有効化が要る7 |
flowchart TB
accTitle: 出力経路がスプーラーに依存するかを判定する流れ
accDescr: 候補の経路がWindowsの印刷キューへ送る場合は、IPPクラスドライバーのキューでプリンターがMopria認証済みかつネットワーク接続ならIPPが有効で到達でき、USB接続ならIPP over USBモードのものと、Windows Ready Printの一部であるUniversal Printのキューはスプーラー依存でもWPP互換、Mopria非認証機や第三者ドライバーのキュー、XPS Document Writer・FAXのように4章の表で削除されるキューはWPPで止まり得て、Microsoft Print to PDFのように削除対象に挙げられていない同梱キューは5.1のとおり個別に判定し、キューへ送らない場合はSDKが内部でキューやドライバーを呼ぶなら同じ判定に戻り、呼ばないSDKや装置へ直接送る経路はスプーラーに依存しない逃げ道になる
route["候補の出力経路"]
route --> q1{"Windowsの印刷キューへ送るか"}
q1 -->|"はい"| q4{"IPPクラスドライバーのキューか"}
q4 -->|"はい"| q5{"Mopria認証済みか"}
q5 -->|"はい"| q9{"IPP到達か(USBはover USB)"}
q9 -->|"はい"| depok["依存するがWPP互換"]
q9 -->|"いいえ"| dep["依存し、WPPで止まり得る"]
q5 -->|"いいえ"| dep
q4 -->|"いいえ"| q6{"Universal Printのキューか"}
q6 -->|"はい"| depok
q6 -->|"いいえ"| q7{"4章の表で削除されるか"}
q7 -->|"はい(第三者ドライバー・XPS・FAX)"| dep
q7 -->|"いいえ(Print to PDFなど)"| indiv["個別に判定(5.1)"]
q1 -->|"いいえ"| q2{"メーカーSDKを介するか"}
q2 -->|"はい"| q3{"内部でキュー・ドライバーを呼ぶか"}
chk["確認:SDK文書と5.1の一覧"] -.-> q3
q3 -->|"はい"| q4
q3 -->|"いいえ"| indep["依存しない逃げ道"]
q2 -->|"いいえ"| indep
図22: 最終的にどのキューを通るかで決まり、Mopria認証済み機のIPPクラスドライバーのキューとUniversal Printのキュー以外は、削除対象に挙げられていない同梱キューを除いてWPPで止まり得る。
前回記事のFAQで「対象機種がWindowsの通常のプリンタードライバーとして振る舞うのか、専用SDK経由の制御が必要なのかを確認するところから」と書きました。ラベル・レシートは、Windowsの印刷スタックが変わっても影響を受けない経路を、少なくとも一つ持っておく。
7. 検証手順 ── WPPを先に有効にして壊す
備えはWPPを有効にした環境で実際に印刷して確かめます。本番PCは使わず、ネットワーク接続のプリンターなら同じプリンターに到達できるVMで足ります。USB接続の機種(IPP over USBへの再登録や6章の直接USB経路)を評価するなら、同じUSBインターフェースをパススルーできるVMを除き、物理の検証機を使います。
- Windows 11 24H2以降の検証機を用意し、5.1の棚卸しで分かったアプリが使うキューをすべて再現する。 現場と同じ物理プリンターをメーカー製ドライバーで入れるだけでなく、第三者製PDF仮想プリンターや
Generic / Text Onlyのような同梱ドライバーのキューも現場と同じ構成で入れます。手順3の削除一覧で判定できるのは、検証機に存在するキューだけだからです。5.1のスクリプトで、ドライバー名とバージョンを記録しておきます。 - アプリの印刷機能を一通り動かし、出力を保存する。 用紙・トレイ・両面・部数の設定画面、帳票ごとの印刷、PDF出力、ラベル印刷。
- WPPを有効にする。 設定アプリの「プリンターとスキャナー」から「Windows protected print mode」の「セットアップ」を選ぶと、削除されるプリンターがダイアログに表示されるので、記録します。2 グループポリシーの「Configure Windows protected print」で有効にする場合はこのダイアログが出ません。14 適用前に5.1のスクリプト(
Get-Printer)の結果を取り、ポリシー適用後は検証機を再起動して、IsProtectedPrintEnabled(4章)か設定アプリの表示でWPPが有効になったことを確認してから、もう一度同じスクリプトを実行して差分を削除されたキューとして記録します。 - 削除された互換プリンターを再インストールする。 Windows Ready Printで入り直し、
DriverNameが「Microsoft IPP Class Driver」に変わったことを5.1のスクリプトで確認します。 - 手順2をもう一度動かす。 設定画面の選択肢が変わっていないか、保存していた設定が復元できるか、キュー名の変更でアプリが印刷先を見失っていないか、出力の余白・フォント・罫線が変わっていないかを、手順2の出力と突き合わせます。
- Mopria非対応の機種は、6章の別経路で動くことを確認する。 「プリンターが一覧に無い」を再現できていれば、備えは正しく機能しています。
WPPを使わない判断をした環境(8章の決定木)では、WPPを有効にするとキューごと削除されて順位付けの影響が見えなくなるため、手順3と4を行いません。代わりに、順位変更の対象になる物理のIPP対応機はWPPを無効にしたまま検証機で削除して再検出・再インストールし、IPPクラスドライバーのキューに変わるか(2章)を5.1のスクリプトで確認してから手順5を行います。クラウドや仮想のキューには再検出する機器も順位変更もないので、実際のキューで手順2の印刷を確認します。
flowchart TB
accTitle: WPPを有効にして壊してから直す検証の流れ
accDescr: 検証機に5.1の棚卸しで分かったアプリが使う物理・仮想・同梱のキューをすべて再現して記録し、印刷機能を一通り動かして出力を保存し、WPPを有効にして削除されたプリンターを記録し、互換機を再登録してから同じ印刷を再実行して差分を突き合わせ、非対応機は別経路で動くことを確認する
s1["検証機にアプリが使う全キューを再現し記録"]
s1 --> s2["印刷機能を一通り動かし出力を保存"]
s2 --> s3["WPPを有効化し削除されたプリンターを記録"]
s3 --> s4["互換機をWindows Ready Printで再登録"]
s4 --> s5["同じ印刷を再実行して差分を突き合わせる"]
s3 --> s6["非対応機は別経路で動くことを確認"]
図23: 「壊す」手順を先に踏むことで、備えの抜けが本番前に見える。
flowchart TB
accTitle: 検証機に再現するキュー
accDescr: 5.1の棚卸しで分かったアプリが使うキューのうち、メーカー製ドライバーの物理プリンター、第三者製PDFなどの仮想プリンター、Generic / Text Onlyなどの同梱ドライバーのキューをすべて検証機へ現場と同じ構成で再現し、手順3の削除一覧で判定できるのは検証機に存在するキューだけであることを示す
inv["5.1の棚卸し:アプリが使うキュー"]
inv --> phys["物理プリンター(メーカー製)"]
inv --> virt["仮想プリンター(第三者製PDF等)"]
inv --> inbox["同梱ドライバー(Generic / Text Only等)"]
phys --> vm["検証機に同じ構成で再現"]
virt --> vm
inbox --> vm
vm --> judge["手順3の削除一覧で残るかを判定"]
note["無いキューは削除差分に現れない"] -.-> judge
図24: 検証機に無いキューは削除差分に現れないので、棚卸しで分かったキューを先にすべて再現する。
WPPはグループポリシーやIntuneで有効化した場合、利用者本人では解除できません。23 検証機ではローカルの設定アプリから有効化し、終わったら「オフにする」で戻します。WPPを無効に戻しても、Windows Ready Printで入れ直したプリンターはそのままで、非互換だったプリンターは手動で再インストールします。24
キッティングでは、グループポリシーからIntuneへで整理した配布の仕組みに、WPPのポリシー(グループポリシーまたはOMA-URI)とプリンターの再登録手順を組み込みます。Point and Printでドライバーを配っていた運用は、2021年のKB5005652以降そもそも管理者資格情報が要るようになっており、34 WPPではドライバー配布自体が行われないため、10 この機会に手順から外すのが整理として素直です。
flowchart TB
accTitle: キッティング手順の見直し
accDescr: Point and Printで第三者ドライバーを配っていた手順は、2021年以降は管理者資格情報が要るうえWPPでは配布自体が行われないため外し、代わりにWPPのポリシー(グループポリシーまたはOMA-URI)とプリンターの再登録手順を配布の仕組みに組み込む
old["Point and Printで第三者ドライバーを配る"]
old --> why1["2021年以降は管理者資格情報が要る"]
old --> why2["WPPでは配布自体が行われない"]
why1 --> drop["手順から外す"]
why2 --> drop
drop --> add["WPPのポリシーと再登録手順を組み込む"]
図25: ドライバーを配る手順は、WPPのポリシーとプリンターの再登録を配る手順に置き換わる。
8. まとめ
決定木 ── そのアプリは直すのか、確かめるだけでよいのか
コードの依存を見る前に、印刷先のキューがWPPの下で残るかを先に判定します。
- 印刷先のキューはWPPで残るか、または物理プリンターをWindows Ready Printで再登録できる機種か。 Universal PrintのクラウドキューやWPP対応の仮想プリンターは、再登録の操作なしでWPPで使える(1章、5.4)ので次へ進みます。Mopria非対応機をメーカー製ドライバーで使っているなら、コードが
PrintDocumentだけでもWPPを有効にした時点でキューごと消えます。6章の別経路を用意するか、WPPを使わない判断を先に下します。その機器がIPP対応で、順位付けの変更によってドライバーが入れ替わり得るなら(2章)、WPPを使わなくても再検出などでドライバーが変わるため、そのうえで次へ進みます。最後の検証は7章末尾の再検出です。再登録できる機種も次へ進みます。WPPを使わず順位変更の影響も無い環境は、7章の検証なしに現在の経路のまま運用します。 - ドライバー固有の設定を保存・復元しているか。
DEVMODEの丸ごと保存、SetHdevmode後のPrinterSettingsの丸ごとシリアライズ、公開プロパティのカスタム値の保存、メーカー名前空間を含むPrintTicketの保存があれば直す(5.2)。 - 特定のキュー名や仮想プリンターに依存しているか(メーカーSDKや帳票ライブラリが内部で呼ぶものを含む)。 名前の固定、WPPでサポートされない仮想プリンター(ポートモニターDLL型などWPP非対応と確認できた第三者製PDFプリンター)経由のアーカイブ、XPS Document Writerへ印刷して中間ファイルを作る処理があれば直す(5.3、5.4)。仮想プリンターがWPPで残るかは、7章の手順3の削除一覧で判定します。
XpsDocumentなどでXPSファイルを直接生成している処理は仮想キューに依存しておらず、この対象ではありません。 - RAW送信をWPPで残らないキュー(メーカー製ドライバーのキューや、7章の手順3の削除一覧で残らないと確認した同梱ドライバーのキュー)に流しているか。 あれば通り道を用意する(5.4、6章)。
- 上のどれにも当てはまらず、
PrintDocumentやFixedDocumentで描いているだけか。 それなら検証する。WPPを使う環境は7章で、WPPを使わない環境は、物理のIPP対応機なら7章末尾の再検出で、クラウドや仮想のキューなら実際の出力確認で確かめます。
flowchart TB
accTitle: 直すのか確かめるだけでよいのかの決定木
accDescr: 印刷先のキューがWPPで残るか(Universal PrintのクラウドキューやWPP対応の仮想プリンター)または物理プリンターをWindows Ready Printで再登録できるかを先に判定し、できなければ別経路の用意かWPP不使用を選び、その機器がIPP対応で順位付けの変更により入れ替わり得るならドライバー固有設定の保存・キュー名や仮想プリンターへの依存(SDKやライブラリ内部を含む)・RAW送信の順に確認して該当すれば直したうえで次へ進み、最後はWPPを使う環境なら7章のWPP有効化検証へ、使わない環境なら物理のIPP対応機はWPPを無効にしたままの再検出検証へ、クラウドや仮想のキューは実際の出力確認へ進み、WPPを使わず入れ替わりの影響も無ければ現在の経路のまま運用する
q0{"キューがWPPで残るか再登録できるか"}
q0 -->|"いいえ"| alt{"どうするか"}
alt -->|"別経路を用意"| qi{"IPP対応で入れ替わり得るか"}
alt -->|"WPPを使わない"| qi2{"IPP対応で入れ替わり得るか"}
qi -->|"はい"| q1{"ドライバー固有設定を保存しているか"}
qi -->|"いいえ"| verify["検証だけ(7章)"]
qi2 -->|"はい"| q1
qi2 -->|"いいえ"| keep["現在の経路のまま運用"]
q0 -->|"はい"| q1
q1 -->|"はい"| fix1["直す(5.2)"]
fix1 --> q2{"キュー名・仮想プリンターに依存しているか"}
sdk["SDK・ライブラリ内部の依存も含む"] -.-> q2
q1 -->|"いいえ"| q2
q2 -->|"はい"| fix2["直す(5.3・5.4)"]
fix2 --> q3{"RAW送信をWPPで残らないキューに流しているか"}
q2 -->|"いいえ"| q3
q3 -->|"はい"| fix3["通り道を用意(6章)"]
fix3 --> vq{"WPPを使うか"}
q3 -->|"いいえ"| vq
vq -->|"はい"| verify
vq -->|"いいえ"| pq{"物理のIPP対応機か"}
pq -->|"はい"| redetect["WPPなしで再検出の検証(7章末尾)"]
pq -->|"いいえ"| outchk["実際のキューで出力確認"]
図26: キューがWPPで残るかを先に判定し、コードの依存は一つ直しても次の確認へ進み、直した経路も最後は検証する。WPPを使わない場合は7章のWPP有効化ではなく、物理のIPP対応機はWPPを無効にしたままの再検出で、クラウド・仮想のキューは実際の出力で確かめる。
いまからやっておくこと
- 現場のプリンターとドライバーの一覧を、5.1のスクリプトで取っておく。 納品先ごとに「v3/v4か、IPPクラスドライバーか、Mopria認証済みか、ネットワーク機ならIPPが有効で到達できるか、USB機ならIPP over USBモードか」を表にする。
- 設定に保存するのは意図だけにする。 ドライバーの状態を保存しない。能力は印刷直前に問い合わせる。
- キュー名が変わっても止まらないようにする。 存在確認と、失敗時のログと通知を入れる。黙ってフォールバックしない。
- PDFはライブラリで作る。 仮想プリンター経由の帳票保存をやめる。
- ラベル・レシートは印刷スタックから切り離した経路を一つ持つ。
- WPPを使う環境は、WPPを有効にした検証機で実際に壊してから直す。 使わない環境は、物理のIPP対応機はWPPを無効にしたまま再検出し、クラウド・仮想のキューは実際のキューで出力を確認する(7章末尾)。
WPPが既定で有効になる時期は示されていないため、4 2027年7月1日のドライバー更新停止を備えの期限にはできません。期限は、自社でWPPを有効にする前か、Windows 11 24H2以降の機能更新を現場へ展開する前に置きます。2027年7月1日は供給側の節目であって、アプリ側の締め切りではありません。1
flowchart TB
accTitle: 業務アプリ側の備えの期限の置き方
accDescr: いま一覧取得と棚卸しを行い、経路の変更と検証を、自社でWPPを有効にする前または24H2以降の機能更新を展開する前という自社側の期限までに終え、2027年7月1日のドライバー更新停止は供給側の節目であって備えの期限ではなく、時期未定のWPPの既定有効化がいつ来ても影響を受けない状態を先に作る
now["いま:一覧取得と棚卸し"]
now --> prep["経路変更と検証"]
prep --> deadline["期限:自社でWPPを有効にする前 / 機能更新の展開前"]
deadline --> fine["WPPの既定有効化(時期未定)が来ても影響を受けない"]
ms["2027年7月1日:ドライバー更新停止"] -.->|"供給側の節目であって期限ではない"| prep
図27: 期限は自社の展開計画に置き、Microsoftの節目の日付を締め切りにしない。
Windows 10で止まっている環境については、この計画の対象外である代わりに、通常チャネルのWindows 10(22H2)のサポートが2025年10月に終わっています。Windows 10 Enterprise LTSCやIoT Enterprise LTSCはエディションごとに別の期限があるので、使っているエディションのライフサイクルを確認してください。ESUで延命するか、LTSCへ切り替えるかの判断はWindows 10サポート終了後の現実解と、産業用PC向けには産業用PCにはどのWindowsを入れるべきかを参照してください。印刷の備えは、その移行先のWindows 11で7章の検証をやり直すところまでがセットです。
関連記事
- Windows業務アプリの印刷とPDF出力 ── System.Drawing.Printing / WPF / 帳票ライブラリの使い分け
- Excel帳票出力の作り方 - COM/Open XML/テンプレート
- Windowsサービスの作り方と運用 ── タスクスケジューラとの使い分けからBackgroundServiceのサービス化まで
- WindowsアプリでUSB機器を扱う方法 ── 仮想COM・HID・WinUSBの選び方
- シリアル通信アプリの落とし穴 - 再接続とログ設計まで
- グループポリシーからIntuneへ ── 中小企業のデバイス管理移行
- Windows 10サポート終了後の現実解 ── ESU・LTSC・買い替えの判断
関連する相談領域
合同会社小村ソフトでは、帳票・ラベル印刷を持つ業務アプリのプリンタードライバー依存の棚卸し、印刷経路の見直し(PDF直接生成、ラベルプリンターの直接制御)、Windows protected print modeを前提にした検証計画の設計を扱っています。
参考リンク
-
Microsoft Learn, End of servicing plan for third-party printer drivers on Windows. 2025年5月更新のタイムライン(2026年1月15日・2026年7月1日・2027年7月1日)、対象がWindows 11以降とWindows Server 2025以降であること、既存ドライバーはインストール可能でv3/v4の機能を無効化する計画がないこと、署名例外の3条件(Mopria認証不可・Windows 10以下上限・ネイティブARM64)、USB機はIPP over USBモードでのみ各機能を使えること、Windows 10 21H2以降にMicrosoft IPP Class Driverが同梱されていることについて。 ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9
-
Microsoft Learn, Overview of Windows protected print mode. 有効化時に第三者ドライバーを使うプリンターがアンインストールされドライバーストアから削除されること、Mopria認証済みでも第三者ドライバーで導入されたプリンターは再インストールが要ること、サポートされないソフトウェアプリンター(OneNote (Desktop)など)・XPS・FAXが削除されること、グループポリシーで有効化した場合はユーザーが解除できないこと、設定アプリからの有効化・無効化手順について。 ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
Microsoft Learn, Policy CSP - Printers: ConfigureWindowsProtectedPrint. 適用OSがWindows 11 24H2以降であること、既定では無効でドライバーや印刷機能に制限がないこと、ADMXの対応先レジストリキー
Software\Policies\Microsoft\Windows NT\Printers\WPPと値WindowsProtectedPrintGroupPolicyStateについて。 ↩ ↩2 ↩3 ↩4 ↩5 ↩6 -
Microsoft Learn, Windows protected print mode FAQ. 非互換プリンターは有効化中に再インストールできず無効化後は手動で入れ直すこと、独自機能はPrint Support Appで提供されること、Windows protected print modeが将来の時点で既定で有効になることについて。 ↩ ↩2 ↩3
-
Microsoft Learn, Legacy printer driver submission process. 2026年1月15日以降、WHQL・Attestationを問わずプリンタードライバーの提出が既定でブロックされ、正当化文書を添えた手動審査になったことについて。 ↩
-
Microsoft Learn, Step 2: A Driver Package for the Device is Selected. 複数のドライバーパッケージが合致するとき、Windowsが各パッケージに順位を付けて最も良い順位のものをインストールすること、同順位なら日付とバージョンで選ぶことについて。 ↩
-
Microsoft Learn, IPP printers with the Universal Print Connector. Microsoft IPP Class DriverがMopria認証済みプリンターとIPPで通信する同梱ドライバーであること、プリンターによってはIPPが既定で無効で有効化が必要なことについて。 ↩ ↩2
-
Microsoft Learn, Windows Print Path Overview. WindowsにGDI印刷パスとXPS印刷パスの2つの主要な印刷パスが存在することについて。 ↩
-
Microsoft Learn, Printer driver isolation. 分離モード(Shared / Isolated / None)の意味、INFの
DriverIsolationキーワードを宣言しないドライバーが既定でスプーラープロセス内で動くこと、管理者が印刷の管理コンソールやスプーラー関数で各ドライバーの設定を上書きできることについて。 ↩ -
Microsoft Learn, More information on Windows protected print mode for enterprises and developers. 印刷の不具合が過去3年のMSRC報告の9%を占めること、スプーラーがSYSTEMで動き第三者コードを読み込むこと、古いドライバーがCFG/CET/ACGと互換性がないこと、IPPがHTTP POSTベースでURIで識別されPWG RasterやPDFなど少数のPDLをクライアント側でレンダリングすること、WPPでのモジュール読み込み制限・ユーザー権限でのXPSレンダリング・制限トークン・子プロセス生成禁止・バイナリ緩和策、Point and Printが第三者ドライバーをインストールしなくなることについて。 ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Discover Windows Ready Print. Windows Ready PrintがIPP・eSCL・Universal Printを含む呼び名で、第三者ドライバーを必要とせず、Mopria認証済みプリンター向けに設計され、PCのアーキテクチャに依存しないことについて。 ↩
-
Microsoft Learn, Universal Print troubleshooting - Understanding the stages of a print job. Universal Printのプリンターが同梱のUniversal Print class driverを使い、スプーラーがIPP over HTTPSでジョブをサービスへ送ることについて。 ↩ ↩2
-
Microsoft Learn, What’s new in Windows 11, version 24H2. Windows protected print modeが24H2で追加され、設定アプリまたはグループポリシーで有効化できることについて。 ↩
-
Microsoft Learn, Windows protected print mode for enterprises. グループポリシー「Configure Windows protected print」での有効化手順、IntuneのOMA-URI、WPP有効なクライアントからWPP無効なサーバーを印刷管理で管理できないことについて。 ↩ ↩2 ↩3
-
Microsoft Learn, WindowsProtectedPrintInfo.IsProtectedPrintEnabled Property. Windows 11 24H2で導入された、現在のデバイスでWPPが有効かを返す静的プロパティについて。 ↩
-
Microsoft Learn, Get-PrinterDriver. 指定したコンピューターのプリンタードライバー一覧を返し、管理者資格情報を必要としないことについて。 ↩
-
Microsoft Learn, How to display printer status in a UWP device app.
get-printer | Select Name, {(get-printerdriver -Name $_.DriverName).MajorVersion}でv3かv4かを見分ける手順について。 ↩ -
Microsoft Learn, PnPUtil. ドライバーストアのパッケージを列挙する際に同梱(in-box)のパッケージは対象外で、同梱以外のパッケージだけが列挙されることについて。 ↩
-
Microsoft Learn, PnPUtil Command Syntax.
/enum-driversが第三者のドライバーパッケージを列挙し、Windows 11 21H2以降は/classでクラス名を絞り込めること、管理者としてコマンドプロンプトを開いて実行することについて。 ↩ -
Microsoft Learn, PrintQueue.QueueDriver Property. キューが使うプリンタードライバーを
PrintDriverとして取得できることについて。 ↩ -
Microsoft Learn, PrintServer Class.
System.Printing名前空間のクラスがWindowsサービスやASP.NETアプリケーション内での利用をサポートしておらず、性能低下や実行時例外を起こし得ることについて。 ↩ -
Microsoft Learn, DEVMODEW structure (wingdi.h). 公開メンバーの直後にドライバー定義の非公開メンバーを置けること、そのサイズを
dmDriverExtraで示すこと、Windowsが検証するのは公開部分だけで非公開部分の壊れたデータがドライバーをクラッシュさせ得ることについて。 ↩ -
dotnet/winforms(GitHub), PrinterSettings.cs.
SetHdevmodeがdmDriverExtraのぶんの非公開領域を内部に複写し、GetHdevmodeがそれを書き戻すこと、それ以外の経路では非公開領域を持たないことについて。 ↩ -
Microsoft Learn, SerializableAttribute Class.
Serializable属性を付けた型ではprivateとpublicのすべてのフィールドが既定で直列化され、除外するにはNonSerialized属性を付けることについて。 ↩ -
Microsoft Learn, PrinterSettings Class. .NET Framework版の宣言には
Serializable属性が付き、.NET版には付いていないこと、GetHdevmodeとSetHdevmodeがDEVMODEとの相互変換であることについて。 ↩ -
Microsoft Learn, PaperSize.RawKind Property.
RawKindが標準の用紙種類の値かカスタム値を表す整数であることについて。 ↩ -
Microsoft Learn, PaperSourceKind Enum.
Upper・Lowerなどの標準の給紙元の種類に加え、プリンター固有の給紙元を表すCustomが定義されていることについて。 ↩ ↩2 -
Microsoft Learn, Print Schema. Print Schemaが第三者による拡張を認め、私的なProperty要素はその第三者に明確に関連付けられた名前空間に属さなければならないことについて。 ↩
-
Microsoft Learn, Print Schema-Related Technologies. PrintTicketが
DEVMODEの後継であること、デバイス固有のPrintTicketが特定機種向けの私的拡張を含み得ることについて。 ↩ -
Microsoft Learn, How to: Validate and Merge PrintTickets.
PrintQueue.GetPrintCapabilitiesでプリンターの対応機能を確認し、MergeAndValidatePrintTicketで要求内容をプリンター固有の妥当なPrintTicketにマージ・検証する手順について。 ↩ -
Microsoft Learn, ConflictStatus Enum.
MergeAndValidatePrintTicketが対応していない設定をドライバーに置き換えさせて有効なチケットを返し、置き換えがあったことをValidationResult.ConflictStatusのConflictResolvedで報告することについて。 ↩ -
Microsoft Learn, WritePrinter function.
StartDocPrinterからEndDocPrinterまでの手順、データ種別が「RAW」のときは文書がハードウェアの言語でDEVMODE相当の設定を完全に記述している必要があること、WritePrinterがブロッキング関数でUIスレッドから呼ぶと応答なしに見え得ることについて。 ↩ -
Microsoft Learn, RAW data type. RAWデータがさらなる処理なしにプリントモニターへ送られること、PCLコマンドで構成されるファイルがその例であることについて。 ↩
-
Microsoft Learn, Printing issue troubleshooting guidance. KB5005652以降のPoint and Printの既定動作変更で管理者資格情報が求められるようになったこと、2021年の更新プログラム適用後にUSB接続のレシート・ラベルプリンターで印刷できなくなりKnown Issue Rollbackで解消された事例について。 ↩ ↩2
関連する記事
同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。
Windows業務アプリの印刷とPDF出力 ── System.Drawing.Printing / WPF / 帳票ライブラリの使い分け
PrintDocumentによるWinForms印刷、WPFのFlowDocument/FixedDocument印刷、PDF出力の選択肢を要件別の判断表で整理します。改ページ制御やDPIのずれ、Windowsサービスからの印刷の危険まで解説します。
WinForms/WPFアプリの多言語化 ── resx・サテライトアセンブリ・カルチャ切り替えの実務
Windowsデスクトップアプリの多言語化を整理します。CurrentCultureとCurrentUICultureの違い、resxとサテライトアセンブリの仕組み、WPFでの現実的な方式選択、実行時の言語切り替え、書式・RTLまで解説します。
Windowsアプリ 外注・受託開発を依頼する前に整理したいこと
Windowsアプリの外注・受託開発を依頼する前に、既存ソフト改修、装置連携、COM/ActiveX、配布・更新、保守の整理ポイントを解説します。
Windowsアプリのタスクトレイ常駐とトースト通知 ── NotifyIconの落とし穴とAppNotificationの選び方
業務Windowsアプリのタスクトレイ常駐とトースト通知の実装を整理します。NotifyIconの正しい使い方、Explorer再起動時の再登録、トーストAPI3種の選定判断表、通知が届かないケースまで解説します。
WinForms/WPFアプリにEntra ID認証を組み込む ── MSAL.NETとWAMブローカーの実務構成
WinForms/WPFデスクトップアプリにEntra ID認証を組み込む手順を整理します。パブリッククライアントの考え方、アプリ登録、MSAL.NETのAcquireTokenSilent、WAMブローカー、トークンキャッシュの永続化まで解説します。
関連トピック
このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。
Windows技術トピック
Windows 開発、不具合調査、既存資産活用の技術トピックをまとめた入口です。
UI スレッド / タイマーテーマ
WPF / WinForms、UI スレッド、async/await、タイマー設計を整理するトピックです。
このテーマがつながるサービス
この記事は次のサービスページにつながります。近い入口からご覧ください。
Windowsアプリ開発
帳票・ラベル印刷を持つ業務アプリの印刷経路の見直しと改修はWindowsアプリ開発の相談範囲だからです。
技術相談・設計レビュー
既存アプリのプリンタードライバー依存の棚卸しと、置き換えの順番を決める設計レビューは技術相談の範囲だからです。
よくある質問
この記事のテーマについて、相談時によくある質問をまとめています。
- 今動いているプリンターとアプリは、2026年7月や2027年7月を過ぎると突然印刷できなくなりますか?
- なりません。Microsoftの計画は「新しいサードパーティ製ドライバーをWindows Updateに載せない」「順位付けでIPPクラスドライバーを優先する」「更新を受け付けない」という供給側の段階的な打ち切りで、既存のドライバーを無効化するものではないと明記されています。既存ドライバーはメーカー提供のインストーラーからも引き続きインストールできます。危ないのは、IPPクラスドライバーが合致する機器で、PCの入れ替えやOSの再インストールのときにドライバーが自動的にIPPクラスドライバーへ置き換わる場面と、Windows protected print modeが有効化された場面です。
- Windows protected print modeは既定で有効になりますか?
- 本記事執筆時点(2026年9月)では既定で無効で、設定アプリかグループポリシー、Intuneで有効化します。ただしMicrosoftのFAQは「将来の時点で既定で有効になる」と明言しています。時期は示されていないため、有効化されても困らない状態を先に作っておくのが備えです。
- ラベルプリンターやレシートプリンターはどうなりますか?
- Mopria認証を取れないプリンターについては、2026年1月15日以降もドライバーの署名が例外的に認められる条件に挙げられています。つまりメーカー製ドライバーが当面残る可能性はありますが、Windows protected print modeを有効にした環境では第三者ドライバーを使うプリンターがアンインストールされるため、そのままでは使えません。装置と直接TCP/USB/シリアルで通信するメーカーSDKや、プリンター言語の直接送信で制御する経路を持っておくと、印刷スプーラーの変化から切り離せます。内部でWindowsのキューやドライバーを呼ぶSDKは、第三者ドライバーが消えれば同じように止まるため逃げ道になりません。
- アプリの印刷コードはPrintDocumentのままでよいですか?
- GDI印刷パスやXPS印刷パスは残り、Microsoftはv3/v4ドライバーの機能を無効化する計画はないと明言しています。PrintDocumentやFixedDocumentで描画しているだけのアプリは、直す対象ではなく確認する対象です。直す対象は、ドライバー固有の設定(DEVMODEの非公開部分やPrintTicketの私的名前空間)を保存・復元しているコード、特定のキュー名や仮想プリンター名に依存しているコード(メーカーSDKや帳票ライブラリが内部で呼ぶものを含む)、WPPで残らないキュー(メーカー製ドライバーのキューなど)へRAWデータをスプーラー経由で流しているコードです。ただし、印刷先のプリンター自体がWindows Ready Printで再登録できない機種なら、コードが描画だけでもWindows protected print modeの下ではキューごと消えるため、別経路の用意が先です。
- 何から手を付けるべきですか?
- 納品先のプリンターとドライバーの一覧を取るところからです。PowerShellのGet-PrinterとGet-PrinterDriverで、どのキューがどのドライバー(v3かv4か、IPPクラスドライバーか)を使っているかは管理者権限なしで取れます。次に、その一覧の中でアプリが名前指定・設定保存・RAW送信をしているキューを突き合わせ、本記事の判断表で「そのまま」「検証」「経路を変える」に振り分けます。