「새 PC로 바꿨더니 같은 프린터인데 용지나 용지함의 선택지가 다르다」「저장해 둔 인쇄 설정이 복원되지 않는다」「라벨 프린터가 목록에서 사라졌다」. 프린터 드라이버의 제공 종료에 대비한다는 것은, 이런 변화가 일어나도 업무가 멈추지 않게 하는 일입니다.
먼저 짚어야 할 것은 드라이버의 제공 종료 계획과 Windows protected print mode의 활성화는 별개의 이야기라는 점입니다. 계획의 날짜가 지났다고 해서 기존 인쇄가 일제히 멈추는 것은 아닙니다. 반면 드라이버가 선택되는 방식이 달라지는 장면이나 Windows protected print mode를 켜는 장면에서는, 앱이 의존하던 설정과 인쇄 대상이 사라집니다.12
이 글에서는 WinForms·WPF 같은 Windows 업무 앱을 유지보수하는 개발자와 프린터를 배포하는 관리자를 대상으로, 무엇이 바뀌는가, 무엇을 조사하는가, 어디를 고치는가, 어떻게 검증하는가의 순서로 정리합니다. 인쇄 API나 PDF 출력 방식 자체를 고르는 법은 지난 글 Windows 업무 앱의 인쇄와 PDF 출력을 참조하십시오.
전제 환경은 Windows 11(WPP의 검증은 24H2 이후), PowerShell 5.1 이상(PrintManagement 모듈), C#(.NET 6 이후 또는 .NET Framework 4.x, System.Drawing.Printing / System.Printing)입니다. 난이도는 중급입니다.
1. 먼저 결론
인쇄 코드를 일괄로 다시 쓰는 것이 아니라, 먼저 「인쇄 대상이 남는가」를 확인하고 그다음에 드라이버에 의존하는 부분을 고칩니다.
판단의 순서는 다음 3단계입니다.
| 순서 | 확인할 것 | 다음 행동 |
|---|---|---|
| 1. 인쇄 대상을 확인한다 | WPP에서 큐가 남는가. 물리 프린터를 Windows Ready Print로 다시 등록할 수 있는가 | 남지 않으면 다른 출력 경로를 준비하거나, WPP를 쓰지 않는다는 판단을 먼저 내립니다 |
| 2. 앱의 의존을 확인한다 | 드라이버 고유 설정, 큐 이름, 가상 프린터, RAW 전송에 의존하고 있지 않은가 | 해당하는 부분을 고칩니다. SDK나 장표 라이브러리 내부의 의존도 포함합니다 |
| 3. 실제 출력으로 확인한다 | 드라이버나 큐가 바뀌어도 장표·PDF·라벨을 올바로 출력할 수 있는가 | WPP를 쓰는 환경은 켜고 검증하고, 쓰지 않는 환경은 다른 절차로 검증합니다 |
PrintDocument나 FixedDocument로 그리기만 한다면 기본적으로 개선이 아니라 검증의 대상입니다. 다만 인쇄 대상 큐 자체가 WPP에서 사라지고 다시 등록도 할 수 없는 경우에는, 그리기 코드에 문제가 없어도 인쇄할 수 없습니다. 다른 경로가 먼저 필요합니다.
작업부터 시작한다면 5.1의 목록 취득 → 4장·5.1의 표로 인쇄 대상 판정 → 5.2~5.5의 의존 확인 → 6장의 경로 선택 → 7장의 검증 순서로 진행하십시오. 판단이 망설여지는 지점의 배경은 2~4장에서 설명합니다.
이후로는 Windows protected print mode를 WPP로 줄여 부릅니다. 「큐」는 Windows에 등록된 인쇄 대상을, 「스풀러」는 인쇄 작업을 받아 출력 대상으로 넘기는 구조를 가리킵니다.
그림의 실선은 항상 성립하는 관계, 점선은 조건이 붙는 관계입니다(성립 조건은 상세 페이지의 관계별 설명에 적혀 있습니다). 관계 전체 목록(총 39건, 근거와 확신도 포함)과 주요 개념의 정의는 지식 맵 상세 페이지에 정리되어 있습니다(일본어). 데이터: JSON-LD / Turtle
2. 무엇이 정해졌는가 ── 3단계의 타임라인
2.1 끝나는 것은 공급과 업데이트이지, 기존 드라이버의 일제 정지가 아니다
일차 자료는 Microsoft Learn의 「End of servicing plan for third-party printer drivers on Windows」입니다. 2023년 9월에 계획이 발표되었고, 2025년 5월에 날짜가 조정되었습니다. 집필 시점의 계획은 다음과 같습니다.1
| 시기 | 변경되는 것 | 업무 앱 쪽에서 주의할 것 |
|---|---|---|
| 2026년 1월 15일 | Windows 11 이후와 Windows Server 2025 이후에서, 새로운 프린터 드라이버를 Windows Update에 게시하지 않음. 기존 드라이버의 업데이트는 개별 심사로 가능 | 새 PC·프린터를 배포할 때 제조사 드라이버를 기존과 같은 방법으로 구할 수 있다고 장담할 수 없습니다 |
| 2026년 7월 1일 | 프린터 드라이버의 순위 지정을, 항상 Windows에 포함된 IPP 클래스 드라이버를 우선하도록 변경 | IPP 클래스 드라이버도 일치하는 기기에서는 PC 교체나 프린터 재검색으로 다른 드라이버가 선택될 수 있습니다 |
| 2027년 7월 1일 | 보안 수정을 제외하고 서드파티 프린터 드라이버의 업데이트를 받지 않음 | 업데이트 중단 날짜를 앱 쪽 대비의 기한으로 착각하지 마십시오 |
기존 드라이버는 계속해서 Windows Update나 제조사가 제공하는 설치 프로그램에서 설치할 수 있고, Microsoft는 v3/v4 드라이버의 기능을 비활성화할 계획이 없다고 밝히고 있습니다. 즉 이것은 드라이버의 공급과 업데이트를 단계적으로 끝내는 계획이지, 현장 PC에 들어 있는 드라이버를 그날 비활성화하는 계획이 아닙니다.1
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장).
2.2 현장에서 드라이버가 바뀌는 것은 주로 두 가지 장면
계획이 기존 드라이버를 멈추지 않더라도, 다음 장면에서는 앱에서 보이는 환경이 달라집니다.
| 장면 | 무슨 일이 일어나는가 |
|---|---|
| PC 교체·OS 재설치·프린터 재검색 | 그 기기에 IPP 클래스 드라이버도 일치하는 경우, 순위 지정에 따라 이전과 다른 드라이버가 선택됩니다 |
| WPP의 활성화 | 서드파티 드라이버를 쓰는 프린터가 삭제됩니다. 호환 기기는 Windows Ready Print로 다시 등록하고, 비호환 기기는 그대로는 쓸 수 없게 됩니다 |
Windows는 같은 장치에 여러 드라이버 패키지가 일치하면 각각에 순위(rank)를 매겨 가장 좋은 것을 선택합니다. 2026년 7월 1일의 변경은 이 선택에서 IPP 클래스 드라이버를 우선하도록 하는 것입니다. IPP 클래스 드라이버가 후보가 되지 않는 기기에서는 제조사 패키지가 계속 선택될 수 있습니다.31
flowchart TB
accTitle: 현장에서 드라이버가 교체되는 두 가지 경로
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["인쇄 대상이 사라진다"]
그림 2: 제공 종료 계획과 WPP를 나누어 생각하면, 드라이버가 바뀌는 장면과 인쇄 대상 자체가 사라지는 장면을 구분할 수 있습니다.
여기서 IPP 지원과 Mopria 인증을 같은 조건으로 다루지 않는 것도 중요합니다.
| 조건 | 주로 무엇의 판정에 쓰는가 |
|---|---|
| IPP 클래스 드라이버가 그 기기에 일치할 것 | 순위 지정의 변경으로 드라이버가 교체될 수 있는가 |
| Mopria 인증을 받았고, 네트워크 연결이면 IPP가 켜져 있고 도달할 수 있을 것, USB 연결이면 IPP over USB 모드일 것 | 물리 프린터를 WPP 아래에서 Windows Ready Print로 다시 등록할 수 있는가 |
Mopria 비인증이라도 IPP를 지원하는 기기에서는, WPP를 쓰지 않아도 순위 지정의 변경으로 드라이버가 교체될 수 있습니다. 반대로 드라이버 이름이 「Microsoft IPP Class Driver」라는 것만으로는 WPP에서 쓸 수 있다는 것까지 확인한 것이 아닙니다.14
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
그림 3: 순위 지정의 영향은 IPP 지원 여부로 정해지고, WPP에서 남을 수 있는지는 Mopria 인증에 더해 IPP가 켜져 있고 도달할 수 있는지(USB 연결이면 IPP over USB 모드)로 정해집니다.
2.3 드라이버 서명에는 예외가 있지만 지속이 보장되지는 않는다
2026년 1월 15일 이후에도 다음 중 하나에 해당하는 드라이버는 서명의 예외 신청을 개별 심사에 올릴 수 있습니다.1
- Mopria 인증을 받을 수 없는 프린터용.
- Windows 10 이하를 대상 OS의 상한으로 삼은 패키지.
- 네이티브 ARM64 드라이버.
WHQL이든 Attestation이든 제출은 기본적으로 차단되며, 정당성 문서를 첨부한 수동 심사가 됩니다. 조건에 해당하더라도 제조사가 제출하는 것이나 Microsoft가 승인하는 것이 보장되지는 않습니다.5 또한 서명된 드라이버를 구할 수 있다는 것과, WPP를 켠 환경에서 쓸 수 있다는 것은 별개입니다. 라벨·영수증 프린터의 대비는 6장에서 다룹니다.
flowchart TB
accTitle: 2026년 1월 15일 이후에도 드라이버 서명이 인정되는 조건
accDescr: 제조사의 드라이버 제출은 기본적으로 차단되고 Mopria 인증을 받을 수 없는 프린터, Windows 10 이하를 상한으로 삼은 패키지, 네이티브 ARM64 드라이버라는 세 조건 중 하나에 해당하는 것만 예외 신청을 개별 심사에 올릴 수 있으나 심사를 거쳐 승인되는 경우가 있을 뿐 서명이 보장되지는 않는다
submit["제조사의 드라이버 제출"]
submit --> block["기본적으로 차단"]
block --> c1["Mopria 인증을 받을 수 없는 기종"]
block --> c2["Windows 10 이하가 상한"]
block --> c3["네이티브 ARM64"]
c1 --> apply["예외 신청이 가능"]
c2 --> apply
c3 --> apply
apply --> review["개별 심사"]
review --> maybe["승인되는 경우가 있다(보장은 없다)"]
그림 4: 조건에 해당해도 심사에 올릴 수 있을 뿐, 서명될지는 보장되지 않습니다.
3. 구조 ── 기존의 드라이버 경로와 Windows Ready Print
3.1 바뀌는 것은 그리기 API 너머의 인쇄 경로
기존의 Windows 인쇄에서는 앱이 GDI나 XPS의 그리기 명령을 내고, 스풀러가 작업을 받고, 프린터 드라이버가 프린터의 언어(PDL)로 변환해 보냈습니다. GDI 인쇄 경로와 XPS 인쇄 경로는 둘 다 이 구조 위에 있습니다.6
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["프린터"]
그림 5: 기존 경로에서는 격리 여부에 따라 프로세스는 달라지지만, 인쇄 스택 안에서 서드파티 코드가 PDL 변환을 맡는 구조는 같습니다.
그 후속으로 마련된 것이 Windows Ready Print입니다. IPP(Internet Printing Protocol)에 의한 인쇄, eSCL에 의한 스캔, Universal Print를 묶은 이름이며 서드파티 드라이버를 필요로 하지 않습니다. Mopria 인증을 받은 프린터를 위해 설계되었고, CPU 아키텍처에 의존하지 않는 점도 장점입니다.7
Windows 10 21H2 이후에는 Mopria 준수 프린터를 네트워크와 USB로 다루는 Microsoft IPP Class Driver가 포함되어 있습니다.1 Universal Print의 클라우드 큐는 포함된 Universal Print Class Driver를 사용합니다.8
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
그림 6: Windows Ready Print도 스풀러를 거칩니다. 변환과 전송을 맡는 쪽이 서드파티 드라이버에서 포함된 클래스 드라이버로 바뀝니다.
IPP는 HTTP 기반 프로토콜이며 프린터를 ipps://printer.example.com/ipp/print 같은 URI로 식별합니다. 드라이버 없는 인쇄에서 쓰는 PDL은 PWG Raster나 PDF 등 공개 표준에 기반한 소수의 형식으로 한정되고, 최종 문서는 클라이언트 쪽에서 렌더링됩니다.9 Universal Print에서는 스풀러가 IPP over HTTPS로 작업을 서비스에 보냅니다.8
앱에서 본 입구는 바뀌지 않습니다. GDI나 XPS로 그리는 앱은 같은 API를 호출합니다. 바뀌는 것은 그 너머에서 용지와 용지함의 목록을 돌려주고, 고유 기능을 제공하고, PDL로 변환하는 구조입니다. 그래서 그리기만 하는 앱보다, 드라이버가 돌려주는 정보나 고유 설정에 의존하는 앱이 더 큰 영향을 받습니다. 제조사 고유 기능에 대해서는 Print Support App(PSA)에 의한 제공도 확인합니다.10
3.2 복합기는 인쇄·팩스·스캔을 따로따로 확인한다
Windows Ready Print로 옮길 수 있는지는 기기가 그 기능을 탑재하고 대응하는 프로토콜을 구현하고 있는 것이 전제입니다.1
| 기능 | 네트워크 연결에서 필요한 지원 | USB 연결에서 추가되는 조건 |
|---|---|---|
| 인쇄 | IPP | IPP over USB 모드 |
| 팩스 송신 | IPP Fax Out | IPP over USB 모드 |
| 스캔 | eSCL 또는 WS-Scan | IPP over USB 모드 |
Mopria의 인쇄 지원만 보고 팩스나 스캔도 이전할 수 있다고 판단하지 마십시오.
flowchart TB
accTitle: 복합기의 각 기능을 따로 확인하는 순서
accDescr: 사용할 기능을 하나씩 고르고 기기에의 탑재, 표의 대응 프로토콜, USB 연결 시의 IPP over USB 모드를 차례로 확인하며 인쇄 기능의 결과를 팩스나 스캔에 그대로 적용하지 않고 나머지 기능도 따로 확인한다
start["사용할 기능을 하나 고른다"]
start --> feature{"기기가 그 기능을 탑재했는가?"}
feature -->|"예"| protocol{"표의 프로토콜을 지원하는가?"}
feature -->|"아니오"| unmet["이 기능의 조건은 미충족"]
protocol -->|"예"| usb{"USB 연결인가?"}
protocol -->|"아니오"| unmet
usb -->|"예"| mode{"IPP over USB 모드인가?"}
usb -->|"아니오"| checked["이 기능의 조건을 확인 완료"]
mode -->|"예"| checked
mode -->|"아니오"| unmet
checked --> next["나머지 기능을 따로 확인"]
unmet --> next
그림 7: 기능의 탑재, 대응 프로토콜, 연결 시의 추가 조건 순으로 확인합니다. 인쇄의 확인 결과를 팩스나 스캔에 그대로 쓰지 않습니다.
3.3 배경에 있는 것은 인쇄 스택의 보안
Microsoft Learn의 해설에서는 인쇄 관련 결함이, 그 해설이 집계한 지난 3년간 MSRC(Microsoft Security Response Center) 신고 사례의 9%를 차지한다고 되어 있습니다. 스풀러는 SYSTEM 권한으로 동작하고, 표준 사용자에게서도 널리 도달할 수 있으며, 서드파티 코드를 필요할 때 로드합니다. 오래된 드라이버 중에는 CFG나 CET 같은 현대적 완화책과 호환되지 않는 것이 있어, 참여하는 코드 전체의 대응이 필요한 완화책을 적용하기 어려운 구조입니다.9
flowchart TB
accTitle: 서드파티 드라이버를 로드하는 한 완화책이 듣지 않는 이유
accDescr: SYSTEM 권한의 스풀러가 서드파티 코드를 로드하고 오래된 드라이버가 CFG나 CET 같은 완화책과 호환되지 않기 때문에 모든 참여자의 대응이 필요한 완화책을 스풀러에 적용할 수 없어 취약점이 악용되기 쉬워진다
sys["스풀러는 SYSTEM 권한"]
load["서드파티 코드를 필요할 때 로드"]
old["오래된 드라이버는 완화책과 비호환"]
sys --> risk["취약점이 악용되기 쉽다"]
load --> nomit["완화책(CFG / CET / ACG)을 적용할 수 없다"]
old --> nomit
nomit --> risk
그림 8: 완화책은 모든 참여자가 대응해야 비로소 듣기 때문에, 드라이버를 떼어 내지 않는 한 스풀러를 끝까지 지킬 수 없습니다.
서드파티 드라이버가 동작하는 위치는 프린터 드라이버 격리 설정에 따라 달라집니다.11
| 격리 모드 | 드라이버가 동작하는 위치 |
|---|---|
| 없음(None) | 스풀러 본체의 프로세스 안 |
| 공유(Shared) | 스풀러와는 다른, 다른 드라이버와 공유하는 프로세스 |
| 격리(Isolated) | 드라이버 전용의 별도 프로세스 |
INF에서 DriverIsolation=2를 선언한 드라이버는 기본적으로 공유 프로세스를 쓰고, 선언하지 않은 드라이버는 기본적으로 스풀러 본체 안에서 동작합니다. 관리자는 인쇄 관리 콘솔이나 그룹 정책으로 덮어쓸 수 있습니다. 다만 어느 모드에서든 인쇄 스택 안에서 서드파티 코드가 동작한다는 점은 달라지지 않습니다.11 WPP는 이 서드파티 코드에 대한 의존을 떼어 내는 동작 모드입니다.
flowchart TB
accTitle: 서드파티 드라이버가 동작하는 프로세스가 정해지는 방식
accDescr: INF에서 DriverIsolation=2를 선언한 드라이버는 기본적으로 스풀러와는 다른 공유 프로세스에서 동작하고 선언이 없는 드라이버는 기본적으로 스풀러 본체 안에서 동작하며 관리자는 인쇄 관리 콘솔이나 그룹 정책으로 공유, 스풀러 본체 안, 드라이버 전용의 별도 프로세스(격리) 중 하나로 덮어쓸 수 있다
inf{"INF에서 DriverIsolation=2를 선언"}
inf -->|"예"| shared["다른 공유 프로세스에서 동작(기본값)"]
inf -->|"아니오"| inproc["스풀러 본체 안에서 동작(기본값)"]
admin["관리자의 설정이나 정책으로 덮어쓰기"] -.-> shared
admin -.-> inproc
admin -.-> isolated["전용의 별도 프로세스에서 동작(격리)"]
그림 9: 격리 모드는 INF의 선언과 관리자의 설정으로 정해지며, 선언이 없는 오래된 드라이버는 기본적으로 스풀러 본체 안에서 동작합니다.
4. Windows protected print mode에서 무엇이 사라지는가
4.1 WPP는 「Windows Ready Print만 쓴다」는 동작 모드
WPP는 Windows 11 24H2에서 도입되었습니다. 이 글의 집필 시점에는 기본값이 꺼짐이며, 꺼져 있는 동안에는 드라이버 설치나 인쇄 기능에 제한이 없습니다.1213 켜는 방법과 되돌릴 수 있는 사람을 나누어 정리합니다.
| 켜는 경로 | 설정하는 곳 | 다시 끄는 방법 |
|---|---|---|
| 설정 앱 | 「프린터 및 스캐너」의 Windows protected print mode | 본인이 설정 앱에서 켠 경우에는 본인이 설정 앱에서 되돌릴 수 있습니다 |
| 그룹 정책 | 「컴퓨터 구성 > 관리 템플릿 > 프린터 > Configure Windows protected print」 | 관리자가 정책을 변경합니다 |
| Intune | OMA-URI ./Device/Vendor/MSFT/Policy/Config/Printers/ConfigureWindowsProtectedPrint |
관리자가 정책을 변경합니다 |
그룹 정책으로 켠 경우, 사용자는 관리자에게 연락하지 않으면 해제할 수 없습니다. Intune의 OMA-URI도 같은 ADMX 기반의 디바이스 정책을 적용하는 경로입니다. 본인이 설정 화면에서 되돌릴 수 있는 것은 본인이 설정 화면에서 켠 경우라고 생각해 두십시오.14213
flowchart TB
accTitle: Windows protected print mode를 켜는 세 가지 경로
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
그림 10: 켜는 경로는 세 가지이며, 본인이 되돌릴 수 있는 것은 설정 앱에서 본인이 켠 경우뿐입니다.
4.2 남는 큐, 사라지는 큐, 다시 등록해야 하는 큐
켤 때의 영향은 프린터 본체뿐 아니라 지금 어떤 드라이버로 등록되어 있는가에 따라서도 달라집니다.2
| 현재의 인쇄 대상 | WPP를 켜면 | 대비하는 방법 |
|---|---|---|
| 서드파티 드라이버(v3/v4)로 등록한 물리 프린터 | 큐가 제거되고 드라이버도 드라이버 저장소에서 삭제됩니다 | 호환 기기라면 Windows Ready Print로 다시 등록합니다. 비호환 기기는 다른 경로나 WPP 미사용을 선택합니다 |
| Mopria 인증을 받았더라도 제조사 드라이버로 등록한 프린터 | 한 번 삭제됩니다. 인증을 받았다고 해서 기존 큐가 남는 것은 아닙니다 | 네트워크라면 IPP의 활성화와 도달성을, USB라면 IPP over USB 모드를 확인하고 다시 등록합니다 |
| Windows Ready Print로 등록이 끝난 호환 프린터 | 계속 쓸 수 있습니다 | 기능, 설정, 실제 출력을 검증합니다 |
| Universal Print의 클라우드 큐 | Windows Ready Print의 일부로서 WPP 호환 쪽에 있습니다 | 큐 이름에 대한 의존을 확인하고 실제 출력을 검증합니다 |
| 지원되지 않는 소프트웨어 프린터 | 삭제됩니다 | 서드파티 PDF 프린터 등은 제품의 WPP 지원을 확인합니다. 장표 보관은 PDF 라이브러리에서의 직접 생성으로 옮깁니다 |
| WPP 지원으로 업데이트된 가상 프린터 | 미지원 제품과 한꺼번에 다루지 않습니다. OneNote에는 Protected virtual printer가 마련되어 있습니다 | 사용 중인 제품·큐가 어느 쪽인지 검증합니다 |
| Microsoft XPS Document Writer, 팩스의 가상 프린터 | 삭제됩니다 | WPP를 다시 끈 뒤 XPS는 「Windows 기능」, 팩스는 「Windows 팩스 및 스캔」의 선택적 기능에서 수동으로 다시 넣습니다 |
flowchart TB
accTitle: Windows protected print mode를 켤 때 프린터에 일어나는 일
accDescr: 켜면 서드파티 드라이버로 도입된 프린터와 지원되지 않는 가상 프린터·XPS Document Writer·팩스의 가상 프린터는 삭제되고 Mopria 인증을 받았으며 네트워크 연결이면 IPP가 켜져 있고 도달할 수 있고 USB 연결이면 IPP over USB 모드인 기종은 Windows Ready Print로 다시 등록할 수 있으며 미지원 기기는 켜져 있는 동안 쓸 수 없다
on["WPP를 켠다"]
on --> third["서드파티 드라이버의 프린터를 삭제"]
on --> soft["미지원 가상 프린터를 삭제"]
soft --> xps["XPS Document Writer·팩스도 삭제"]
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
그림 11: 제조사 드라이버의 큐는 Mopria 인증을 받았더라도 한 번 사라집니다. 다시 등록할 수 있는 조건은 따로 확인합니다.
WPP가 켜져 있는 동안 삭제된 서드파티 드라이버는 쓸 수 없습니다. 또한 WPP를 다시 꺼도, Windows Ready Print로 다시 넣은 프린터가 원래 드라이버로 자동으로 돌아가지는 않습니다.210
앱 쪽에서는 제조사 드라이버가 돌려주는 용지·용지함·고유 기능, 포트 모니터 DLL 형태의 가상 프린터, XPS Document Writer를 전제로 하는 처리가 확인 대상입니다. XpsDocument 등으로 XPS 파일을 직접 생성하는 처리는, XPS Document Writer라는 가상 큐로 인쇄하는 것과는 별개이며 이 삭제의 대상이 아닙니다.
4.3 관리와 스풀러 내부에도 변경이 있다
WPP에서는 포트 모니터 DLL 같은 서드파티 바이너리를 로드하지 않게 됩니다. AddPrintProvidorW 같은 모듈 로드 API도 새 모듈을 로드할 수 없고, IPP에 필요한 Microsoft 서명 바이너리만 로드됩니다. AddPrintProvidorW는 winspool.h의 역사적 철자이며, Microsoft Learn의 해설에서는 AddPrintProviderW로 표기되어 있습니다.9
이 제한으로 XPS 렌더링은 SYSTEM이 아니라 사용자 권한으로 동작하고, 새 스풀러 작업자 프로세스에는 SeTcbPrivilege 등을 뺀 제한된 토큰이 쓰입니다. 자식 프로세스의 생성이 금지되고 CFG·CET·ACG도 켜집니다.9
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"]
그림 12: 그림 8에서 듣지 않던 완화책은 서드파티 바이너리를 떼어 내야 비로소 켤 수 있습니다.
Point and Print는 IPP 구성은 남지만, 서드파티 드라이버의 설치는 하지 않게 됩니다. 「프린트 서버에 연결하면 드라이버가 배포된다」를 전제로 한 초기 구축 절차도 재검토가 필요합니다.9
WPP가 현재 켜져 있는지는 Windows 11 24H2 이후의 WinRT API Windows.Graphics.Printing.ProtectedPrint.WindowsProtectedPrintInfo.IsProtectedPrintEnabled로 확인할 수 있습니다.15 그룹 정책의 설정값은 HKLM\Software\Policies\Microsoft\Windows NT\Printers\WPP 아래의 WindowsProtectedPrintGroupPolicyState입니다.13
참고로 WPP가 켜진 클라이언트에서는 WPP가 꺼진 프린트 서버를 인쇄 관리로 관리할 수 없습니다. 관리 담당자에게는 WPP를 끈 관리용 클라이언트를 따로 준비합니다.14
5. 기존 앱의 점검 ── 봐야 할 4곳
flowchart TB
accTitle: 업무 앱에서 점검할 4곳
accDescr: 업무 앱의 인쇄 코드 가운데 드라이버 고유 설정의 저장, 큐 이름 의존(SDK나 라이브러리 내부의 것 포함), WPP에서 지원되지 않는 가상 프린터에 대한 의존, WPP에서 남지 않는 큐로의 RAW 전송이라는 4곳은 개선 대상이고 그리기만 하는 코드는 검증 대상이 된다
app["업무 앱의 인쇄 코드"]
app --> deps["네 가지 의존을 점검"]
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["검증한다"]
그림 13: 네 가지 의존만 개선 대상이고, 그리기만 하는 코드는 검증으로 돌립니다.
5.1 먼저 현장의 드라이버 목록을 뽑아 인쇄 대상을 판정한다
개선이 필요한지는 현장에 무엇이 들어 있는지를 본 뒤에 정합니다. PowerShell의 PrintManagement 모듈로 큐와 드라이버의 목록을 가져옵니다. Get-Printer와 Get-PrinterDriver로 목록을 뽑는 데는 관리자 권한이 필요 없지만, 뒤쪽의 pnputil에는 관리자 권한이 필요합니다.1617
# 큐별로 드라이버 이름·메이저 버전(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를 구분할 수 있습니다.18 다만 v3/v4의 구분과 기본 포함/서드파티의 구분은 별개입니다. 다음과 같이 분류합니다.
| 분류 | 구분하는 방법 | 이어서 확인할 것 |
|---|---|---|
| IPP 클래스 드라이버의 큐 | DriverName이 Microsoft IPP Class Driver |
Mopria 인증, 네트워크의 IPP 활성화·도달성, USB의 IPP over USB 모드. 이름만으로 WPP 호환이라고 단정하지 않습니다 |
| Universal Print의 큐 | 포함된 Universal Print Class Driver를 사용8 | WPP 호환 쪽으로 다루고, 앱의 큐 이름 의존과 출력을 확인합니다 |
| 그 밖의 기본 포함 드라이버의 큐 | 알려진 클래스 드라이버 이름도 아니고 서드파티 패키지 목록에도 해당하지 않는 것 | XPS·팩스는 삭제 대상입니다. Generic / Text Only 등은 남는다고 전제하지 않습니다. Microsoft Print to PDF는 삭제 대상으로 열거되어 있지 않으므로 큐별로 판정합니다 |
| 제조사 드라이버의 큐 | INF 파일 이름·공급자를 pnputil의 서드파티 패키지 목록과 대조 |
드라이버 교체의 후보입니다. WPP에서는 기존 큐가 사라지므로 물리 기기의 재등록 가능 여부를 확인합니다 |
Get-PrinterDriver의 InfPath는 드라이버 저장소 안 INF의 경로이며, 공개 이름인 oemN.inf를 돌려준다는 보장은 없습니다. pnputil /enum-drivers가 돌려주는 공개 이름·원래 INF 이름·공급자와, InfPath의 파일 이름이나 Manufacturer를 대조합니다. pnputil /enum-drivers는 서드파티 패키지만 나열하며, 기본 포함 패키지는 목록에 나오지 않습니다.1917
flowchart TB
accTitle: 현장의 프린터 목록을 점검하는 절차
accDescr: PowerShell로 큐와 드라이버의 목록을 뽑고 DriverName과 Manufacturer 및 pnputil의 서드파티 패키지 목록과의 대조로 IPP 클래스 드라이버의 큐, Universal Print의 큐(WPP 호환), 그 밖의 기본 포함 드라이버의 큐(XPS·팩스는 삭제, 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의 관리자 권한이 필요합니다.
이 목록과 앱의 설정·인쇄 코드·사용 SDK가 참조하는 큐를 대조합니다. 납품처별로 드라이버, Mopria 인증, 연결 방식, IPP의 도달성, USB의 동작 모드까지 기록해 두면 4장의 표로 판정할 수 있습니다.
WPP에서 인쇄 대상이 남지 않고 다시 등록도 할 수 없는 경우에는, 코드 점검보다 먼저 6장의 다른 경로를 준비하거나 WPP를 쓰지 않는다는 판단을 내립니다. WPP를 쓰지 않아도 IPP의 순위 변경을 겪을 수 있는 기기라면, 이어서 5.2 이후를 확인하십시오. WPP를 쓰지 않고 드라이버 교체의 영향도 없는 경우에는 현재 경로 그대로 운영한다는 판단이 됩니다.
앱 안에서 드라이버 이름을 확인하려면 WPF의 System.Printing에서 PrintQueue.QueueDriver.Name을 읽을 수 있습니다.20
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}");
}
다만 System.Printing 네임스페이스는 Windows 서비스 안에서의 사용을 지원하지 않습니다. 상주 서비스에서 인쇄하고 있다면 이 진단 처리는 관리 도구 쪽에 두십시오.21 서비스에서의 인쇄 제약은 Windows서비스 만드는 법과 운영과 지난 글의 7장을 참조하십시오.
5.2 확인 1: 드라이버 고유 설정을 저장·복원하고 있지 않은가
가장 찾기 어려운 것이 인쇄 설정의 저장입니다. 저장 방법에 따라 망가지는 이유가 다릅니다.
| 저장하고 있는 것 | 전형적인 구현 | 드라이버가 바뀌면 곤란한 이유 |
|---|---|---|
DEVMODE의 비공개 부분 |
DocumentProperties의 결과나 GetHdevmode의 버퍼를 통째로 저장하고 SetHdevmode로 되돌린다 |
비공개 데이터는 그 드라이버만 해석할 수 있습니다 |
.NET Framework의 PrinterSettings 전체 |
인쇄 대화 상자 이후의 객체를 바이너리 직렬화한다 | 내부에 복사된 드라이버의 비공개 영역도 함께 저장될 수 있습니다 |
| 공개 속성의 값 | PaperSize, PaperSource, PrinterResolution, Duplex 등을 자체 형식으로 저장한다 |
비공개 버퍼가 아니라 사용자 지정 용지·용지함 번호 등의 의미가 달라집니다 |
사설 확장을 포함한 PrintTicket |
제조사 고유의 네임스페이스를 포함한 XML을 저장한다 | 고유 확장이 원래 드라이버나 기종에 의존합니다 |
DEVMODE는 공개 멤버 뒤에 dmDriverExtra로 크기를 나타내는 비공개 데이터를 가질 수 있습니다. Windows가 검증하는 것은 공개 부분뿐이며, 손상된 비공개 데이터는 앱이나 스풀러의 프로세스에서 드라이버를 크래시시킬 수 있습니다.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: 통째로 저장한 설정 가운데 망가지는 것은 비공개 부분입니다.
SetHdevmode로 설정을 받은 PrinterSettings는 이 비공개 영역을 내부에 복사합니다.23 .NET Framework판의 PrinterSettings에는 Serializable 특성이 붙어 있고, 바이너리 직렬화는 기본적으로 private 필드도 포함하므로 객체 전체의 저장에도 같은 의존이 숨어 있습니다.2425
한편 .NET판의 PrinterSettings에는 Serializable 특성이 없고, 공개 속성을 개별적으로 자체 형식으로 저장하는 구현에서는 네이티브 DEVMODE 버퍼나 dmDriverExtra 영역까지 저장하지는 않습니다.24 이 경우에 주의할 것은 드라이버에 의존하는 값입니다.
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 이후 객체의 통째 저장은 비공개 부분 쪽에 들어가며, 망가지는 방식은 달라도 둘 다 드라이버의 상태를 지니고 다니는 것입니다.
RawKind가 표준 PaperKind나 PaperSourceKind를 나타내고 있다면 드라이버가 바뀌어도 의미를 유지합니다. 보장이 없는 것은 Custom이나 제조사 고유의 번호가 다른 드라이버에서도 같은 용지·용지함을 가리키는 것입니다. 표준값까지 일괄로 망가지는 것으로 다루지 마십시오.2627
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: 망가지는 것은 표준값이 아니라 제조사 드라이버의 목록에 대한 사용자 지정 값입니다.
PrintTicket도 공개 키워드는 psk 네임스페이스에서 정의되지만, 디바이스 고유의 사설 확장을 포함할 수 있습니다. 서드파티의 요소는 그 서드파티에 명확히 연결된 네임스페이스에 두어야 한다는 규정입니다. 저장 XML에 제조사의 네임스페이스가 섞여 있다면 드라이버 고유 설정으로 보고 확인합니다.2829
대처: 저장하는 것은 「의도」만으로
용지 크기·방향·양면·매수·용지함 선택이라는 의도를 자신의 설정 파일에 공개 키워드로 가집니다. 드라이버의 내부 상태를 넘겨받는 것이 아니라, 인쇄 직전에 현재의 기능과 대조합니다.
WPF에서는 PrintQueue.GetPrintCapabilities로 기능을 가져오고, 요구를 PrintTicket으로 만들어 MergeAndValidatePrintTicket에 넘깁니다.30 여기서 주의해야 할 것은 미지원 요구가 반드시 오류가 되지는 않는다는 점입니다. 드라이버가 충돌을 해결하여, 보통은 기본값 등으로 바꿔 넣은 유효한 티켓을 돌려주는 경우가 있습니다.
ValidationResult.ConflictStatus가 ConflictResolved라면 ValidatedPrintTicket의 양면이나 용지함을 요구와 비교하고, 차이를 로그에 남겨 사용자에게 알립니다.31
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: 설정의 의도를 저장하고 인쇄 시점에 현재의 기능으로 검증합니다. 바뀐 설정은 말없이 쓰지 말고 차이를 확인합니다.
WinForms에서는 PrinterSettings.PaperSizes에서 이름이 아니라 Kind나 치수로 용지를 다시 고릅니다. 급지원의 PaperSources는 Upper나 Lower처럼 고유한 표준값이면 재사용할 수 있지만, 여러 고유 용지함이 한꺼번에 PaperSourceKind.Custom으로 돌아오는 경우가 있습니다. 게다가 PaperSource에는 용지 치수가 없습니다. 고유 용지함을 Kind만으로 특정하지 말고, 현재의 기능에 명시적으로 다시 매핑하거나 사용자가 다시 고르게 하십시오.27
5.3 확인 2: 프린터 이름·큐 이름에 의존하고 있지 않은가
지난 글에서는 프린터 이름을 설정 파일에 두기를 권했습니다. 여기서 더하는 것은 드라이버의 교체나 재검색 뒤에 같은 이름의 큐가 만들어진다는 보장은 없다는 전제입니다. 옛 큐 이름을 가리킨 설정은 그대로는 인쇄 대상을 잃습니다.
확인할 곳은 설정 파일, 코드에 직접 쓴 이름, SDK·장표 라이브러리 내부의 세 가지입니다. 자신의 코드에 고정 이름이 없어도, 제조사 SDK가 내부에서 특정 큐나 드라이버를 호출하는 경우가 있습니다. SDK의 문서와 5.1의 목록을 대조하십시오.
flowchart TB
accTitle: 큐 이름에 대한 의존이 숨어 있는 세 곳
accDescr: 큐 이름에 대한 의존은 설정 파일의 고정 이름, 코드에 직접 쓴 고정 이름, 제조사 SDK나 장표 라이브러리가 내부에서 호출하는 큐·드라이버의 세 곳에 숨어 있으며 앞의 둘은 코드와 설정의 검색으로 뒤의 하나는 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 확인 3: 가상 프린터를 파일 생성에 쓰고 있지 않은가
서드파티 PDF 프린터로 인쇄해 출력 폴더를 감시하는 장표 아카이브나, XPS Document Writer로 중간 파일을 만드는 처리는, 쓰고 있는 큐가 WPP에서 삭제되면 동작하지 않게 됩니다.
다만 삭제되는 것은 WPP에서 지원되지 않는 소프트웨어 프린터입니다. 포트 모니터 DLL 형태 같은 미지원 제품과, OneNote처럼 WPP 지원으로 업데이트된 제품을 혼동하지 마십시오. 7장의 절차 3에서 실제로 쓰는 큐가 삭제 대상인지 확인합니다.2
PDF가 필요하다면 지난 글의 5장에서 설명한 대로 PDF 라이브러리로 직접 생성하는 구성으로 옮기는 것이 인쇄 스택의 변화에 덜 의존하는 설계입니다.
5.5 확인 4: RAW 전송이 WPP에서 사라지는 큐를 지나고 있지 않은가
RAW 전송은 OpenPrinter → StartDocPrinter(데이터 종류 「RAW」) → WritePrinter → EndDocPrinter로 프린터 언어의 데이터를 스풀러를 거쳐 흘려보내는 방식입니다. 문서 쪽이 하드웨어의 언어로 인쇄 설정을 완전히 기술해야 하며 DEVMODE의 설정은 쓰이지 않습니다.3233
라벨·영수증에서는 정석이지만, RAW 전송은 「스풀러를 지나지 않는 직접 통신」이 아닙니다. 드라이버를 사실상 포트로 가는 통로로 쓰고 있더라도, 그 큐가 WPP에서 사라지면 통로를 잃습니다.
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 전송은 드라이버를 통로로만 쓰고 있지만, 통로 자체가 사라집니다.
확인해야 할 것은 어느 큐·드라이버·포트의 조합으로 보내고 있는지입니다. 제조사 드라이버의 큐뿐 아니라 Generic / Text Only 같은 IPP 클래스 드라이버 이외의 물리 프린터용 기본 포함 드라이버도 남는다고 전제할 수 없습니다. 7장의 삭제 목록에서 사라진다고 확인된 것은 마찬가지로 다른 경로가 필요합니다.13
또한 IPP 클래스 드라이버의 큐로 고유 PDL을 RAW로 흘려보낼 수 있다고는 Microsoft Learn에 기술되어 있지 않습니다. 프린터 쪽 IPP 구현이 받아들이는 PDL에 의존하므로, 「IPP로 바꾸면 같은 RAW 데이터가 통한다」라고 판단하지 마십시오.
6. 라벨·영수증 프린터의 우회 경로
라벨·영수증에는 스풀러에 의존하지 않는 출력 경로를 적어도 하나 갖는 것을 코무라소프트는 권합니다.
2장의 서명 예외에 해당하더라도 제조사 드라이버의 계속 제공이나 WPP에서의 사용이 보장되지는 않습니다.1 Microsoft의 문제 해결 문서에도, 2021년의 업데이트 뒤에 USB 연결 영수증·라벨 프린터에서 인쇄가 되지 않다가 Known Issue Rollback으로 해결된 사례가 있습니다.34 출력 경로를 나누어 파악해 두는 것이 대비가 됩니다.
| 경로 | 스풀러 의존 | 적합한 장면·주의점 |
|---|---|---|
| 장치와 직접 TCP/USB/시리얼로 통신하는 제조사 SDK | 하지 않음 | 제조사가 장기간 SDK를 유지보수하는 기종에 적합. SDK의 비트 수, 의존 런타임, 서명의 갱신을 따라갑니다 |
| 내부에서 Windows의 큐·드라이버를 호출하는 제조사 SDK | 함 | 기존 자산으로 남기더라도 내부의 큐가 WPP에서 사라지면 멈춥니다. 스풀러에서 독립된 우회 경로가 되지 못합니다 |
| TCP 소켓으로 프린터 언어를 직접 전송 | 하지 않음 | 네트워크 연결 라벨 프린터에 적합. 연결 끊김·재전송·타임아웃을 설계합니다 |
| 시리얼(가상 COM)/USB로 직접 전송 | 하지 않음 | 영수증 프린터나 계측 장치에 병설하는 기기에 적합. 가상 COM·HID·WinUSB의 선택이 전제가 됩니다 |
| IPP 클래스 드라이버를 거쳐 인쇄(IPP / IPP over USB) | 함. 조건을 만족하면 WPP 호환 | Mopria 인증, 네트워크의 IPP 활성화·도달성, USB의 동작 모드를 확인합니다. 스풀러 밖으로 나가는 경로는 아닙니다 |
TCP의 재접속 설계에는 시리얼 통신 앱의 함정의 사고방식을 쓸 수 있습니다. USB의 방식 선택은 Windows 앱에서 USB 기기를 다루는 방법을 참조하십시오. IPP는 프린터에 따라 기본값으로 꺼져 있는 경우가 있어 활성화가 필요합니다.4
SDK라는 이름만으로는 독립된 경로인지 알 수 없습니다. SDK의 문서와 5.1의 목록으로, 장치에 직접 통신하는지 마지막에는 Windows의 큐를 호출하는지 확인합니다.
Windows의 큐를 쓰는 경우, Universal Print는 WPP 호환 쪽이지만 이것도 스풀러를 지납니다. IPP 클래스 드라이버도 Universal Print도 아닌 큐는, 서드파티 드라이버나 XPS·팩스라면 WPP에서 멈추고, Microsoft Print to PDF처럼 삭제 대상으로 열거되어 있지 않은 기본 포함 큐는 개별로 판정합니다. 「WPP 호환」과 「스풀러 비의존」은 별개의 분류입니다.
flowchart TB
accTitle: 출력 경로가 스풀러에 의존하는지 판정하는 흐름
accDescr: 후보 경로가 Windows의 인쇄 큐로 보내는 경우에는 IPP 클래스 드라이버의 큐이고 프린터가 Mopria 인증을 받았으며 네트워크 연결이면 IPP가 켜져 있고 도달할 수 있고 USB 연결이면 IPP over USB 모드인 것과 Windows Ready Print의 일부인 Universal Print의 큐는 스풀러 의존이라도 WPP 호환이고 Mopria 비인증 기기나 서드파티 드라이버의 큐, XPS Document Writer·팩스처럼 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·팩스)"| 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에서 멈출 수 있습니다.
7. 검증 절차 ── WPP를 쓰는 경우·쓰지 않는 경우
WPP를 쓰는 경우와 쓰지 않는 경우로 검증의 분기를 먼저 확인합니다. 어느 쪽이든 변경 전의 출력을 남기고 실제로 쓰는 인쇄 대상에서 확인합니다.
flowchart TB
accTitle: WPP 사용 여부로 나누는 인쇄 검증 절차
accDescr: 검증용 PC에 모든 큐를 재현해 변경 전의 출력을 저장하고 WPP를 쓰는 경우에는 켜서 삭제된 큐를 기록하고 호환 기기의 재등록 후 출력을 비교하는 한편 비호환 기기의 다른 경로를 확인하며 쓰지 않는 경우에는 물리의 IPP 순위 변경 대상 기기를 끈 채로 재검색해 출력을 비교하고 그 밖은 실제 큐에서 인쇄를 확인한다
prepare["모든 큐를 재현해 기록"]
prepare --> baseline["변경 전의 인쇄 결과를 저장"]
baseline --> use{"WPP를 쓰는가"}
use -->|"쓴다"| enable["켜고 삭제 큐를 기록"]
enable --> compatible["호환 기기는 필요에 따라 재등록"]
compatible --> compare["변경 전과 같은 인쇄로 비교"]
enable --> alternate["비호환 기기는 다른 경로로 확인"]
use -->|"쓰지 않는다"| physical{"물리의 IPP 순위 변경 대상인가"}
physical -->|"예"| redetect["끈 채로 삭제·재검색"]
redetect --> compare
physical -->|"아니오"| existing["실제 큐에서 인쇄 확인"]
compare --> finish["결과를 기록하고 검증용 PC를 복구"]
alternate --> finish
existing --> finish
그림 23: 변경 전의 출력을 공통 기준으로 삼고, WPP를 쓰는 환경에서만 켭니다. 쓰지 않는 환경에서는 IPP의 순위 변경과 실제 큐에서의 인쇄를 확인합니다.
7.1 공통 준비: 운영 환경이 아니라 검증용 PC에서 모든 인쇄 대상을 재현한다
검증에는 Windows 11 24H2 이후의 PC를 쓰고, 운영 PC에서는 하지 않습니다. 네트워크 연결이라면 같은 프린터에 도달할 수 있는 VM에서 검증할 수 있습니다. USB 연결의 재등록이나 직접 통신을 평가하는 경우에는 같은 USB 인터페이스를 패스스루할 수 있는 VM을 제외하고 물리 검증용 PC를 씁니다.
WPP의 사용 여부와 관계없이 다음 절차 1·2로 변경 전의 상태를 남깁니다.
- 현장에서 앱이 쓰는 큐를 모두 재현한다. 제조사 드라이버의 물리 프린터뿐 아니라 서드파티 PDF 가상 프린터나
Generic / Text Only같은 기본 포함 큐도 같은 구성으로 넣습니다. 5.1의 스크립트로 드라이버 이름과 버전을 기록합니다. 삭제 차이로 판정할 수 있는 것은 검증용 PC에 존재하는 큐뿐입니다. - 인쇄 기능을 한 차례 모두 돌려 보고 출력을 저장한다. 용지·용지함·양면·매수의 설정 화면, 장표별 인쇄, PDF 출력, 라벨 인쇄를 확인하고 나중에 비교할 수 있는 기준을 만듭니다.
flowchart TB
accTitle: 검증용 PC에 재현할 큐
accDescr: 5.1의 점검으로 파악한 앱이 쓰는 큐 가운데 제조사 드라이버의 물리 프린터, 서드파티 PDF 등의 가상 프린터, Generic / Text Only 같은 기본 포함 드라이버의 큐를 모두 검증용 PC에 현장과 같은 구성으로 재현하고 절차 3의 삭제 목록으로 판정할 수 있는 것은 검증용 PC에 존재하는 큐뿐임을 나타낸다
inv["5.1의 점검: 앱이 쓰는 큐"]
inv --> phys["물리 프린터(제조사 제품)"]
inv --> virt["가상 프린터(서드파티 PDF 등)"]
inv --> inbox["기본 포함 드라이버(Generic / Text Only 등)"]
phys --> vm["검증용 PC에 같은 구성으로 재현"]
virt --> vm
inbox --> vm
vm --> judge["절차 3의 삭제 목록으로 남는지 판정"]
note["없는 큐는 삭제 차이에 나타나지 않는다"] -.-> judge
그림 24: 검증용 PC에 없는 큐는 삭제 차이에 나타나지 않으므로, 점검으로 파악한 큐를 먼저 모두 재현합니다.
7.2 WPP를 쓰는 환경: 켜고, 사라진 인쇄 대상까지 포함해 검증한다
절차 1·2 뒤에 다음 순서로 진행합니다.
- WPP를 켜고 삭제되는 큐를 기록한다. 설정 앱의 「프린터 및 스캐너」에서 「Windows protected print mode」의 「설정」을 고르면 삭제 대상이 대화 상자에 표시됩니다.2 그룹 정책으로 켜는 경우에는 대화 상자가 나오지 않으므로, 적용 전의
Get-Printer결과를 저장하고 적용 후에 검증용 PC를 다시 시작합니다.IsProtectedPrintEnabled나 설정 화면에서 활성화를 확인한 뒤 다시 목록을 뽑아 차이를 기록합니다.14 - 삭제된 호환 프린터를 다시 설치한다. Windows Ready Print로 다시 넣고, 물리 프린터의
DriverName이 Microsoft IPP Class Driver로 바뀌었는지 5.1의 스크립트로 확인합니다. - 같은 인쇄를 반복해 변경 전과 비교한다. 설정 화면의 선택지, 저장 설정의 복원, 큐 이름 변경에 따른 인쇄 대상의 소실을 확인합니다. 출력의 여백·글꼴·괘선도 절차 2의 출력과 대조합니다.
- 비호환 기기는 6장의 다른 경로로 인쇄한다. 「프린터가 목록에 없다」는 상태를 재현한 뒤 출력할 수 있음을 확인합니다. 고친 코드뿐 아니라 준비한 경로까지 검증 대상입니다.
7.3 WPP를 쓰지 않는 환경: 켜지 않고 드라이버 선택의 변화를 검증한다
WPP를 쓰지 않기로 판단한 환경에서는 절차 3·4를 하지 않습니다. WPP를 켜면 큐째로 삭제되어 순위 지정만의 영향이 보이지 않게 되기 때문입니다.
| 인쇄 대상 | 절차 1·2 뒤에 할 것 |
|---|---|
| 순위 변경의 대상이 되는 물리의 IPP 지원 기기 | WPP를 끈 채로 검증용 PC에서 삭제·재검색·재설치합니다. IPP 클래스 드라이버로 바뀌는지를 5.1의 스크립트로 확인하고 절차 5의 비교를 합니다 |
| 클라우드·가상의 큐 | 재검색할 물리 기기도 순위 변경도 없으므로 실제로 쓰는 큐에서 절차 2의 출력을 확인합니다 |
7.4 검증 후의 복구와 초기 구축 절차 정비
로컬 설정 앱에서 WPP를 켠 검증용 PC는 「끄기」로 되돌릴 수 있습니다. 그룹 정책이나 Intune에서 적용한 경우에는 관리자 쪽의 정책 변경이 필요하므로, 켜는 경로에 맞춰 복구 절차도 준비합니다.213
WPP를 다시 꺼도 Windows Ready Print로 다시 넣은 프린터는 그대로입니다. 비호환이었던 프린터는 수동으로 다시 설치합니다.210
초기 구축에서는 그룹 정책에서 Intune으로에서 정리한 배포 구조에 WPP 정책과 프린터의 재등록 절차를 넣습니다. Point and Print에 의한 서드파티 드라이버 배포는 2021년의 KB5005652 이후 기본적으로 관리자 자격 증명이 필요해졌고,34 WPP에서는 배포 자체가 이루어지지 않습니다.9 WPP를 쓰는 환경에서는 드라이버 배포에 의존한 절차를 이 정책 적용과 재등록 절차로 바꿉니다.
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를 쓰지 않는다는 판단을 먼저 내립니다 |
| 드라이버 고유 설정을 저장하고 있다 | 상태가 아니라 의도를 저장하고 인쇄 직전에 기능을 확인합니다 |
| 큐 이름이나 가상 프린터에 의존하고 있다 | 인쇄 대상의 존재 확인·로그·알림·재선택을 준비합니다. PDF는 라이브러리로 직접 생성합니다 |
| RAW 전송의 통로가 WPP에서 사라진다 | 스풀러에 의존하지 않는 경로를 준비합니다 |
| 인쇄 대상을 확보할 수 있고 그리기만 하며 특정 드라이버에 의존하지 않는다 | 일괄로 다시 쓰지 말고 실제 출력을 검증합니다 |
하나 고쳤다고 끝이 아닙니다. 설정을 고친 뒤에도 큐 이름, 가상 프린터, RAW 전송을 이어서 확인하고, 마지막에 7장에서 출력을 확인합니다. WPP를 쓰지 않아도 IPP의 순위 변경이 있을 수 있는 기기에서는 의존 점검과 WPP를 끈 채로의 재검색 검증이 필요합니다.
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.3)"]
pq -->|"아니오"| outchk["실제 큐에서 출력 확인"]
그림 26: 큐가 WPP에서 남는지를 먼저 판정하고, 코드의 의존은 하나 고쳐도 다음 확인으로 나아가며, 고친 경로도 마지막에는 검증합니다. WPP를 쓰지 않는 경우에는 7장의 WPP 활성화가 아니라, 물리의 IPP 지원 기기는 WPP를 끈 채로의 재검색으로, 클라우드·가상의 큐는 실제 출력으로 확인합니다.
대비의 기한은 Microsoft의 날짜가 아니라 자사의 배포 계획에 둔다
WPP는 미래에 기본값으로 켜진다고 되어 있지만 그 시기는 제시되어 있지 않습니다.10 대비의 기한은 자사에서 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의 분기점 날짜를 마감으로 삼지 않습니다.
우선은 납품처의 목록을 뽑고 설정·인쇄 대상·출력 경로의 의존을 파악하는 일부터입니다. PDF는 직접 생성하고, 라벨·영수증에는 인쇄 스택에서 독립된 경로를 하나 가집니다. 그 위에서 실제 배포 조건에 맞춰 인쇄를 확인합니다.
Windows 10에 머무는 환경은 이 계획의 대상 밖이지만, 일반 채널의 Windows 10(22H2) 지원은 2025년 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 ↩10
-
Microsoft Learn, Overview of Windows protected print mode. 활성화 시 서드파티 드라이버를 쓰는 프린터가 제거되고 드라이버 저장소에서 삭제된다는 점, Mopria 인증을 받았어도 서드파티 드라이버로 도입된 프린터는 재설치가 필요하다는 점, 지원되지 않는 소프트웨어 프린터(OneNote (Desktop) 등)·XPS·팩스가 삭제된다는 점, 그룹 정책으로 켠 경우 사용자가 해제할 수 없다는 점, 설정 앱에서의 활성화·비활성화 절차에 대하여. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
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, Legacy printer driver submission process. 2026년 1월 15일 이후 WHQL·Attestation을 불문하고 프린터 드라이버의 제출이 기본적으로 차단되고 정당성 문서를 첨부한 수동 심사가 되었다는 점에 대하여. ↩
-
Microsoft Learn, Windows Print Path Overview. Windows에 GDI 인쇄 경로와 XPS 인쇄 경로라는 두 가지 주요 인쇄 경로가 존재한다는 점에 대하여. ↩
-
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 ↩3
-
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 ↩5 ↩6
-
Microsoft Learn, Windows protected print mode FAQ. 비호환 프린터는 활성화 중에 재설치할 수 없고 비활성화 후에는 수동으로 다시 넣어야 한다는 점, 고유 기능은 Print Support App으로 제공된다는 점, Windows protected print mode가 미래의 어느 시점에 기본값으로 켜진다는 점에 대하여. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Printer driver isolation. 격리 모드(Shared / Isolated / None)의 의미, INF의
DriverIsolation키워드를 선언하지 않은 드라이버가 기본적으로 스풀러 프로세스 안에서 동작한다는 점, 관리자가 인쇄 관리 콘솔이나 스풀러 함수로 각 드라이버의 설정을 덮어쓸 수 있다는 점에 대하여. ↩ ↩2 -
Microsoft Learn, What’s new in Windows 11, version 24H2. Windows protected print mode가 24H2에서 추가되었고 설정 앱 또는 그룹 정책으로 켤 수 있다는 점에 대하여. ↩
-
Microsoft Learn, Policy CSP - Printers: ConfigureWindowsProtectedPrint. 적용 OS가 Windows 11 24H2 이후라는 점, 기본값은 꺼짐이며 드라이버나 인쇄 기능에 제한이 없다는 점, ADMX의 대응 레지스트리 키
Software\Policies\Microsoft\Windows NT\Printers\WPP와 값WindowsProtectedPrintGroupPolicyState에 대하여. ↩ ↩2 ↩3 ↩4 ↩5 -
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, PnPUtil Command Syntax.
/enum-drivers가 서드파티의 드라이버 패키지를 나열하고 Windows 11 21H2 이후에는/class로 클래스 이름을 좁힐 수 있다는 점, 관리자로 명령 프롬프트를 열어 실행한다는 점에 대하여. ↩ ↩2 -
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, 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, PrinterSettings Class. .NET Framework판의 선언에는
Serializable특성이 붙어 있고 .NET판에는 붙어 있지 않다는 점,GetHdevmode와SetHdevmode가DEVMODE와의 상호 변환이라는 점에 대하여. ↩ ↩2 -
Microsoft Learn, SerializableAttribute Class.
Serializable특성을 붙인 형식에서는 private과 public의 모든 필드가 기본적으로 직렬화되며 제외하려면NonSerialized특성을 붙인다는 점에 대하여. ↩ -
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·satellite assembly·culture 전환의 실무
Windows 데스크톱 앱의 다국어화를 정리합니다. CurrentCulture와 CurrentUICulture의 차이, resx와 satellite assembly의 구조, WPF에서 현실적인 방식 선택, 런타임 언어 전환, 서식·RTL까지 설명...
Windows 앱의 작업 트레이 상주와 토스트 알림 ── NotifyIcon의 함정과 AppNotification 고르는 법
업무용 Windows 앱의 작업 트레이 상주와 토스트 알림 구현을 정리합니다. NotifyIcon의 올바른 사용법, Explorer 재시작 시 재등록, 토스트 API 3종의 선정 판단표, 알림이 도착하지 않는 경우까지 설명합니다.
Windows 앱 외주·수탁 개발을 의뢰하기 전에 정리할 점
Windows 앱 외주·수탁 개발을 의뢰하기 전에, 기존 소프트웨어 수정, 장치 연동, COM/ActiveX, 배포·업데이트, 유지보수를 정리하는 포인트를 설명합니다.
Time Travel Debugging ── 장기 가동에서 재현되지 않는 결함을 「녹화」해서 되감기
한 달에 한 번만 나오는 결함은 크래시 덤프로는 결과밖에 찍히지 않습니다. WinDbg의 Time Travel Debugging(TTD)으로 실행을 녹화해 되감는 방법을 TTD.exe의 녹화 설계, 링 버퍼, TTD.Calls 쿼리, 덤프와의 역...
관련 토픽
이 기사와 가까운 토픽 페이지입니다. 기사를 출발점 삼아 관련 서비스와 다른 기사로 이어집니다.
Windows 기술 토픽
Windows 개발, 장애 조사, 기존 자산 활용에 관한 KomuraSoft LLC 기사를 모은 토픽 허브입니다.
UI 스레드 & 타이머
WPF / WinForms UI 스레드, async 흐름, Dispatcher 사용, 타이머 판단을 정리한 토픽 페이지입니다.
이 주제와 연결되는 서비스
이 기사는 다음 서비스 페이지로 이어집니다. 가까운 입구부터 확인해 주세요.
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 전송을 하고 있는 큐를 대조하여, 이 글의 판단표로 「그대로」「검증」「경로를 바꾼다」로 나눕니다.