WSD 全称:Web Services on Devices(也写作 Web Services for Devices)设备 Web 服务 通过这个 PowerShell 脚本,可以简化网络打印机的安装过程。用户只需输入打印机的 IP 地址,脚本将自动安装并配置网络打印机。此脚本适用于已预先安装打印机驱动的环境,能够确保网络打印机的自动安装与设置。

wsdportmon.dll (WSD 端口监视器) vs ippmon.dll (IPP 端口监视器)
核心结论:wsdportmon.dll(WSD 打印)、ippmon.dll(IPP 打印)是 Windows 打印子系统中两套完全独立的端口监视器,二者都跑在spoolsv.exe,但是协议栈、报文格式、发现机制、DLL、注册表、网络端口全部隔离。Win10/Win11 战略方向:弱化 WSD,强化 IPP Everywhere + Protected Print(受保护打印),把 IPP 作为跨平台默认无驱打印标准。
一、基础定位
wsdportmon.dll(WSD 端口监视器)
- 全称:WSD Port Monitor,用于 DPWS / WSD(Web Services‑for‑Devices)打印
- 宿主进程:
spoolsv.exePrint Spooler - 协议:SOAP‑XML over HTTP;设备发现依靠 WS‑Discovery(UDP 3702 多播)
- 端口:发现 UDP:3702;业务 TCP:5357 (HTTP) / TCP:5358 (HTTPS)
- 配套驱动:WSD 打印配合 v4 打印驱动;无原生通用类驱动,依赖打印机厂商驱动。
- 适用场景:Windows 局域网同子网设备;跨 VLAN 组播失效,WSD 自动发现不可用。
ippmon.dll(IPP 端口监视器)
- 全称:IPP Port Monitor,Internet Printing Protocol
- 宿主进程:
spoolsv.exePrint Spooler - 协议:二进制 TLV 报文封装在 HTTP POST Body;发现依靠 mDNS/Bonjour (UDP5353)
- 端口:业务 TCP:631 (HTTP‑IPP) / TCP:631 (TLS‑IPPS 加密)
- 配套驱动:
ippclass.dllMicrosoft IPP Class Driver(IPP Everywhere 通用无驱驱动),不需要厂商驱动。 - Win11 新增:Protected Print(受保护打印模式),强制仅允许 IPP 类驱动,拦截老旧 v3 驱动、RAW、LPR、WSD 打印路径,提升打印子系统安全。
二、底层原理拆解
2.1 wsdportmon.dll(WSD)完整协议栈
应用层 → GDI/XPS假脱机
↓
厂商v4打印驱动
↓
wsdportmon.dll 【WSD端口监视器】
├─调用 wsdapi.dll / wsdapi.dll 完成DPWS SOAP报文封装解析
├─WS‑Discovery:UDP3702多播 Probe/ProbeMatches 设备发现
├─HTTP SOAP‑XML交互:GetPrinter、PrintJob、Subscribe事件订阅
└─调用winhttp.dll做HTTP传输
↓
winhttp.dll → schannel.dll → ws2_32.dll
↓
TCP 5357 /5358;UDP3702
↓
WSD打印机设备
WSD 特点:
- 控制报文与打印作业全部是SOAP‑XML文本;
- 具备事件订阅:打印机状态变化主动推送回 Windows;
- 强依赖子网多播,跨 VLAN 三层网络自动发现失效,虽然可以手动填写 WSD HTTP URL,但实际生产兼容性差;
- 没有系统通用无驱,大多需要厂商驱动。
2.2 ippmon.dll(IPP)完整协议栈
应用层 → GDI/XPS假脱机
↓
ippclass.dll(IPP Class Driver,IPP Everywhere无驱)
↓
ippmon.dll 【IPP端口监视器】
├─IPP TLV二进制编解码(RFC‑IPP标准)
├─HTTP POST封装IPP二进制载荷
├─Get‑Printer‑Attributes、Print‑Job、Cancel‑Job
└─winhttp.dll + schannel完成IPPS TLS加密
↓
winhttp.dll → schannel.dll → ws2_32.dll
↓
TCP 631 / TCP631(TLS)
↓
IPP打印机 / CUPS服务端
IPP 特点:
- 报文是二进制 TLV,不是 XML;HTTP 只是承载通道;
- mDNS 仅做设备发现;打印通信本身完全不依赖多播;跨 VLAN 手动填写
ipps://ip/ipp/print即可正常打印;ippclass.dll通用类驱动,Windows 自带,不需要厂商提供驱动;macOS/Linux CUPS 原生支持。
2.3 Protected Print(Win11 受保护打印模式)底层原理
组策略 / 注册表开启受保护打印:HKLM\Software\Policies\Microsoft\Windows NT\Printers\ProtectedPrint = 1
- Spooler 打印路由器做路径拦截;
- 只放行:
ippmon.dll + Microsoft IPP Class Driver路径; - 拒绝 wsdportmon.dll (WSD)、raw tcp9100、LPR、第三方 v3 驱动;
- 目标:消除老旧 v3 打印驱动大量提权漏洞;打印作业强制 IPPS 加密传输。
开启 Protected Print 之后,WSD 打印机直接失效。
三、依赖文件
wsdportmon.dll(WSD)
| 文件 | 路径 | 作用 |
|---|---|---|
| wsdportmon.dll | C:\Windows\System32\wsdportmon.dll |
WSD 端口监视器主体,spoolsv 加载 |
| wsdportmon.inf | C:\Windows\INF\wsdportmon.inf |
端口监视器注册 inf |
| wsdapi.dll | C:\Windows\System32\wsdapi.dll |
DPWS SOAP 报文、WS‑Discovery 逻辑库 |
| wpdci.dll | System32 | WSD 设备交互辅助库 |
| winhttp.dll | System32 | HTTP 传输 |
HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\WSD Port Monitor
Driver = wsdportmon.dllHKLM\SYSTEM\CurrentControlSet\Control\Print\Ports\WSD‑xxxxxxxxippmon.dll(IPP)
| 文件 | 路径 | 作用 |
|---|---|---|
| ippmon.dll | C:\Windows\System32\ippmon.dll |
IPP 端口监视器主体 |
| ippmon.inf | C:\Windows\INF\ippmon.inf |
IPP 监视器注册 inf |
| ippclass.dll | spool\drivers | IPP Everywhere 通用无驱驱动 |
| winhttp.dll、schannel.dll | System32 | HTTP/TLS 加密 |
HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\IPP Port Monitor
Driver = ippmon.dllHKLM\SYSTEM\CurrentControlSet\Control\Print\Ports\ipp://xxx公共宿主依赖
spoolsv.exePrint Spooler 服务,两个监视器全部在此进程内加载;spooler 停止,WSD、IPP 全部失效。spoolss.dll:打印路由器,负责调度各个端口监视器。
四、依赖关系
wsdportmon.dll 依赖链
wsdportmon.dll
├─宿主:spoolsv.exe(Spooler服务)
├─内部依赖DLL
│ ├─wsdapi.dll(DPWS/SOAP/WS‑Discovery核心)
│ ├─winhttp.dll(HTTP)
│ └─ws2_32.dll socket
├─注册表依赖:WSD Port Monitor注册表项
├─网络依赖
│ ├─UDP3702多播(WS‑Discovery发现)
│ └─TCP5357/5358 WSD业务通信
└─限制:跨VLAN三层,UDP多播无法转发,自动发现失效;Protected Print开启后被拦截
ippmon.dll 依赖链
ippmon.dll
├─宿主:spoolsv.exe(Spooler服务)
├─内部依赖DLL
│ ├─ippclass.dll(上层IPP通用驱动)
│ ├─winhttp.dll HTTP
│ ├─schannel.dll TLS(IPPS加密)
│ └─ws2_32.dll socket
├─Windows可选组件:Printing‑Internet‑Print‑Client
├─注册表依赖:IPP Port Monitor注册表项
├─网络依赖
│ ├─TCP631(IPP/IPPS)
│ └─mDNS UDP5353仅用于发现;打印本身不依赖多播
└─适配:Protected Print受保护打印模式唯一放行端口监视器
关键区分:
- WSD:发现和业务两套网络,发现强依赖 UDP 多播;
- IPP:mDNS 只是发现;打印业务完全 TCP 单播,跨 VLAN 可用。
五、完整逻辑链路
链路 1:WSD 打印机完整流程(wsdportmon.dll)
- fdPHost + wsdapi.dll 通过 UDP3702 WS‑Discovery 多播探测局域网 WSD 打印机。
- Windows 发现 WSD 设备,生成 WSD 端口记录,注册表写入 WSD‑xxxx 端口。
- spoolsv 加载
wsdportmon.dll端口监视器。 - wsdportmon.dll 调用 wsdapi.dll 发起 HTTP SOAP‑XML 请求获取设备元数据、能力。
- 绑定厂商 v4 打印驱动。
- 打印作业:假脱机文档封装为 SOAP PrintJob XML,HTTP POST 到打印机 TCP5357。
- DPWS 订阅事件:打印机状态变更主动推送回 Windows。
- 开启 Protected Print 时,spooler 直接拒绝该端口监视器,打印失败。
链路 2:IPP 打印机完整流程(ippmon.dll)
- mDNS/Bonjour 发现局域网
_ipp._tcp.local打印机;仅发现阶段。 - 用户添加打印机,spoolsv 加载
ippmon.dll。 - ippmon.dll 发送 HTTP POST
Get‑Printer‑Attributes获取打印机能力。 - 绑定系统自带
Microsoft IPP Class Driver(ippclass.dll),无需厂商驱动。 - 打印作业:假脱机文档封装 IPP TLV 二进制报文,HTTP POST TCP631;IPPS 场景经过 schannel TLS 加密。
- ippmon 周期性轮询打印机状态。
- 开启 Protected Print,该路径正常放行。
六、配套链:运维、故障、组策略、选型对比
关键 PowerShell 运维片段
# 查看两套端口监视器注册状态
Get‑ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Print\Monitors\*Port Monitor"
# IPP端口创建
Add‑PrinterPort ‑Name "ipp://192.168.1.10/ipp/print" ‑PortType IPP
# WSD端口(一般自动生成,极少手动创建)
Get‑Item "HKLM:\SYSTEM\CurrentControlSet\Control\Print\Ports\WSD*"
# 查看受保护打印模式配置
Get‑ItemProperty "HKLM:\Software\Policies\Microsoft\Windows NT\Printers"‑Name ProtectedPrint ‑ErrorAction SilentlyContinue
故障链条
-
WSD 故障
- 同子网搜不到 WSD 打印机:检查 fdPHost 服务、防火墙 UDP3702;交换机 IGMP‑Snooping;
- 跨 VLAN 环境:WSD 自动发现不可用;就算手动填 WSD URL,兼容性参差不齐;
- 开启 Protected Print:WSD 打印直接失效。
-
IPP 故障
- 找不到 IPP Port Monitor:缺少
Printing‑Internet‑Print‑Client可选 Windows 功能; - mDNS 看不到设备,但手动填写 ipp:// 可以打印:属于 mDNS 发现故障,ippmon 本身正常;
- IPPS 打印失败:打印机证书不信任,TLS 握手失败。
- 找不到 IPP Port Monitor:缺少
组策略控制点
计算机配置‑打印机‑关闭WSD打印:注销wsdportmon.dllWSD 端口监视器。计算机配置‑打印机‑关闭Internet打印客户端:注销ippmon.dllIPP 端口监视器。计算机配置‑打印机‑启用受保护打印:Protected Print,仅允许 IPP Everywhere 路径,禁用 WSD、RAW、LPR、老旧 v3 驱动。
wsdportmon.dll vs ippmon.dll 横向对比表
| 项目 | WSD(wsdportmon.dll) | IPP(ippmon.dll) |
|---|---|---|
| 报文格式 | SOAP‑XML | IPP 二进制 TLV 封装 HTTP |
| 设备发现 | WS‑Discovery UDP3702 多播 | mDNS UDP5353 多播(仅发现) |
| 业务端口 | TCP5357/5358 | TCP631(IPP/IPPS) |
| 通用无驱 | ❌需要厂商驱动 | ✅ippclass.dll系统自带 IPP Everywhere |
| 跨 VLAN 可用性 | ❌自动发现失效;手动 URL 兼容性差 | ✅手动填写 ipp URI 完全可用 |
| 跨操作系统 | 仅 Windows 完整支持 | Windows/macOS/Linux CUPS 全平台 |
| Protected Print 受保护打印 | ❌被拦截拒绝 | ✅唯一放行路径 |
| 事件推送 | DPWS 主动订阅推送状态 | 轮询获取打印机状态 |
| Win11 战略定位 | 逐步弱化、兼容存量 | 主推,企业异构环境首选 |
生产最佳实践
- 新建网络环境优先部署 IPP Everywhere / IPPS 加密,放弃 WSD;
- 已有存量 WSD 打印机,尽量切换到 IPP 模式;
- 高安全域开启 Protected Print 受保护打印,强制 IPP 路径,消除老旧打印驱动攻击面;
- 跨 VLAN 办公网络:不要依赖任何多播发现,手动填写
ipps://ip/ipp/print部署打印机。
WSD
相关容易混淆名词
- DPWS:
Devices Profile for Web Services,Web 服务设备配置文件(OASIS 公开标准,WSD 就是 Windows 对 DPWS 的微软实现)Microsoft ... - WSDAPI:Windows 系统 API,
Web Services on Devices API,实现 WSD 的系统组件,对应二进制wsdapi.dll - WS‑Discovery:底层发现子协议,端口 UDP/TCP 3702,负责局域网多播设备发现,属于 DPWS 的一部分
- Windows 配套服务:
fdPHost、FDResPub(Function Discovery,功能发现,上层调用 WSDAPI)
用途:Windows Vista/7/10/11 用于局域网自动发现网络打印机、扫描仪,实现网络即插即用;WSDMON 是 WSD 打印机监视器驱动组件。端口:WS‑Discovery 3702;WSDAPI 本地监听 UDP 5357、5358。
WSD(Web Services on Devices)拆解|解构|底层原理|依赖文件|依赖关系|逻辑链路|配套链
基础定位WSD = Web Services on Devices,微软对 OASIS 标准 DPWS(Devices Profile for Web Services,设备 Web 服务配置文件) 的 Windows 原生实现。主要用于局域网零配置自动发现网络打印机、扫描仪;实现设备即插即用、双向状态上报、打印任务提交。区分:
- DPWS:OASIS 公开跨平台标准规范
- WSD/WSDAPI:微软 Windows 的 DPWS 软件实现
- WS‑Discovery:DPWS 下属子协议,负责设备发现(UDP 3702 多播)
一、底层原理
1、协议栈分层(OSI)
应用层:WSDAPI + WSDMON端口监视器 + PrintSchema打印XML架构
表示层:SOAP‑XML、WSDL设备描述、WS‑Addressing寻址
会话层:WS‑Discovery发现、WS‑Eventing事件订阅
传输层:
发现阶段:UDP 3702 多播(239.255.255.250)
业务通信:TCP 5357(HTTP明文) / TCP 5358(HTTP‑TLS加密)
网络层:IPv4/IPv6局域网多播
- 发现阶段(WS‑Discovery)
设备上电发送
Hello多播报文宣告上线;Windows 客户端发送Probe多播探测报文;匹配设备单播返回ProbeMatches,携带设备 UUID、访问 URL(XAddrs)。
多播报文只能在同一 VLAN / 子网传播;跨 VLAN 默认无法发现,需要组播代理。
-
元数据获取阶段拿到设备 HTTP 地址后,客户端 HTTP 请求获取设备 WSDL 元数据 XML;获取打印机能力:纸张、分辨率、墨水状态、扫描服务。
-
业务交互阶段SOAP over HTTP 提交打印任务、订阅设备事件(缺纸、卡纸、墨量变化);WSDMON 端口监视器负责对接 Windows 打印后台 spooler,把打印作业封装为 WSD SOAP 消息发给打印机,接收设备状态事件回写到打印子系统Microsoft ...。
关键特点:全部消息为 XML‑SOAP 文本,相比 RAW 9100 流量开销更大;支持双向 BIDI 状态回传,不需要 SNMP 也能拿到打印机状态。
2、Windows 内部软件架构
GUI:设备和打印机(control.exe /name Microsoft.DevicesAndPrinters)
↓
Function Discovery(fdPHost / FDResPub)功能发现服务
↓
wsdapi.dll(WSDAPI核心COM组件,DPWS协议栈实现)
├─http.sys内核HTTP服务器(监听5357/5358端口)
└─UDP socket监听3702多播
↓
WSDMON(WSD Port Monitor,打印机端口监视器 wsdportmon.dll)
↓
spoolsv.exe打印后台服务 → 硬件WSD打印机
fdPHost:Function Discovery Provider Host,客户端角色,本机发现外部 WSD 设备(打印机、扫描仪)。FDResPub:Function Discovery Resource Publication,服务端角色,把本机设备(共享打印机)对外广播宣告给局域网其他主机。wsdapi.dll:实现完整 DPWS/WS‑Discovery 协议,封装 SOAP 报文、多播收发、元数据解析、事件订阅。wsdportmon.dll(WSDMON):打印子系统专用端口监视器,桥接 spooler 打印后台与 WSDAPI 协议栈,只用于打印场景Microsoft ...。http.sys内核 HTTP 驱动,承载 WSD 的 TCP 5357/5358 HTTP 端点,不需要启动 IIS。
二、依赖文件
核心二进制文件
wsdapi.dllC:\Windows\System32\wsdapi.dll,WSDAPI 主 COM 组件,DPWS 协议栈实现,所有 WSD 功能的核心库。wsdportmon.dllC:\Windows\System32\spool\monitors\wsdportmon.dll,WSDMON 打印端口监视器,spooler 加载,专门处理 WSD 打印端口。fdwcnex.dll:Function Discovery WSD 连接器,fdPHost 服务加载,桥接功能发现与 WSDAPI。http.sys:内核 HTTP 驱动,TCP5357/5358 监听载体。- 驱动 / INF:
wsdportmon.infWSD 端口监视器注册信息。
系统服务可执行文件
fdPHost.exe(Function Discovery Provider Host):客户端发现外部 WSD 设备FDResPub.exe(Function Discovery Resource Publication):发布本机设备到局域网spoolsv.exe:打印后台,WSDMON 由 spoolsv 加载。
注册表依赖
- WSD 端口监视器注册
HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\WSD Port Monitor
注册表损坏会导致 WSD 打印端口消失,无法添加 WSD 打印机。
- 功能发现配置:
HKLM\SYSTEM\CurrentControlSet\Services\fdPHost、HKLM\SYSTEM\CurrentControlSet\Services\FDResPub - WSDAPI 配置项:
HKLM\SOFTWARE\Microsoft\WSDAPI
端口清单
| 端口 | 协议 | 用途 |
|---|---|---|
| UDP 3702 | WS‑Discovery | 多播设备发现(Hello / Probe),多播地址239.255.255.250 |
| TCP 5357 | HTTP | WSD 明文业务通信(SOAP / 元数据) |
| TCP 5358 | HTTP‑TLS | WSD 加密业务通信 |
三、依赖关系
WSD完整工作链路依赖
├─必须系统服务
│ ├─fdPHost(客户端发现外部WSD设备,手动/延迟启动)
│ ├─FDResPub(发布本机设备,默认手动;网络发现开启才运行)
│ └─Spooler打印后台(使用WSD打印时必须)
├─核心二进制依赖
│ ├─wsdapi.dll(COM,DPWS协议栈)
│ ├─fdwcnex.dll(FD ↔ WSDAPI桥接)
│ ├─wsdportmon.dll(WSDMON打印端口监视器,spoolsv加载)
│ └─http.sys(内核HTTP,5357/5358监听)
├─网络依赖
│ ├─UDP多播,IGMP组播;跨VLAN不原生支持
│ └─防火墙放行UDP3702、TCP5357、TCP5358(专用网络配置文件)
└─可选依赖
└─SSDP(UPnP,和WSD两套独立发现机制,互不强制依赖)
重要:
- fdPHost 停止:Windows 无法发现局域网 WSD 打印机;已经安装好的 WSD 打印机仍然可以打印(不需要发现,直接 TCP 通信)。
- FDResPub 停止:其他电脑发现不到本机共享的 WSD 设备,不影响本机去发现外部打印机。
- 禁用 UDP3702:设备发现失效,但是已知 WSD 设备(已经安装)打印不受影响。
四、完整逻辑链路
链路 A:Windows 发现局域网 WSD 打印机完整流程
- 本机
fdPHost.exe启动,加载fdwcnex.dll调用wsdapi.dll。 - wsdapi.dll 通过 UDP 3702 向多播地址
239.255.255.250发送Probe探测报文(SOAP‑XML),查询wprt:PrintDevice打印设备类型。 - 局域网内支持 WSD 的打印机收到多播报文,单播回复
ProbeMatches报文,返回设备 UUID、HTTP 访问 URL (XAddrs)。 - WSDAPI 拿到设备 URL,发起 TCP 5357 HTTP 请求,获取设备 WSDL 元数据 XML,解析打印机能力、服务端点。
- Function Discovery 向上层(设备和打印机控制面板)上报发现到的设备实例。
- 用户点击添加设备:系统注册 WSD 端口,spoolsv 加载
wsdportmon.dll,创建 WSD 打印机端口。 - WSDMON 订阅 WS‑Eventing 事件,持续接收打印机缺纸、墨量状态上报。
链路 B:WSD 打印作业发送流程
- 应用程序发起打印,spoolsv 生成打印作业文件。
- spoolsv 调用 WSDMON(wsdportmon.dll)端口监视器。
- WSDMON 调用 wsdapi.dll,把打印数据封装为 WSD SOAP 消息,HTTP POST 发送到打印机 TCP5357 端点。
- 打印机接收任务执行打印;通过 WS‑Eventing 事件回传状态。
- WSDMON 把设备状态回写给 Windows 打印子系统,设备管理器 / 打印机面板显示状态。
链路 C:本机对外发布 WSD 设备(FDResPub)
- FDResPub 服务启动,调用 wsdapi.dll。
- http.sys 监听 TCP5357/5358。
- 本机共享打印机通过 WS‑Discovery,UDP3702 向外广播 Hello 报文,宣告本机设备存在,局域网其他 Windows 主机可以发现本机设备。
五、配套链(运维、故障链、等效方案、组策略)
1、运维命令
#查看WSD相关服务状态
Get‑Service fdPHost,FDResPub,Spooler
#启动服务
net start fdphost
net start fdrespub
#重新注册WSDAPI COM(故障修复)
regsvr32 wsdapi.dll
#查看WSD打印端口监视器注册表
Get‑ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Print\Monitors\WSD Port Monitor"
2、故障链条
-
现象:找不到 WSD 打印机
- 根因 1:fdPHost 未启动;
- 根因 2:防火墙拦截 UDP3702 多播;
- 根因 3:交换机 IGMP‑Snooping 阻断组播;跨 VLAN 无法多播发现;
- 根因 4:打印机固件 WSD 功能关闭。
注意:发现失败不等于不能打印;可以手动填入打印机 HTTP 地址手动添加 WSD 端口。 -
现象:可以发现打印机,提交打印任务失败
- TCP5357 被防火墙拦截;wsdportmon.dll 损坏;spooler 异常。
-
现象:WSD 端口监视器消失,添加端口看不到 WSD Port Monitor
HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\WSD Port Monitor注册表丢失;需要重新注册 wsdportmon.inf。
经典坑:WSD 依赖局域网多播,VPN、跨 VLAN 环境无法自动发现 WSD 设备,只能手动指定设备 URL 添加。
3、组策略控制点
计算机配置‑管理模板‑网络‑功能发现:关闭 WSD 发现;关闭功能发现资源发布。
启用该策略后 fdPHost/FDResPub 功能被抑制,WSD 设备发现失效。
4、替代方案对比
| 方案 | 发现机制 | 端口 | 适用场景 |
|---|---|---|---|
| WSD(DPWS) | WS‑Discovery UDP3702 多播 | UDP3702,TCP5357/5358 | Windows 原生,自动发现打印机扫描仪,双向 BIDI 状态 |
| Bonjour/mDNS | mDNS UDP5353 | UDP5353 | 跨平台(macOS/iOS)AirPrint |
| Standard TCP/IP Port(TCPMON) | 手动填写 IP | RAW 9100 /IPP631 | 企业稳定首选,不依赖多播,跨 VLAN 可用 |
5、安全风险配套
- 历史漏洞:MS09‑063 WSDAPI 远程代码执行漏洞(Vista/Server2008)。
- 风险:UDP3702 多播不受子网隔离容易被伪造设备欺骗;公网环境绝对不能开放 5357/5358 端口,仅允许局域网专用网络配置文件放行。
6、演进备注
IPP(Internet Printing Protocol)打印机监视器组件拆解|解构|底层原理|依赖文件|依赖关系|逻辑链路|配套链
基础定位IPP:Internet Printing Protocol,互联网打印协议,PWG 开放标准,基于 HTTP/HTTPS,TCP 631 端口。Windows 中 IPP 端口监视器:ippmon.dll,属于 Print Spooler 打印子系统的端口监视器 (Port Monitor),宿主进程:spoolsv.exe(SYSTEM 权限)。区分易混淆组件:
ippmon.dll:IPP 端口监视器,负责网络传输、IPP‑TLV 报文、HTTP/IPPS 会话(端口监视器层)ippclass.dll:Microsoft IPP Class Driver,IPP 无驱类驱动,负责 PrintTicket 与 IPP 属性转换(驱动层)ippromon.dll:Standard TCP/IP RAW9100 端口监视器,老式 TCP 打印,不是 IPP- WSD:wsdportmon.dll,DPWS/SOAP 打印;IPP 基于 HTTP,两套完全独立端口监视器。
Windows 版本边界:Win8/Server2012 开始原生内置 ippmon.dll;需要可选组件「Internet 打印客户端」;Win11 强化 IPP Everywhere、Protected Print 受保护打印模式,主推 IPP 替代 RAW、SMB 共享打印。
一、底层原理
协议栈分层
上层应用:Word/浏览器 → GDI/XPS → PrintTicket
↓
打印驱动层:ippclass.dll(IPP Class Driver)
↓
端口监视器:ippmon.dll 【本组件】
├─ IPP TLV二进制报文编解码(RFC‑IPP)
└─ HTTP/IPPS(HTTPS)会话封装
↓
winhttp.dll → schannel.dll(TLS) → ws2_32.dll socket
↓
网络层 TCP 631(ipp://) / TCP631 TLS(ipps://加密)
↓
打印机/CUPS服务端
ippmon.dll 核心职责(端口监视器标准接口)
InitializePrintMonitor2,spoolsv 加载调用Microsoft ...- 端口管理:创建、删除、配置 IPP 端口,保存 URI
ipp://x.x.x.x/ipp/print/ipps:// - 能力查询:HTTP POST 发送
Get‑Printer‑Attributes,获取打印机能力(纸张、双面、色彩、介质) - 打印作业提交:
Print‑JobIPP 操作,把假脱机文档封装进 HTTP POST body 下发打印机 - 状态轮询:轮询打印机状态(缺纸、卡纸、墨粉、作业状态)回写给 spooler
- IPPS 加密:调用 winhttp+schannel 完成 TLS 加密通信;支持 Basic/Digest 认证
- mDNS 解析:解析
printer.localBonjour/mDNS 设备域名,解析为 IP 地址。
IPP 报文格式:TLV Type‑Length‑Value 二进制,嵌入 HTTP POST 请求 Body;HTTP 头承载会话,Body 是 IPP 二进制,不是 XML。核心操作:Print‑Job、Get‑Printer‑Attributes、Cancel‑Job。
与 WSD 关键差异
| 项目 | IPP(ippmon.dll) | WSD(wsdportmon.dll) |
|---|---|---|
| 底层载体 | HTTP,二进制 TLV 报文 | SOAP‑XML over HTTP |
| 端口 | TCP631(IPPS TLS‑631) | TCP5357/5358;UDP3702 发现 |
| 发现方式 | mDNS/Bonjour(_ipp._tcp.local) | WS‑Discovery UDP3702 多播 |
| 跨平台 | Windows/macOS/Linux CUPS 全平台 | 仅 Windows 原生完整栈 |
| 驱动 | IPP Everywhere 无驱 | 需要 Windows WSDMON |
二、依赖文件
核心二进制
ippmon.dllC:\Windows\System32\ippmon.dll;SysWOW64 32 位兼容版本;KnownDLL 保护,防止 DLL 劫持。ippmon.inf:端口监视器注册 inf,路径:C:\Windows\INF\ippmon.infippclass.dll:IPP 类驱动,C:\Windows\System32\spool\drivers,PrintTicket‑IPP 属性映射。
传输依赖
winhttp.dll:HTTP/HTTPS 会话,IPPS 加密传输核心schannel.dll/secur32.dll:TLS 握手、证书校验ws2_32.dll:Windows socket TCP 通信dnscache.dll:DNS/mDNS 域名解析
打印子系统宿主依赖
spoolsv.exePrint Spooler 服务,加载 ippmon.dll 宿主进程spoolss.dll:打印路由器,spooler 内部路由winspool.drv:客户端 Win32 打印 API,应用层到 spoolsv RPC 桥梁printui.dll:rundll32 打印 UI 配置,命令行添加 IPP 打印机底层调用库。
注册表依赖
- 端口监视器注册位置
HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\IPP Port Monitor
键值Driver = ippmon.dll;该注册表丢失,IPP 端口监视器消失,无法创建 ipp:// 端口。
- IPP 打印机端口实例:
HKLM\SYSTEM\CurrentControlSet\Control\Print\Ports\ipp://192.168.1.100/ipp/print,保存 URI、超时、认证参数。 - 可选 Windows 功能:
Printing‑Internet‑Print‑Client(Internet 打印客户端),缺失则 ippmon 不注册。
网络端口
| 端口 | 协议 | 说明 |
|---|---|---|
| TCP 631 | HTTP | ipp:// 明文 IPP 通信 |
| TCP 631 | TLS | ipps:// 加密 IPPS 通信 |
| UDP 5353 | mDNS | Bonjour 设备发现(非 ippmon,系统 mDNS 组件) |
三、依赖关系
ippmon.dll 完整依赖链
├─强制系统服务
│ └─Spooler(Print Spooler):spoolsv.exe加载ippmon.dll,服务停止IPP打印完全失效
├─二进制模块依赖(spoolsv进程内加载)
│ ├─spoolss.dll(打印路由器)
│ ├─winhttp.dll(HTTP会话)
│ ├─schannel.dll(TLS加密IPPS)
│ └─ws2_32.dll(TCP套接字)
├─上层驱动配合
│ └─ippclass.dll(Microsoft IPP Class Driver),IPP无驱打印机必须配对
├─Windows可选功能依赖
│ └─Printing‑Internet‑Print‑Client(Internet打印客户端),未安装则监视器不注册
├─网络依赖
│ ├─TCP 631出站;IPPS需要TLS证书校验
│ ├─DNS/mDNS解析(printer.local)
│ └─不需要多播IGMP;IPP打印本身**不依赖组播发现**(发现是mDNS职责)
└─不依赖
└─不依赖UDP3702 WS‑Discovery;和WSD(wsdportmon.dll)完全独立两套监视器
关键运维要点:
- mDNS/Bonjour 只是设备发现;IPP 打印通信本身不需要多播;跨 VLAN 无法 mDNS 发现,但手动填写 IPP URI 仍然可以打印。
- ippmon.dll 只做传输层;不做文档渲染转换;文档转换交给 ippclass.dll/v4 打印过滤管线。
四、完整逻辑链路
链路 A:创建 IPP 打印机端口(PowerShell / 设置添加打印机)
- 用户 / PowerShell
Add‑PrinterPort,调用winspool.drvWin32 打印 API。 - RPC 到
spoolsv.exe打印后台服务。 - spoolss 打印路由器读取注册表
HKLM\..\Print\Monitors\IPP Port Monitor,加载ippmon.dll。 - ippmon.dll 执行端口创建逻辑,校验 IPP URI 格式
ipp://xxx/ipp/print。 - ippmon.dll 发起 HTTP POST
Get‑Printer‑Attributes到打印机 TCP631,获取打印机能力。 - 端口配置写入注册表
HKLM\...\Print\Ports\。 - 绑定
Microsoft IPP Class Driver(ippclass.dll)驱动,完成打印机队列创建。
链路 B:IPP 打印作业完整数据流
- 应用程序打印,GDI/XPS 输出,spoolsv 生成假脱机文档。
- spoolsv 调用对应端口监视器
ippmon.dll。 - ippmon.dll 组装 IPP
Print‑JobTLV 二进制报文,封装 HTTP POST 请求。 - 如果是
ipps://,winhttp+schannel 完成 TLS 握手、证书校验。 - TCP631 发送 HTTP 请求至打印机 IPP 端点。
- 打印机返回 IPP 响应报文;ippmon.dll 解析响应状态码,回传给 spooler。
- ippmon 周期性
Get‑Printer‑Attributes轮询打印机状态;spooler 更新打印机面板状态(缺纸 / 墨低)。 - 作业完成 / 异常,spoolsv 更新打印队列状态。
链路 C:IPPS 加密打印流程
- URI 以
ipps://开头;ippmon.dll 通知 winhttp 启用 TLS。 - schannel 执行 TLS 握手,校验打印机证书(可配置忽略证书校验)。
- IPP TLV 报文在 TLS 隧道内传输。
五、配套链(运维命令、故障链条、组策略、对比选型)
1、PowerShell 运维命令
#查看IPP端口监视器注册表
Get‑ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Print\Monitors\IPP Port Monitor"
#查看已存在IPP端口
Get‑Item "HKLM:\SYSTEM\CurrentControlSet\Control\Print\Ports\ipp*"
#添加IPP打印端口
Add‑PrinterPort ‑Name "ipp://192.168.1.50/ipp/print" ‑PortType IPP
#添加IPP打印机(使用Microsoft IPP Class Driver)
Add‑Printer ‑Name "IPP‑Printer" ‑PortName "ipp://192.168.1.50/ipp/print" ‑DriverName "Microsoft IPP Class Driver"
#查看spooler服务
Get‑Service Spooler
#安装Internet打印客户端可选功能
Install‑WindowsCapability ‑Online ‑Name Printing‑Internet‑Print‑Client~~~~0.0.1.0
2、故障链条
- 现象:找不到 IPP Port Monitor,无法创建 ipp:// 端口
- 根因:未安装
Printing‑Internet‑Print‑Client可选组件;注册表IPP Port Monitor丢失;ippmon.dll 损坏。
- 根因:未安装
- 现象:可以创建端口,打印报错,无法下发作业
- TCP631 防火墙拦截;打印机 IPP 服务未开启;URI 路径错误;IPPS 证书校验失败。
- 现象:mDNS 看不到 IPP 打印机,但是手动填写 ipp URI 可以打印
- 问题属于mDNS/Bonjour 发现层故障,不是 ippmon.dll 本身故障;IPP 打印通信正常。
- 现象:打印机状态不更新
- ippmon 轮询被超时限制;打印机拒绝
Get‑Printer‑Attributes请求。
- ippmon 轮询被超时限制;打印机拒绝
3、组策略控制点
- 计算机配置‑管理模板‑打印机:关闭 Internet 打印客户端,禁用 ippmon IPP 端口监视器。
- Windows 受保护打印模式 WPP:强制只允许 IPP 类驱动打印,禁用 v3/v4 第三方打印驱动kaas.hpclo...。
4、端口监视器横向选型对比
| 监视器 DLL | 协议 | 端口 | 发现方式 | 跨平台 | 生产适用性 |
|---|---|---|---|---|---|
| ippmon.dll | IPP/IPPS | TCP631 | mDNS(Bonjour) | ✅Windows/macOS/Linux | ⭐⭐⭐⭐⭐企业首选无驱打印 |
| wsdportmon.dll | WSD(DPWS) | 5357/5358 | UDP3702 WS‑Discovery | ❌仅 Windows 完整栈 | 局域网 Windows 环境 |
| ippromon.dll | RAW Socket | 9100 | 无发现 | ✅ | 传统 TCP 打印,无双向状态 |
| lprmon.dll | LPR | 515 | 无发现 | ✅ | 老旧 Unix 兼容,逐步淘汰 |
5、生产最佳实践
- 异构混合环境(Windows/macOS/Linux)优先使用 IPP Everywhere,避开 WSD 多播限制。
- 跨 VLAN 环境:mDNS 发现失效,手动填写 ipp://URI 即可正常打印,IPP 打印本身不依赖组播。
- 安全优先场景使用
ipps://加密;注意打印机证书管理。 - Windows 受保护打印模式 WPP,强制使用 IPP 栈,提升打印子系统安全,规避老旧 v3 驱动漏洞风险Microsoft ...
1、如何在 Windows 系统中使用 WSD 协议?
WSD(Web Services on Devices)用于局域网发现 WSD 打印机 / 扫描仪,分为客户端(发现外部设备)、服务端(发布本机设备)。
使用前提条件
- 网络配置文件:网卡网络配置文件必须为专用 / 专用网络;公用网络会直接阻止 WSD 多播发现。
- 打印机设备侧:打印机固件开启 WSD/DPWS 功能。
- Windows 服务:
fdPHost必须运行;打印需要Spooler。 - 防火墙放行:UDP3702,TCP5357、TCP5358。
操作步骤‑自动发现添加 WSD 打印机
- 确认打印机与电脑在同一个子网 VLAN(WSD 发现依赖 UDP 组播,跨 VLAN 默认无法自动发现)。
- 开启服务
Start‑Service fdPHost ‑ErrorAction SilentlyContinue
Start‑Service Spooler ‑ErrorAction SilentlyContinue
- 打开:
control.exe /name Microsoft.DevicesAndPrinters→ 添加设备,Windows 会通过 WS‑Discovery 多播探测局域网 WSD 设备。 - 在列表选中发现的 WSD 打印机,下一步完成安装;系统自动加载
wsdportmon.dllWSD 端口监视器。
跨 VLAN(无法自动发现):手动指定 URL 添加 WSD 打印机
- 打印机 Web 管理页面获取 WSD 设备 URL,格式示例:
http://192.168.1.100:5357/wprt/printer - 设置 → 蓝牙和设备 → 添加设备 → 我需要的设备不在列表中 → 使用 TCP/IP 地址或主机名添加打印机
- 设备类型选择:Web 服务设备 (WSD),填入打印机 IP,系统自动解析 WSD 端点完成安装。
注意:就算无法自动发现,只要 TCP 连通 5357 端口,手动填入 IP 就可以使用 WSD 打印。
2、如何在不重启的情况下更新计算机名?
Windows 内核中ActiveComputerName(hostname 读取的运行时 NetBIOS 主机名)没有官方不重启修改全局内核变量的方法。
Rename‑Computer/SetComputerNameExWAPI 只写入磁盘注册表,不会改写内核内存。
- 修改后:注册表是新名称;
hostname.exe、$env:COMPUTERNAME、SMB、Netlogon 域安全通道、WSD 设备宣告全部沿用旧名称。 - 必须操作系统重启,smss.exe 重新加载注册表,内核才刷新
ActiveComputerName。
局部临时生效(非全局,仅部分组件)
- DNS 主机名:修改
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Hostname,重启网卡服务,TCP/IP 栈 DNS 主机名更新;NetBIOS 内核名称不变。 - 当前会话伪装:
$env:COMPUTERNAME="NEW‑NAME",仅当前 PowerShell/CMD 会话生效,其他进程、系统服务全部还是旧主机名。
⚠️网上第三方工具直接改写内核内存ActiveComputerName,属于未文档化非官方手段;会破坏 AD 域安全通道、SMB、WSD、WMI,域环境严禁使用。
WSD 涉及两个核心服务
| 服务名称 | 显示名称 | 作用 | 启动类型建议 |
|---|---|---|---|
| fdPHost | Function Discovery Provider Host | 客户端:发现局域网外部 WSD 打印机 / 扫描仪 | 手动 (延迟启动) |
| FDResPub | Function Discovery Resource Publication | 服务端:把本机共享打印机对外广播给局域网其他电脑 | 手动 |
PowerShell 配置 WSD 服务
# 设置fdPHost自动(延迟启动)并启动,用于本机发现外部WSD设备
Set‑Service fdPHost ‑StartupType AutomaticDelayedStart
Start‑Service fdPHost
# FDResPub:本机需要对外发布本机共享打印机才开启;不需要则保持手动
Set‑Service FDResPub ‑StartupType Manual
#Start‑Service FDResPub
#打印后台服务(WSD打印必需)
Set‑Service Spooler ‑StartupType Automatic
Start‑Service Spooler
防火墙配置(WSD 必需)
#启用WSD防火墙规则
Enable‑NetFirewallRule ‑Name "WSD‑Events‑TCP‑In"
Enable‑NetFirewallRule ‑Name "WSD‑HTTP‑TCP‑In"
Enable‑NetFirewallRule ‑Name "WSD‑Discovery‑UDP‑In"
规则说明:
- WSD‑Discovery‑UDP‑In:UDP3702 设备多播发现
- WSD‑HTTP‑TCP‑In:TCP5357 WSD 明文业务通信
- WSD‑Events‑TCP‑In:TCP5357 WSD 事件订阅
组策略配置(域环境批量管控)
计算机配置 → 管理模板 → 网络 → 功能发现- 关闭功能发现的网络发现:启用 → fdPHost/WSD 设备发现全部失效;不启用则允许 WSD 发现。
- 关闭功能发现资源发布:启用 → FDResPub 停止,本机设备不会对外广播 WSD Hello 报文。
修复 WSD 端口监视器(WSD 打印端口丢失故障)
#重新注册WSD端口监视器
pnputil /add‑driver "$env:windir\System32\spool\monitors\wsdportmon.inf"
Restart‑Service Spooler
关键注意点
- WSD 发现依靠 UDP 组播,跨 VLAN 无法自动发现,只能手动填写 IP 添加 WSD 设备。
- 仅开启 fdPHost 就可以发现外部打印机;FDResPub 只用于对外发布本机设备,普通办公客户端不需要开启。
- 公用网络配置文件,WSD 防火墙规则不会生效,设备无法发现。
跨平台 WSD(DPWS)使用解答
基础概念重申:WSD = Web Services on Devices,微软 Windows 实现;底层标准是 OASIS DPWS(Devices Profile for Web Services)。WS‑Discovery(UDP3702)是 DPWS 的设备发现子协议。⚠️:Linux/macOS 没有系统原生 WSD 完整协议栈,不像 Windows 内置wsdapi.dll。
1、如何在 Windows 系统中使用 WSD 协议?
- 网络配置文件设置为专用网络;公用网络防火墙阻断 WSD。
- 开启服务:
fdPHost(发现外部 WSD 设备)、Spooler打印后台;如需对外发布本机设备开启FDResPub。 - 防火墙放行规则:UDP3702,TCP5357、TCP5358。
- 同子网:控制面板「设备和打印机」直接自动发现 WSD 打印机;
- 跨 VLAN:无法组播发现,手动填写打印机 WSD HTTP URL 添加 Web 服务设备。
2、如何在 Linux 系统中使用 WSD (DPWS) 协议?
现状
方案 A:绕过 WSD,直接使用打印机底层服务(生产推荐)
- RAW Socket 9100 端口
- IPP 631 端口
Linux CUPS 直接添加Socket://ip:9100或者ipp://ip:631,完全避开 WSD 协议,稳定性最好。
方案 B:使用第三方 DPWS 开源组件,实现 WSD 发现与通信
- gSOAP:实现 DPWS 标准的 C 库,可以开发 DPWS 客户端 / 服务端;无开箱即用工具,需要二次开发。
- wsdd(WS‑Discovery Daemon)
项目:wsdd,仅实现 WS‑Discovery 发现协议(UDP3702)✅ 可以在 Linux 上发出 Probe 报文,局域网探测 WSD 设备,拿到设备 XAddrs (WSD http 地址)❗ wsdd 只做设备发现,不实现完整 WSD 打印 SOAP 业务;拿到 URL 后 CUPS 仍然不能直接打印。
wsdd 部署示例(Debian/Ubuntu)
apt install wsdd
systemctl enable --now wsdd
# 抓包验证UDP3702多播探测
tcpdump -i eth0 udp port 3702
小结 Linux
- 仅做设备发现:部署
wsdd; - 打印业务:不建议走 WSD,优先 IPP/RAW9100;
- 如果必须完整 DPWS/WSD 打印,需要基于 gSOAP 自行开发客户端。
现状
方案
-
✅ 优先绕过 WSD 协议(推荐)WSD 打印机几乎全部同时支持 IPP/AirPrint,macOS 直接通过 AirPrint 发现打印机,或者手动填写 IP 使用 IPP/Socket 打印,完全避开 WSD。
-
想要在 macOS 做 WSD 设备发现:可以编译运行开源
wsdd(WS‑Discovery 守护进程),完成 UDP3702 探测,获取 WSD 设备 URL;macOS 打印系统无法消费 WSD SOAP 打印任务,仅能做发现,不能打印。
关键坑:Windows 的 WSD 打印机,拿到 WSD http 地址,macOS 无法直接拿来打印。
Windows / Linux /macOS WSD 能力横向对照表
| 平台 | 原生 WSD/DPWS 完整栈 | WS‑Discovery 设备发现 | 原生支持 WSD 打印 | 推荐打印方式 |
|---|---|---|---|---|
| Windows | ✅ wsdapi.dll 完整实现 | ✅ fdPHost 内置 | ✅ WSDMON 端口监视器 | WSD / Standard‑TCP/IP |
| Linux | ❌无原生栈 | ✅ 第三方 wsdd 工具 | ❌CUPS 不支持 WSD 打印 | IPP / RAW‑Socket 9100 |
| macOS | ❌无原生栈 | ✅编译 wsdd 第三方 | ❌系统打印不支持 WSD | AirPrint / IPP |
运维最佳实践:异构混合环境(Windows+Linux+macOS),不要依赖 WSD 协议;统一使用 IPP/AirPrint,跨平台兼容性最好。
wsdd(Linux WS‑Discovery 守护进程)拆解|解构|底层原理|依赖文件|依赖关系|逻辑链路|配套链
基础定位wsdd = WS‑Discovery Daemon,Linux 开源实现,实现 OASIS DPWS 标准中的 WS‑Discovery 协议(UDP 3702)。两大角色:
- 客户端模式(wsdd‑c):发送 Probe 多播,发现局域网 WSD/DPWS 设备(WSD 打印机)。
- 服务端模式(wsdd):对外发布本机服务,让 Windows 主机可以发现 Linux 主机上的 CUPS 打印机(模拟 Windows FDResPub 的行为)。
重要边界:wsdd 只实现 WS‑Discovery 发现子协议,不实现完整 DPWS/WSD SOAP 业务层。✔ 能发现设备、广播设备存在;❌ 不能完成 WSD 打印、解析 WSDL、提交 SOAP 打印任务。CUPS 仍然不能直接使用 WSD 端点打印。
一、底层原理
协议栈
应用层:wsdd python业务逻辑
表示层:SOAP‑Envelope 精简SOAP报文(仅WS‑Discovery消息:Hello / Bye / Probe / ProbeMatches / Resolve)
传输层:UDP 3702
网络层:IPv4多播地址 239.255.255.250;支持IPv6多播
WS‑Discovery 核心报文
Probe:客户端 wsdd‑c 向多播组发送探测,查询设备类型,例如打印设备wprt:PrintDeviceProbeMatches:设备单播回复,返回设备 UUID、XAddrs(WSD HTTP 访问地址)Hello:服务端 wsdd 启动,向多播组宣告本机设备上线Bye:服务端退出,发送报文宣告设备离线
wsdd不实现:WS‑Eventing、WSDL 元数据获取、SOAP 打印业务,这些属于上层 DPWS,需要 gSOAP 等完整栈。
两种运行模式
- 客户端模式
wsdd -c / wsdd‑c监听 + 发送 UDP3702 多播,发送 Probe,收集局域网 DPWS/WSD 设备,输出设备 UUID、XAddrs、设备类型。
仅做扫描发现,不做打印。
- 服务端模式(默认直接运行 wsdd)
读取 CUPS 打印机列表,组装 WS‑Discovery Hello 报文,UDP3702 多播广播;Windows 主机 fdPHost 收到 Hello 报文,就会在「设备和打印机」看到这台 Linux CUPS 打印机。
⚠️ Windows 只是发现看到图标;实际打印不走 WSD,Windows 内部会回退使用 IPP 和 CUPS 通信。
二、依赖文件
基于 Debian/Ubuntu 打包版本(apt install wsdd)
- 主程序:
/usr/bin/wsdd(Python3 脚本) - systemd 单元:
/lib/systemd/system/wsdd.service - 配置目录:
/etc/wsdd/,可选配置config - PID 文件:
/run/wsdd.pid - 日志输出:syslog/journald
软件依赖
- python3(运行时)
- python3‑netifaces:网卡枚举,获取本机网卡、IP、多播支持
- python3‑lxml:生成 / 解析 SOAP‑XML WS‑Discovery 报文
- cups‑client(服务端模式需要,读取本机 CUPS 打印机列表)
无内核模块;纯用户空间 Python 应用,基于系统 socket API。
三、依赖关系
wsdd 依赖关系
├─系统依赖
│ ├─Python3解释器
│ ├─netifaces:遍历本机网卡,过滤回环,选择参与多播的网卡
│ ├─lxml:SOAP XML报文序列化解析
│ ├─socket内核:UDP socket,加入多播组239.255.255.250:3702
│ └─IGMP:内核IGMP协议栈,加入多播组,交换机转发组播报文
├─服务端模式额外依赖(对外发布本机CUPS打印机给Windows)
│ └─cups‑client:调用cups API获取本机打印机名称、URI
├─网络依赖
│ ├─防火墙放行 UDP 3702(入站+出站)
│ ├─交换机IGMP Snooping,允许239.255.255.250多播
│ └─仅同一子网VLAN生效;跨VLAN组播无法到达
└─不依赖
└─不实现TCP 5357/5358;不实现完整DPWS/WSD业务;不处理打印作业
关键:
- 客户端模式扫描网络 WSD 打印机:不需要 CUPS。
- 服务端模式,让 Windows 发现 Linux 打印机:必须 CUPS 运行。
四、完整逻辑链路
链路 A:客户端模式 wsdd‑c 扫描局域网 WSD 设备
- wsdd‑c 启动,读取本机网卡列表,跳过 lo 回环。
- UDP socket 创建,加入多播组
239.255.255.250:3702。 - 构造 SOAP‑XML
Probe报文,查询打印设备类型wprt:PrintDevice。 - UDP 发送多播 Probe 到局域网。
- 局域网 WSD 打印机收到 Probe,单播回复
ProbeMatches。 - wsdd‑c 使用 lxml 解析返回 XML,提取:设备 UUID、XAddrs (WSD http 地址)、设备类型。
- 控制台输出设备清单;程序退出。
到此为止,只拿到 WSD URL;没有后续 WSDL、SOAP 打印交互。
链路 B:服务端模式 wsdd(把 Linux CUPS 打印机广播给 Windows)
- wsdd 服务启动,systemd 调用 /usr/bin/wsdd。
- 枚举本机网卡,加入 UDP 多播组 239.255.255.250:3702。
- 调用 cups 客户端接口,读取本机 CUPS 所有打印机。
- 为每台 CUPS 打印机生成 DPWS 设备 UUID,组装 WS‑Discovery Hello SOAP 报文。
- UDP 多播向外发送 Hello 报文,携带 XAddrs 指向本机 CUPS IPP 地址。
- Windows 主机 fdPHost(WSDAPI)收到 Hello 报文。
- Windows「设备和打印机」出现该 Linux 打印机图标。
Windows只是通过 WS‑Discovery 发现;实际打印通信走 IPP,不走 WSD SOAP。
- wsdd 监听 UDP 3702,收到 Windows 发来的 Probe 探测报文,回复 ProbeMatches。
- wsdd 进程退出时,发送 Bye 报文,宣告设备离线。
五、配套链(运维、故障、配置、限制)
1、常用运维命令
# 查看状态
systemctl status wsdd
# 启动停止
systemctl start wsdd
systemctl stop wsdd
systemctl enable wsdd
# 客户端模式扫描局域网WSD设备
wsdd -c
# 指定网卡运行(多网卡机器)
wsdd -i eth0
wsdd -c -i eth0
# 查看日志
journalctl -u wsdd -f
2、防火墙配置示例(ufw)
#放行UDP3702入站出站
ufw allow proto udp from any to any port 3702
3、配置文件 /etc/wsdd/config
#指定网卡,多网卡服务器常用
INTERFACES="eth0"
#是否发布cups打印机
CUPS=true
4、故障链条
-
现象:wsdd‑c 扫描不到局域网 WSD 打印机
- 根因 1:防火墙拦截 UDP3702;
- 根因 2:交换机 IGMP‑Snooping 丢弃多播报文;
- 根因 3:网卡未加入多播组;
- 根因 4:跨 VLAN,组播无法跨三层。
-
现象:Windows 看不到 Linux 发布的 CUPS 打印机
- wsdd 服务未运行;cups 未运行;防火墙 UDP3702 拦截;
- Windows 主机网络配置文件为公用网络,fdPHost 防火墙阻断 WSD 发现报文。
-
认知误区:
❌:跑了 wsdd,Linux 就可以用 WSD 协议打印 WSD 打印机。✅:wsdd 仅做 WS‑Discovery 发现;打印需要 IPP/RAW9100。
5、能力边界清单
| 功能 | wsdd 是否支持 |
|---|---|
| WS‑Discovery Hello / Bye / Probe / ProbeMatches | ✅完整支持 |
| 发现局域网 WSD/DPWS 打印机设备 | ✅ |
| 对外广播本机 CUPS 打印机给 Windows | ✅ |
| 获取设备 WSDL 元数据(TCP5357 HTTP) | ❌不实现 |
| WS‑Eventing 事件订阅 | ❌不实现 |
| WSD SOAP 打印任务提交 | ❌不实现 |
6、同类组件对比
- wsdd:轻量 Python,只做 WS‑Discovery;适合异构环境设备发现。
- gSOAP:完整 DPWS 协议栈 C 库;可实现完整 WSD 客户端 / 服务端;需要开发,无现成工具。
- Windows wsdapi.dll:微软完整 DPWS 实现,包含 WS‑Discovery + WSDL + SOAP 打印业务。
7、生产环境最佳实践
- Linux 客户端要使用 WSD 打印机:不要依赖 wsdd 做打印;wsdd‑c 仅用于扫描获取 IP,CUPS 添加 IPP/Socket (9100)。
- Linux 服务器共享打印机给 Windows:启用 wsdd 服务端模式,Windows 可以自动发现;实际打印走 IPP。
- 跨 VLAN 环境:WS‑Discovery 多播失效,wsdd 无法跨三层发现设备,必须手动填写 IP。
基于 PowerShell 的 .ps1 批处理文件需求开发文档,用于安装网络打印机,并根据输入的 IP 地址自动添加打印机。假设驱动已经预安装好。
需求开发文档:使用 PowerShell 安装网络打印机
1. 目标
开发一个 PowerShell 脚本 .ps1,用于在 Windows 系统上安装网络打印机。该脚本将:
- 自动根据输入的 IP 地址配置并添加网络打印机。
- 确保驱动程序已安装,并且打印机通过 TCP/IP 协议进行连接。
2. 需求
- 打印机驱动程序已经在系统中预先安装。
- 用户可以通过输入打印机的 IP 地址来安装打印机。
- 打印机将通过 TCP/IP 协议连接到网络。
3. 功能描述
PowerShell 脚本将执行以下任务:
- 提示用户输入网络打印机的 IP 地址。
- 检查并确保打印机驱动程序已经安装。
- 使用 PowerShell 命令将网络打印机添加到系统中。
4. 方案设计
- 使用 PowerShell cmdlet 添加打印机。
Add-PrinterPort用于创建打印机端口。Add-Printer用于将打印机添加到系统。
5. 安装步骤及命令说明
步骤 1: 准备工作
- 确保打印机驱动已经安装且可用。
- 确保打印机的 IP 地址正确。
步骤 2: 编写 PowerShell 脚本
以下是使用 PowerShell 添加网络打印机的脚本示例:
# 提示用户输入打印机的 IP 地址
$PrinterIP = Read-Host "请输入打印机的 IP 地址 (例如 192.168.1.100)"
# 定义打印机名称和驱动程序
$PrinterName = "NetworkPrinter" # 设置打印机名称
$DriverName = "PrinterModel" # 设置驱动程序名称 (必须与预安装驱动名称一致)
# 创建打印机端口
$PortName = "IP_$PrinterIP" # 基于 IP 地址创建端口名称
$PortExists = Get-WmiObject -Query "SELECT * FROM Win32_TCPIPPrinterPort WHERE Name = '$PortName'"
if ($PortExists -eq $null) {
Write-Host "正在创建打印机端口 $PortName..."
Add-PrinterPort -Name $PortName -PrinterHostAddress $PrinterIP
Write-Host "打印机端口 $PortName 创建成功"
} else {
Write-Host "打印机端口 $PortName 已存在"
}
# 检查是否已经安装指定驱动程序
$DriverExists = Get-WmiObject -Query "SELECT * FROM Win32_PrinterDriver WHERE Name = '$DriverName'"
if ($DriverExists -eq $null) {
Write-Host "指定的打印机驱动未找到,请确保驱动已安装"
exit
}
# 安装网络打印机
Write-Host "正在安装打印机..."
Add-Printer -Name $PrinterName -Port $PortName -DriverName $DriverName
Write-Host "打印机 '$PrinterName' 安装成功"
# 设置为默认打印机
Set-Printer -Name $PrinterName -IsDefault $true
Write-Host "打印机 '$PrinterName' 已设置为默认打印机"
步骤 3: PowerShell 脚本说明
-
输入打印机 IP 地址:
- 使用
Read-Host提示用户输入打印机的 IP 地址。
- 使用
-
创建打印机端口:
- 使用
Add-PrinterPort命令来创建基于 IP 地址的 TCP/IP 打印机端口。 - 使用
Get-WmiObject检查端口是否已经存在,如果不存在则创建。
- 使用
-
检查打印机驱动程序:
- 使用
Get-WmiObject检查系统中是否安装了所需的打印机驱动程序。
- 使用
-
安装网络打印机:
- 使用
Add-Printer命令将打印机添加到系统中。
- 使用
-
设置默认打印机:
- 使用
Set-Printer设置该打印机为默认打印机。
- 使用
步骤 4: 文件保存与执行
- 将脚本保存为
.ps1文件,例如install_network_printer.ps1。 - 通过 PowerShell 执行脚本:
- 打开 PowerShell 窗口(以管理员身份运行)。
- 进入脚本所在的目录并运行:
powershellCopy Code
.\install_network_printer.ps1
6. 错误处理
- 如果用户输入的 IP 地址无效或无法连接,脚本将显示错误信息并退出。
- 如果打印机驱动程序未正确安装,脚本将提示并退出。
- 如果打印机端口已存在,则跳过创建端口步骤。
7. 测试
在多台机器上测试该 PowerShell 脚本,确保能够通过 IP 地址成功安装并配置网络打印机。
通过这个 PowerShell 脚本,可以简化网络打印机的安装过程。用户只需输入打印机的 IP 地址,脚本将自动安装并配置网络打印机。此脚本适用于已预先安装打印机驱动的环境,能够确保网络打印机的自动安装与设置。
为了实现通过命令行批处理文件(.cmd)安装网络打印机,假设驱动已经预安装好,您需要通过命令来手动添加打印机。以下是需求开发文档,描述了如何使用命令行批处理文件来安装网络打印机。
需求开发文档:通过命令行安装网络打印机
1. 目标
开发一个批处理文件 .cmd,用于在 Windows 系统上安装网络打印机。该批处理文件将:
- 自动添加已预安装驱动的网络打印机
- 通过输入打印机的 IP 地址来自动配置并安装打印机
2. 需求
- 打印机驱动程序已预先安装。
- 需要在打印机 IP 地址可用的情况下通过命令行自动添加打印机。
- 打印机将通过 TCP/IP 协议连接。
3. 功能描述
批处理文件的功能包括:
- 通过 IP 地址添加打印机:根据用户输入的打印机 IP 地址,自动将打印机添加到系统。
- 命令行自动配置:使用命令行将打印机与操作系统连接并确保能够正常打印。
4. 方案设计
使用 Windows 提供的命令行工具进行操作:
rundll32:用于调用 Windows API 管理打印机。printui.dll:用于打印机管理。net use:用于映射共享打印机(如果是共享网络打印机)。
5. 安装步骤及命令说明
步骤 1: 准备工作
- 打印机驱动已安装并准备好。
- 确保打印机的 IP 地址和打印机名称正确。
步骤 2: 批处理命令编写
-
添加网络打印机
- 假设打印机的 IP 地址为
192.168.1.100,并且已安装相应的打印机驱动程序。
下面是添加网络打印机的基本命令:
Copy Code@echo off set /p PrinterIP=请输入打印机的IP地址(例如 192.168.1.100): set PrinterName=NetworkPrinter rem 使用 netsh 或 rundll32 进行打印机添加 rundll32 printui.dll,PrintUIEntry /if /b "%PrinterName%" /f "C:\path\to\driver.inf" /r "TCPIP_%PrinterIP%" /m "PrinterModel" echo 打印机添加成功!打印机名称为:%PrinterName% pause/b "%PrinterName%":指定打印机的名称。/f "C:\path\to\driver.inf":指定打印机驱动的安装文件路径。/r "TCPIP_%PrinterIP%":指定打印机的连接类型(使用 TCP/IP 协议)和 IP 地址。/m "PrinterModel":指定驱动的打印机型号。
- 假设打印机的 IP 地址为
-
添加共享网络打印机(如果适用) 如果您要添加的是共享打印机,您可以使用以下命令:
Copy Code@echo off set /p PrinterIP=请输入共享打印机的IP地址(例如 192.168.1.100): set PrinterName=SharedPrinter rem 添加网络共享打印机 net use \\%PrinterIP%\PrinterName rundll32 printui.dll,PrintUIEntry /y /n "\\%PrinterIP%\PrinterName" echo 打印机已连接并设置为默认打印机 pausenet use \\%PrinterIP%\PrinterName:映射共享打印机。rundll32 printui.dll,PrintUIEntry /y /n "\\%PrinterIP%\PrinterName":将共享打印机设置为默认打印机。
-
设置打印机为默认打印机 若需要将已安装的打印机设置为默认打印机,可以使用以下命令:
Copy Coderundll32 printui.dll,PrintUIEntry /y /n "NetworkPrinter"
步骤 3: 批处理文件说明
- 该批处理文件将提示用户输入打印机的 IP 地址,并根据该地址添加网络打印机。
- 批处理文件会将指定的打印机设置为默认打印机。
printui.dll和net use命令会确保打印机正确添加并能被系统识别。
步骤 4: 文件保存与执行
- 将上述内容保存为
.cmd文件,例如install_network_printer.cmd。 - 双击执行该批处理文件,根据提示输入打印机的 IP 地址即可自动安装网络打印机。
6. 错误处理
- 如果输入的 IP 地址无法连接,批处理文件将显示错误信息,并要求重新输入。
- 如果驱动程序文件路径错误,系统会提示找不到驱动并退出。
7. 测试
- 在多台机器上测试批处理文件,确保能根据 IP 地址正确安装并设置打印机。
通过以上的批处理命令,可以在 Windows 系统上自动添加网络打印机,并通过 IP 地址指定连接的打印机。该批处理文件简化了打印机安装的步骤,特别适用于预安装驱动的情况。
基于 VBScript 的网络打印机安装需求开发文档,适用于在驱动程序已预安装的情况下,手动添加打印机并通过输入 IP 地址进行配置和安装。
需求开发文档:使用 VBScript 安装网络打印机
1. 目标
开发一个 VBScript 脚本,用于在 Windows 系统上安装网络打印机。该脚本将:
- 提示用户输入打印机的 IP 地址。
- 安装打印机并配置打印机端口。
- 假设打印机驱动程序已经预安装。
2. 需求
- 打印机驱动程序已预安装。
- 用户手动输入打印机的 IP 地址,脚本根据输入的 IP 地址配置和安装打印机。
3. 功能描述
VBScript 脚本将执行以下任务:
- 提示用户输入网络打印机的 IP 地址。
- 创建 TCP/IP 打印机端口。
- 将打印机添加到系统。
- 将安装的打印机设置为默认打印机。
4. 方案设计
- 使用 WScript.Network 对象来操作打印机安装。
- 使用 AddPrinterConnection 方法将打印机添加到系统。
- 使用 AddPrinterPort 方法创建打印机端口。
- 提供用户输入 IP 地址的界面。
5. 安装步骤及命令说明
步骤 1: 准备工作
- 确保打印机驱动程序已在系统中预安装。
- 确保网络中打印机的 IP 地址是正确的,并且打印机已连接到网络。
步骤 2: 编写 VBScript 脚本
以下是 VBScript 脚本示例:
' VBScript 脚本:安装网络打印机
' 提示用户输入打印机的 IP 地址
PrinterIP = InputBox("请输入打印机的 IP 地址 (例如 192.168.1.100):", "输入打印机 IP 地址")
' 检查输入是否为空
If PrinterIP = "" Then
MsgBox "IP 地址不能为空。脚本将退出。"
WScript.Quit
End If
' 定义打印机端口名称和打印机名称
PortName = "IP_" & PrinterIP
PrinterName = "Network Printer" ' 设置打印机的名称
DriverName = "PrinterModel" ' 需要预安装的打印机驱动程序名称
' 创建打印机端口
Set objNetwork = CreateObject("WScript.Network")
' 检查端口是否已存在
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_TCPIPPrinterPort WHERE Name = '" & PortName & "'")
If colItems.Count = 0 Then
' 创建打印机端口
Set objPrinterPort = objWMIService.Get("Win32_TCPIPPrinterPort").SpawnInstance_
objPrinterPort.Name = PortName
objPrinterPort.HostAddress = PrinterIP
objPrinterPort.PortNumber = 9100 ' 默认端口号
objPrinterPort.Put_
MsgBox "打印机端口 " & PortName & " 创建成功。"
Else
MsgBox "打印机端口 " & PortName & " 已存在。"
End If
' 添加打印机连接
Set objPrinter = objNetwork.AddPrinterConnection("\\\\" & PrinterIP & "\" & PrinterName)
objPrinter.SetDefaultPrinter()
MsgBox "网络打印机 '" & PrinterName & "' 已成功安装并设置为默认打印机。"
步骤 3: VBScript 脚本说明
-
输入打印机 IP 地址:
- 使用
InputBox提示用户输入打印机的 IP 地址。如果用户没有输入 IP 地址,则退出脚本。
- 使用
-
创建打印机端口:
- 通过
WMI(Windows Management Instrumentation)查询当前系统中是否已经存在该 IP 地址的打印机端口。 - 如果端口不存在,则使用
Win32_TCPIPPrinterPort创建新的 TCP/IP 打印机端口。
- 通过
-
添加打印机:
- 使用
WScript.Network对象的AddPrinterConnection方法将网络打印机添加到系统中。 - 使用
SetDefaultPrinter设置新添加的打印机为默认打印机。
- 使用
-
错误处理:
- 如果 IP 地址无效或用户未输入,则弹出提示框并退出脚本。
- 如果端口已经存在,脚本会跳过创建端口的步骤。
步骤 4: 文件保存与执行
- 将上述脚本保存为
.vbs文件,例如install_network_printer.vbs。 - 通过 Windows 系统上的 脚本执行 运行该文件:
- 双击
install_network_printer.vbs文件即可运行。
- 双击
6. 错误处理
- 如果用户输入的 IP 地址无效或不可访问,脚本将显示错误提示并终止操作。
- 如果打印机驱动程序未正确安装,脚本将无法添加打印机。此时需要检查驱动程序安装情况。
- 如果端口已存在,脚本会跳过创建端口的步骤。
7. 测试
在多台机器上测试该 VBScript,确保能够通过 IP 地址成功安装并配置网络打印机。
通过这个 VBScript 脚本,可以简化网络打印机的安装过程,用户只需输入打印机的 IP 地址,脚本将自动安装并配置网络打印机。此脚本假设驱动程序已预安装在系统中,能够确保网络打印机的自动安装与设置。



浙公网安备 33010602011771号