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

截图_选择区域_20260820154824

截图_选择区域_20260820154642

截图_选择区域_20260820154701

 

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.exe Print 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.exe Print Spooler
  • 协议:二进制 TLV 报文封装在 HTTP POST Body;发现依靠 mDNS/Bonjour (UDP5353)
  • 端口:业务 TCP:631 (HTTP‑IPP) / TCP:631 (TLS‑IPPS 加密)
  • 配套驱动:ippclass.dll Microsoft IPP Class Driver(IPP Everywhere 通用无驱驱动),不需要厂商驱动。
  • Win11 新增:Protected Print(受保护打印模式),强制仅允许 IPP 类驱动,拦截老旧 v3 驱动、RAW、LPR、WSD 打印路径,提升打印子系统安全。

二、底层原理拆解

2.1 wsdportmon.dll(WSD)完整协议栈

plaintext
应用层 → 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 特点:
  1. 控制报文与打印作业全部是SOAP‑XML文本;
  2. 具备事件订阅:打印机状态变化主动推送回 Windows;
  3. 强依赖子网多播,跨 VLAN 三层网络自动发现失效,虽然可以手动填写 WSD HTTP URL,但实际生产兼容性差;
  4. 没有系统通用无驱,大多需要厂商驱动。

2.2 ippmon.dll(IPP)完整协议栈

plaintext
应用层 → 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 特点:
  1. 报文是二进制 TLV,不是 XML;HTTP 只是承载通道;
  2. mDNS 仅做设备发现;打印通信本身完全不依赖多播;跨 VLAN 手动填写ipps://ip/ipp/print即可正常打印;
  3. ippclass.dll通用类驱动,Windows 自带,不需要厂商提供驱动;macOS/Linux CUPS 原生支持。

2.3 Protected Print(Win11 受保护打印模式)底层原理

组策略 / 注册表开启受保护打印:
 
HKLM\Software\Policies\Microsoft\Windows NT\Printers\ProtectedPrint = 1
  1. Spooler 打印路由器做路径拦截;
  2. 只放行:ippmon.dll + Microsoft IPP Class Driver路径;
  3. 拒绝 wsdportmon.dll (WSD)、raw tcp9100、LPR、第三方 v3 驱动
  4. 目标:消除老旧 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.dll
端口实例:
 
HKLM\SYSTEM\CurrentControlSet\Control\Print\Ports\WSD‑xxxxxxxx

ippmon.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.dll
端口实例:
 
HKLM\SYSTEM\CurrentControlSet\Control\Print\Ports\ipp://xxx

公共宿主依赖

  1. spoolsv.exe Print Spooler 服务,两个监视器全部在此进程内加载;spooler 停止,WSD、IPP 全部失效。
  2. spoolss.dll:打印路由器,负责调度各个端口监视器。

四、依赖关系

wsdportmon.dll 依赖链

plaintext
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 依赖链

plaintext
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)

  1. fdPHost + wsdapi.dll 通过 UDP3702 WS‑Discovery 多播探测局域网 WSD 打印机。
  2. Windows 发现 WSD 设备,生成 WSD 端口记录,注册表写入 WSD‑xxxx 端口。
  3. spoolsv 加载wsdportmon.dll端口监视器。
  4. wsdportmon.dll 调用 wsdapi.dll 发起 HTTP SOAP‑XML 请求获取设备元数据、能力。
  5. 绑定厂商 v4 打印驱动。
  6. 打印作业:假脱机文档封装为 SOAP PrintJob XML,HTTP POST 到打印机 TCP5357。
  7. DPWS 订阅事件:打印机状态变更主动推送回 Windows。
  8. 开启 Protected Print 时,spooler 直接拒绝该端口监视器,打印失败。

链路 2:IPP 打印机完整流程(ippmon.dll)

  1. mDNS/Bonjour 发现局域网_ipp._tcp.local打印机;仅发现阶段
  2. 用户添加打印机,spoolsv 加载ippmon.dll
  3. ippmon.dll 发送 HTTP POST Get‑Printer‑Attributes获取打印机能力。
  4. 绑定系统自带Microsoft IPP Class Driver(ippclass.dll)无需厂商驱动
  5. 打印作业:假脱机文档封装 IPP TLV 二进制报文,HTTP POST TCP631;IPPS 场景经过 schannel TLS 加密。
  6. ippmon 周期性轮询打印机状态。
  7. 开启 Protected Print,该路径正常放行。

六、配套链:运维、故障、组策略、选型对比

关键 PowerShell 运维片段

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

故障链条

  1. WSD 故障
    • 同子网搜不到 WSD 打印机:检查 fdPHost 服务、防火墙 UDP3702;交换机 IGMP‑Snooping;
    • 跨 VLAN 环境:WSD 自动发现不可用;就算手动填 WSD URL,兼容性参差不齐;
    • 开启 Protected Print:WSD 打印直接失效。
  2. IPP 故障
    • 找不到 IPP Port Monitor:缺少Printing‑Internet‑Print‑Client可选 Windows 功能;
    • mDNS 看不到设备,但手动填写 ipp:// 可以打印:属于 mDNS 发现故障,ippmon 本身正常;
    • IPPS 打印失败:打印机证书不信任,TLS 握手失败。

组策略控制点

  1. 计算机配置‑打印机‑关闭WSD打印:注销wsdportmon.dll WSD 端口监视器。
  2. 计算机配置‑打印机‑关闭Internet打印客户端:注销ippmon.dll IPP 端口监视器。
  3. 计算机配置‑打印机‑启用受保护打印: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 战略定位 逐步弱化、兼容存量 主推,企业异构环境首选

生产最佳实践

  1. 新建网络环境优先部署 IPP Everywhere / IPPS 加密,放弃 WSD;
  2. 已有存量 WSD 打印机,尽量切换到 IPP 模式;
  3. 高安全域开启 Protected Print 受保护打印,强制 IPP 路径,消除老旧打印驱动攻击面;
  4. 跨 VLAN 办公网络:不要依赖任何多播发现,手动填写ipps://ip/ipp/print部署打印机。

WSD

全称:Web Services on Devices(也写作 Web Services for Devices)
 
中文:设备 Web 服务

相关容易混淆名词

  1. DPWSDevices Profile for Web Services,Web 服务设备配置文件(OASIS 公开标准,WSD 就是 Windows 对 DPWS 的微软实现)Microsoft ...
  2. WSDAPI:Windows 系统 API,Web Services on Devices API,实现 WSD 的系统组件,对应二进制wsdapi.dll
  3. WS‑Discovery:底层发现子协议,端口 UDP/TCP 3702,负责局域网多播设备发现,属于 DPWS 的一部分
  4. Windows 配套服务:fdPHostFDResPub(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)

plaintext
应用层: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局域网多播
  1. 发现阶段(WS‑Discovery)
     
    设备上电发送Hello多播报文宣告上线;Windows 客户端发送Probe多播探测报文;匹配设备单播返回ProbeMatches,携带设备 UUID、访问 URL(XAddrs)。
多播报文只能在同一 VLAN / 子网传播;跨 VLAN 默认无法发现,需要组播代理。
  1. 元数据获取阶段
     
    拿到设备 HTTP 地址后,客户端 HTTP 请求获取设备 WSDL 元数据 XML;获取打印机能力:纸张、分辨率、墨水状态、扫描服务。
  2. 业务交互阶段
     
    SOAP over HTTP 提交打印任务、订阅设备事件(缺纸、卡纸、墨量变化);WSDMON 端口监视器负责对接 Windows 打印后台 spooler,把打印作业封装为 WSD SOAP 消息发给打印机,接收设备状态事件回写到打印子系统Microsoft ...。
关键特点:全部消息为 XML‑SOAP 文本,相比 RAW 9100 流量开销更大;支持双向 BIDI 状态回传,不需要 SNMP 也能拿到打印机状态。

2、Windows 内部软件架构

plaintext
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。

二、依赖文件

核心二进制文件

  1. wsdapi.dll
     
    C:\Windows\System32\wsdapi.dll,WSDAPI 主 COM 组件,DPWS 协议栈实现,所有 WSD 功能的核心库。
  2. wsdportmon.dll
     
    C:\Windows\System32\spool\monitors\wsdportmon.dllWSDMON 打印端口监视器,spooler 加载,专门处理 WSD 打印端口。
  3. fdwcnex.dll:Function Discovery WSD 连接器,fdPHost 服务加载,桥接功能发现与 WSDAPI。
  4. http.sys:内核 HTTP 驱动,TCP5357/5358 监听载体。
  5. 驱动 / INF:wsdportmon.inf WSD 端口监视器注册信息。

系统服务可执行文件

  1. fdPHost.exe(Function Discovery Provider Host):客户端发现外部 WSD 设备
  2. FDResPub.exe(Function Discovery Resource Publication):发布本机设备到局域网
  3. spoolsv.exe:打印后台,WSDMON 由 spoolsv 加载。

注册表依赖

  1. WSD 端口监视器注册
     
    HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\WSD Port Monitor
注册表损坏会导致 WSD 打印端口消失,无法添加 WSD 打印机。
  1. 功能发现配置:HKLM\SYSTEM\CurrentControlSet\Services\fdPHostHKLM\SYSTEM\CurrentControlSet\Services\FDResPub
  2. 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 加密业务通信

三、依赖关系

plaintext
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两套独立发现机制,互不强制依赖)
重要:
  1. fdPHost 停止:Windows 无法发现局域网 WSD 打印机;已经安装好的 WSD 打印机仍然可以打印(不需要发现,直接 TCP 通信)。
  2. FDResPub 停止:其他电脑发现不到本机共享的 WSD 设备,不影响本机去发现外部打印机。
  3. 禁用 UDP3702:设备发现失效,但是已知 WSD 设备(已经安装)打印不受影响

四、完整逻辑链路

链路 A:Windows 发现局域网 WSD 打印机完整流程

  1. 本机fdPHost.exe启动,加载fdwcnex.dll调用wsdapi.dll
  2. wsdapi.dll 通过 UDP 3702 向多播地址239.255.255.250发送Probe探测报文(SOAP‑XML),查询wprt:PrintDevice打印设备类型。
  3. 局域网内支持 WSD 的打印机收到多播报文,单播回复ProbeMatches报文,返回设备 UUID、HTTP 访问 URL (XAddrs)。
  4. WSDAPI 拿到设备 URL,发起 TCP 5357 HTTP 请求,获取设备 WSDL 元数据 XML,解析打印机能力、服务端点。
  5. Function Discovery 向上层(设备和打印机控制面板)上报发现到的设备实例。
  6. 用户点击添加设备:系统注册 WSD 端口,spoolsv 加载wsdportmon.dll,创建 WSD 打印机端口。
  7. WSDMON 订阅 WS‑Eventing 事件,持续接收打印机缺纸、墨量状态上报。

链路 B:WSD 打印作业发送流程

  1. 应用程序发起打印,spoolsv 生成打印作业文件。
  2. spoolsv 调用 WSDMON(wsdportmon.dll)端口监视器。
  3. WSDMON 调用 wsdapi.dll,把打印数据封装为 WSD SOAP 消息,HTTP POST 发送到打印机 TCP5357 端点。
  4. 打印机接收任务执行打印;通过 WS‑Eventing 事件回传状态。
  5. WSDMON 把设备状态回写给 Windows 打印子系统,设备管理器 / 打印机面板显示状态。

链路 C:本机对外发布 WSD 设备(FDResPub)

  1. FDResPub 服务启动,调用 wsdapi.dll。
  2. http.sys 监听 TCP5357/5358。
  3. 本机共享打印机通过 WS‑Discovery,UDP3702 向外广播 Hello 报文,宣告本机设备存在,局域网其他 Windows 主机可以发现本机设备。

五、配套链(运维、故障链、等效方案、组策略)

1、运维命令

powershell
#查看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、故障链条

  1. 现象:找不到 WSD 打印机
    • 根因 1:fdPHost 未启动;
    • 根因 2:防火墙拦截 UDP3702 多播;
    • 根因 3:交换机 IGMP‑Snooping 阻断组播;跨 VLAN 无法多播发现;
    • 根因 4:打印机固件 WSD 功能关闭。
    注意:发现失败不等于不能打印;可以手动填入打印机 HTTP 地址手动添加 WSD 端口。
  2. 现象:可以发现打印机,提交打印任务失败
    • TCP5357 被防火墙拦截;wsdportmon.dll 损坏;spooler 异常。
  3. 现象: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、安全风险配套

  1. 历史漏洞:MS09‑063 WSDAPI 远程代码执行漏洞(Vista/Server2008)。
  2. 风险:UDP3702 多播不受子网隔离容易被伪造设备欺骗;公网环境绝对不能开放 5357/5358 端口,仅允许局域网专用网络配置文件放行。

6、演进备注

WSD 没有被微软标记弃用;但是企业生产环境运维普遍更推荐Standard TCP/IP 端口(TCPMON),规避多播、跨 VLAN、固件兼容性问题。

 

IPP(Internet Printing Protocol)打印机监视器组件拆解|解构|底层原理|依赖文件|依赖关系|逻辑链路|配套链

基础定位
 
IPP:Internet Printing Protocol,互联网打印协议,PWG 开放标准,基于 HTTP/HTTPS,TCP 631 端口
 
Windows 中 IPP 端口监视器:ippmon.dll,属于 Print Spooler 打印子系统的端口监视器 (Port Monitor),宿主进程:spoolsv.exe(SYSTEM 权限)。
 
区分易混淆组件:
  1. ippmon.dllIPP 端口监视器,负责网络传输、IPP‑TLV 报文、HTTP/IPPS 会话(端口监视器层)
  2. ippclass.dllMicrosoft IPP Class Driver,IPP 无驱类驱动,负责 PrintTicket 与 IPP 属性转换(驱动层)
  3. ippromon.dll:Standard TCP/IP RAW9100 端口监视器,老式 TCP 打印,不是 IPP
  4. WSD:wsdportmon.dll,DPWS/SOAP 打印;IPP 基于 HTTP,两套完全独立端口监视器。
Windows 版本边界:Win8/Server2012 开始原生内置 ippmon.dll;需要可选组件「Internet 打印客户端」;Win11 强化 IPP Everywhere、Protected Print 受保护打印模式,主推 IPP 替代 RAW、SMB 共享打印。

一、底层原理

协议栈分层

plaintext
上层应用: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 核心职责(端口监视器标准接口)

Windows 端口监视器标准接口:InitializePrintMonitor2,spoolsv 加载调用Microsoft ...
  1. 端口管理:创建、删除、配置 IPP 端口,保存 URI ipp://x.x.x.x/ipp/print / ipps://
  2. 能力查询:HTTP POST 发送Get‑Printer‑Attributes,获取打印机能力(纸张、双面、色彩、介质)
  3. 打印作业提交Print‑Job IPP 操作,把假脱机文档封装进 HTTP POST body 下发打印机
  4. 状态轮询:轮询打印机状态(缺纸、卡纸、墨粉、作业状态)回写给 spooler
  5. IPPS 加密:调用 winhttp+schannel 完成 TLS 加密通信;支持 Basic/Digest 认证
  6. mDNS 解析:解析printer.local Bonjour/mDNS 设备域名,解析为 IP 地址。
IPP 报文格式:TLV Type‑Length‑Value 二进制,嵌入 HTTP POST 请求 Body;HTTP 头承载会话,Body 是 IPP 二进制,不是 XML。
 
核心操作:Print‑JobGet‑Printer‑AttributesCancel‑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

二、依赖文件

核心二进制

  1. ippmon.dll
     
    C:\Windows\System32\ippmon.dll;SysWOW64 32 位兼容版本;KnownDLL 保护,防止 DLL 劫持。
  2. ippmon.inf:端口监视器注册 inf,路径:C:\Windows\INF\ippmon.inf
  3. ippclass.dll:IPP 类驱动,C:\Windows\System32\spool\drivers,PrintTicket‑IPP 属性映射。

传输依赖

  1. winhttp.dll:HTTP/HTTPS 会话,IPPS 加密传输核心
  2. schannel.dll / secur32.dll:TLS 握手、证书校验
  3. ws2_32.dll:Windows socket TCP 通信
  4. dnscache.dll:DNS/mDNS 域名解析

打印子系统宿主依赖

  1. spoolsv.exe Print Spooler 服务,加载 ippmon.dll 宿主进程
  2. spoolss.dll:打印路由器,spooler 内部路由
  3. winspool.drv:客户端 Win32 打印 API,应用层到 spoolsv RPC 桥梁
  4. printui.dll:rundll32 打印 UI 配置,命令行添加 IPP 打印机底层调用库。

注册表依赖

  1. 端口监视器注册位置
     
    HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\IPP Port Monitor
键值Driver = ippmon.dll;该注册表丢失,IPP 端口监视器消失,无法创建 ipp:// 端口。
  1. IPP 打印机端口实例:
     
    HKLM\SYSTEM\CurrentControlSet\Control\Print\Ports\ipp://192.168.1.100/ipp/print,保存 URI、超时、认证参数。
  2. 可选 Windows 功能:Printing‑Internet‑Print‑Client(Internet 打印客户端),缺失则 ippmon 不注册。

网络端口

端口 协议 说明
TCP 631 HTTP ipp:// 明文 IPP 通信
TCP 631 TLS ipps:// 加密 IPPS 通信
UDP 5353 mDNS Bonjour 设备发现(非 ippmon,系统 mDNS 组件)

三、依赖关系

plaintext
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)完全独立两套监视器
关键运维要点:
  1. mDNS/Bonjour 只是设备发现;IPP 打印通信本身不需要多播;跨 VLAN 无法 mDNS 发现,但手动填写 IPP URI 仍然可以打印。
  2. ippmon.dll 只做传输层;不做文档渲染转换;文档转换交给 ippclass.dll/v4 打印过滤管线。

四、完整逻辑链路

链路 A:创建 IPP 打印机端口(PowerShell / 设置添加打印机)

  1. 用户 / PowerShell Add‑PrinterPort,调用winspool.drv Win32 打印 API。
  2. RPC 到spoolsv.exe打印后台服务。
  3. spoolss 打印路由器读取注册表 HKLM\..\Print\Monitors\IPP Port Monitor,加载ippmon.dll
  4. ippmon.dll 执行端口创建逻辑,校验 IPP URI 格式 ipp://xxx/ipp/print
  5. ippmon.dll 发起 HTTP POST Get‑Printer‑Attributes到打印机 TCP631,获取打印机能力。
  6. 端口配置写入注册表 HKLM\...\Print\Ports\
  7. 绑定Microsoft IPP Class Driver(ippclass.dll)驱动,完成打印机队列创建。

链路 B:IPP 打印作业完整数据流

  1. 应用程序打印,GDI/XPS 输出,spoolsv 生成假脱机文档。
  2. spoolsv 调用对应端口监视器ippmon.dll
  3. ippmon.dll 组装 IPP Print‑Job TLV 二进制报文,封装 HTTP POST 请求。
  4. 如果是ipps://,winhttp+schannel 完成 TLS 握手、证书校验。
  5. TCP631 发送 HTTP 请求至打印机 IPP 端点。
  6. 打印机返回 IPP 响应报文;ippmon.dll 解析响应状态码,回传给 spooler。
  7. ippmon 周期性Get‑Printer‑Attributes轮询打印机状态;spooler 更新打印机面板状态(缺纸 / 墨低)。
  8. 作业完成 / 异常,spoolsv 更新打印队列状态。

链路 C:IPPS 加密打印流程

  1. URI 以ipps://开头;ippmon.dll 通知 winhttp 启用 TLS。
  2. schannel 执行 TLS 握手,校验打印机证书(可配置忽略证书校验)。
  3. IPP TLV 报文在 TLS 隧道内传输。

五、配套链(运维命令、故障链条、组策略、对比选型)

1、PowerShell 运维命令

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、故障链条

  1. 现象:找不到 IPP Port Monitor,无法创建 ipp:// 端口
    • 根因:未安装Printing‑Internet‑Print‑Client可选组件;注册表IPP Port Monitor丢失;ippmon.dll 损坏。
  2. 现象:可以创建端口,打印报错,无法下发作业
    • TCP631 防火墙拦截;打印机 IPP 服务未开启;URI 路径错误;IPPS 证书校验失败。
  3. 现象:mDNS 看不到 IPP 打印机,但是手动填写 ipp URI 可以打印
    • 问题属于mDNS/Bonjour 发现层故障,不是 ippmon.dll 本身故障;IPP 打印通信正常。
  4. 现象:打印机状态不更新
    • ippmon 轮询被超时限制;打印机拒绝Get‑Printer‑Attributes请求。

3、组策略控制点

  1. 计算机配置‑管理模板‑打印机:关闭 Internet 打印客户端,禁用 ippmon IPP 端口监视器。
  2. 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、生产最佳实践

  1. 异构混合环境(Windows/macOS/Linux)优先使用 IPP Everywhere,避开 WSD 多播限制。
  2. 跨 VLAN 环境:mDNS 发现失效,手动填写 ipp://URI 即可正常打印,IPP 打印本身不依赖组播。
  3. 安全优先场景使用ipps://加密;注意打印机证书管理。
  4. Windows 受保护打印模式 WPP,强制使用 IPP 栈,提升打印子系统安全,规避老旧 v3 驱动漏洞风险Microsoft ...

1、如何在 Windows 系统中使用 WSD 协议?

WSD(Web Services on Devices)用于局域网发现 WSD 打印机 / 扫描仪,分为客户端(发现外部设备)服务端(发布本机设备)

使用前提条件

  1. 网络配置文件:网卡网络配置文件必须为专用 / 专用网络公用网络会直接阻止 WSD 多播发现
  2. 打印机设备侧:打印机固件开启 WSD/DPWS 功能。
  3. Windows 服务:fdPHost必须运行;打印需要Spooler
  4. 防火墙放行:UDP3702,TCP5357、TCP5358。

操作步骤‑自动发现添加 WSD 打印机

  1. 确认打印机与电脑在同一个子网 VLAN(WSD 发现依赖 UDP 组播,跨 VLAN 默认无法自动发现)。
  2. 开启服务
powershell
Start‑Service fdPHost ‑ErrorAction SilentlyContinue
Start‑Service Spooler ‑ErrorAction SilentlyContinue
  1. 打开:control.exe /name Microsoft.DevicesAndPrinters → 添加设备,Windows 会通过 WS‑Discovery 多播探测局域网 WSD 设备。
  2. 在列表选中发现的 WSD 打印机,下一步完成安装;系统自动加载wsdportmon.dllWSD 端口监视器。

跨 VLAN(无法自动发现):手动指定 URL 添加 WSD 打印机

  1. 打印机 Web 管理页面获取 WSD 设备 URL,格式示例:
     
    http://192.168.1.100:5357/wprt/printer
  2. 设置 → 蓝牙和设备 → 添加设备 → 我需要的设备不在列表中 → 使用 TCP/IP 地址或主机名添加打印机
  3. 设备类型选择:Web 服务设备 (WSD),填入打印机 IP,系统自动解析 WSD 端点完成安装。
注意:就算无法自动发现,只要 TCP 连通 5357 端口,手动填入 IP 就可以使用 WSD 打印。

2、如何在不重启的情况下更新计算机名?

Windows 内核中ActiveComputerName(hostname 读取的运行时 NetBIOS 主机名)没有官方不重启修改全局内核变量的方法
  1. Rename‑Computer / SetComputerNameExW API 只写入磁盘注册表,不会改写内核内存
  • 修改后:注册表是新名称;hostname.exe$env:COMPUTERNAME、SMB、Netlogon 域安全通道、WSD 设备宣告全部沿用旧名称。
  • 必须操作系统重启,smss.exe 重新加载注册表,内核才刷新ActiveComputerName

局部临时生效(非全局,仅部分组件)

  1. DNS 主机名:修改HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Hostname,重启网卡服务,TCP/IP 栈 DNS 主机名更新;NetBIOS 内核名称不变
  2. 当前会话伪装:$env:COMPUTERNAME="NEW‑NAME"仅当前 PowerShell/CMD 会话生效,其他进程、系统服务全部还是旧主机名
⚠️网上第三方工具直接改写内核内存ActiveComputerName,属于未文档化非官方手段;会破坏 AD 域安全通道、SMB、WSD、WMI,域环境严禁使用。
##3、如何在 Windows 系统中配置 WSD 服务?

WSD 涉及两个核心服务

服务名称 显示名称 作用 启动类型建议
fdPHost Function Discovery Provider Host 客户端:发现局域网外部 WSD 打印机 / 扫描仪 手动 (延迟启动)
FDResPub Function Discovery Resource Publication 服务端:把本机共享打印机对外广播给局域网其他电脑 手动

PowerShell 配置 WSD 服务

powershell
# 设置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 依赖 Windows 防火墙【专用】网络配置文件;公用网络直接阻断 WSD。
powershell
#启用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 事件订阅

组策略配置(域环境批量管控)

计算机配置 → 管理模板 → 网络 → 功能发现
  1. 关闭功能发现的网络发现:启用 → fdPHost/WSD 设备发现全部失效;不启用则允许 WSD 发现。
  2. 关闭功能发现资源发布:启用 → FDResPub 停止,本机设备不会对外广播 WSD Hello 报文。

修复 WSD 端口监视器(WSD 打印端口丢失故障)

powershell
#重新注册WSD端口监视器
pnputil /add‑driver "$env:windir\System32\spool\monitors\wsdportmon.inf"
Restart‑Service Spooler

关键注意点

  1. WSD 发现依靠 UDP 组播,跨 VLAN 无法自动发现,只能手动填写 IP 添加 WSD 设备。
  2. 仅开启 fdPHost 就可以发现外部打印机;FDResPub 只用于对外发布本机设备,普通办公客户端不需要开启。
  3. 公用网络配置文件,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 协议?

见上一轮完整内容,简要复盘:
  1. 网络配置文件设置为专用网络;公用网络防火墙阻断 WSD。
  2. 开启服务:fdPHost(发现外部 WSD 设备)、Spooler打印后台;如需对外发布本机设备开启FDResPub
  3. 防火墙放行规则:UDP3702,TCP5357、TCP5358。
  4. 同子网:控制面板「设备和打印机」直接自动发现 WSD 打印机;
  5. 跨 VLAN:无法组播发现,手动填写打印机 WSD HTTP URL 添加 Web 服务设备。

2、如何在 Linux 系统中使用 WSD (DPWS) 协议?

Linux无操作系统内置原生 DPWS/WSD 协议栈

现状

CUPS 打印系统本身不原生支持 WSD/DPWS 打印机,不能直接发现 WSD 设备。
 
两种可行方案:

方案 A:绕过 WSD,直接使用打印机底层服务(生产推荐)

绝大多数 WSD 打印机同时还提供:
  • RAW Socket 9100 端口
  • IPP 631 端口
Linux CUPS 直接添加 Socket://ip:9100 或者 ipp://ip:631完全避开 WSD 协议,稳定性最好。

方案 B:使用第三方 DPWS 开源组件,实现 WSD 发现与通信

  1. gSOAP:实现 DPWS 标准的 C 库,可以开发 DPWS 客户端 / 服务端;无开箱即用工具,需要二次开发。
  2. wsdd(WS‑Discovery Daemon)
项目:wsdd,仅实现 WS‑Discovery 发现协议(UDP3702)
 
✅ 可以在 Linux 上发出 Probe 报文,局域网探测 WSD 设备,拿到设备 XAddrs (WSD http 地址)
 
wsdd 只做设备发现,不实现完整 WSD 打印 SOAP 业务;拿到 URL 后 CUPS 仍然不能直接打印

wsdd 部署示例(Debian/Ubuntu)

bash
apt install wsdd
systemctl enable --now wsdd
# 抓包验证UDP3702多播探测
tcpdump -i eth0 udp port 3702
执行后可以扫描局域网 WSD 设备,获取设备 http 端点;但 CUPS 无法直接利用该端点打印

小结 Linux

  1. 仅做设备发现:部署wsdd
  2. 打印业务:不建议走 WSD,优先 IPP/RAW9100
  3. 如果必须完整 DPWS/WSD 打印,需要基于 gSOAP 自行开发客户端。

##3、如何在 macOS 系统中使用 WSD 协议?
 
macOS没有原生 WSD/DPWS 协议栈,系统打印子系统不支持 WSD 打印机。

现状

macOS 打印栈原生支持:AirPrint (mDNS)、IPP、Socket RAW9100、LPD;不支持 WSD

方案

  1. 优先绕过 WSD 协议(推荐)
     
    WSD 打印机几乎全部同时支持 IPP/AirPrint,macOS 直接通过 AirPrint 发现打印机,或者手动填写 IP 使用 IPP/Socket 打印,完全避开 WSD。
  2. 想要在 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)。
 
两大角色:
  1. 客户端模式(wsdd‑c):发送 Probe 多播,发现局域网 WSD/DPWS 设备(WSD 打印机)。
  2. 服务端模式(wsdd):对外发布本机服务,让 Windows 主机可以发现 Linux 主机上的 CUPS 打印机(模拟 Windows FDResPub 的行为)。
重要边界:wsdd 只实现 WS‑Discovery 发现子协议,不实现完整 DPWS/WSD SOAP 业务层
 
✔ 能发现设备、广播设备存在;
 
不能完成 WSD 打印、解析 WSDL、提交 SOAP 打印任务。CUPS 仍然不能直接使用 WSD 端点打印。
项目仓库:https://github.com/christoph2/wsdd
 
语言:Python3

一、底层原理

协议栈

plaintext
应用层:wsdd python业务逻辑
表示层:SOAP‑Envelope 精简SOAP报文(仅WS‑Discovery消息:Hello / Bye / Probe / ProbeMatches / Resolve)
传输层:UDP 3702
网络层:IPv4多播地址 239.255.255.250;支持IPv6多播

WS‑Discovery 核心报文

  1. Probe:客户端 wsdd‑c 向多播组发送探测,查询设备类型,例如打印设备 wprt:PrintDevice
  2. ProbeMatches:设备单播回复,返回设备 UUID、XAddrs(WSD HTTP 访问地址)
  3. Hello:服务端 wsdd 启动,向多播组宣告本机设备上线
  4. Bye:服务端退出,发送报文宣告设备离线
wsdd不实现:WS‑Eventing、WSDL 元数据获取、SOAP 打印业务,这些属于上层 DPWS,需要 gSOAP 等完整栈。

两种运行模式

  1. 客户端模式 wsdd -c / wsdd‑c
     
    监听 + 发送 UDP3702 多播,发送 Probe,收集局域网 DPWS/WSD 设备,输出设备 UUID、XAddrs、设备类型。
仅做扫描发现,不做打印
  1. 服务端模式(默认直接运行 wsdd)
     
    读取 CUPS 打印机列表,组装 WS‑Discovery Hello 报文,UDP3702 多播广播;Windows 主机 fdPHost 收到 Hello 报文,就会在「设备和打印机」看到这台 Linux CUPS 打印机。
⚠️ Windows 只是发现看到图标;实际打印不走 WSD,Windows 内部会回退使用 IPP 和 CUPS 通信。

二、依赖文件

基于 Debian/Ubuntu 打包版本(apt install wsdd
  1. 主程序:/usr/bin/wsdd(Python3 脚本)
  2. systemd 单元:/lib/systemd/system/wsdd.service
  3. 配置目录:/etc/wsdd/,可选配置 config
  4. PID 文件:/run/wsdd.pid
  5. 日志输出:syslog/journald

软件依赖

  • python3(运行时)
  • python3‑netifaces:网卡枚举,获取本机网卡、IP、多播支持
  • python3‑lxml:生成 / 解析 SOAP‑XML WS‑Discovery 报文
  • cups‑client(服务端模式需要,读取本机 CUPS 打印机列表)
无内核模块;纯用户空间 Python 应用,基于系统 socket API。

三、依赖关系

plaintext
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 设备

  1. wsdd‑c 启动,读取本机网卡列表,跳过 lo 回环。
  2. UDP socket 创建,加入多播组 239.255.255.250:3702
  3. 构造 SOAP‑XML Probe报文,查询打印设备类型 wprt:PrintDevice
  4. UDP 发送多播 Probe 到局域网。
  5. 局域网 WSD 打印机收到 Probe,单播回复ProbeMatches
  6. wsdd‑c 使用 lxml 解析返回 XML,提取:设备 UUID、XAddrs (WSD http 地址)、设备类型。
  7. 控制台输出设备清单;程序退出。
到此为止,只拿到 WSD URL;没有后续 WSDL、SOAP 打印交互。

链路 B:服务端模式 wsdd(把 Linux CUPS 打印机广播给 Windows)

  1. wsdd 服务启动,systemd 调用 /usr/bin/wsdd。
  2. 枚举本机网卡,加入 UDP 多播组 239.255.255.250:3702。
  3. 调用 cups 客户端接口,读取本机 CUPS 所有打印机。
  4. 为每台 CUPS 打印机生成 DPWS 设备 UUID,组装 WS‑Discovery Hello SOAP 报文。
  5. UDP 多播向外发送 Hello 报文,携带 XAddrs 指向本机 CUPS IPP 地址。
  6. Windows 主机 fdPHost(WSDAPI)收到 Hello 报文。
  7. Windows「设备和打印机」出现该 Linux 打印机图标。
Windows只是通过 WS‑Discovery 发现;实际打印通信走 IPP,不走 WSD SOAP。
  1. wsdd 监听 UDP 3702,收到 Windows 发来的 Probe 探测报文,回复 ProbeMatches。
  2. wsdd 进程退出时,发送 Bye 报文,宣告设备离线。

五、配套链(运维、故障、配置、限制)

1、常用运维命令

bash
# 查看状态
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)

bash
#放行UDP3702入站出站
ufw allow proto udp from any to any port 3702

3、配置文件 /etc/wsdd/config

ini
#指定网卡,多网卡服务器常用
INTERFACES="eth0"
#是否发布cups打印机
CUPS=true

4、故障链条

  1. 现象:wsdd‑c 扫描不到局域网 WSD 打印机
    • 根因 1:防火墙拦截 UDP3702;
    • 根因 2:交换机 IGMP‑Snooping 丢弃多播报文;
    • 根因 3:网卡未加入多播组;
    • 根因 4:跨 VLAN,组播无法跨三层。
  2. 现象:Windows 看不到 Linux 发布的 CUPS 打印机
    • wsdd 服务未运行;cups 未运行;防火墙 UDP3702 拦截;
    • Windows 主机网络配置文件为公用网络,fdPHost 防火墙阻断 WSD 发现报文。
  3. 认知误区:
❌:跑了 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、同类组件对比

  1. wsdd:轻量 Python,只做 WS‑Discovery;适合异构环境设备发现。
  2. gSOAP:完整 DPWS 协议栈 C 库;可实现完整 WSD 客户端 / 服务端;需要开发,无现成工具。
  3. Windows wsdapi.dll:微软完整 DPWS 实现,包含 WS‑Discovery + WSDL + SOAP 打印业务。

7、生产环境最佳实践

  1. Linux 客户端要使用 WSD 打印机:不要依赖 wsdd 做打印;wsdd‑c 仅用于扫描获取 IP,CUPS 添加 IPP/Socket (9100)。
  2. Linux 服务器共享打印机给 Windows:启用 wsdd 服务端模式,Windows 可以自动发现;实际打印走 IPP。
  3. 跨 VLAN 环境:WS‑Discovery 多播失效,wsdd 无法跨三层发现设备,必须手动填写 IP。
 

 

基于 PowerShell 的 .ps1 批处理文件需求开发文档,用于安装网络打印机,并根据输入的 IP 地址自动添加打印机。假设驱动已经预安装好。


需求开发文档:使用 PowerShell 安装网络打印机

1. 目标

开发一个 PowerShell 脚本 .ps1,用于在 Windows 系统上安装网络打印机。该脚本将:

  • 自动根据输入的 IP 地址配置并添加网络打印机。
  • 确保驱动程序已安装,并且打印机通过 TCP/IP 协议进行连接。

2. 需求

  • 打印机驱动程序已经在系统中预先安装。
  • 用户可以通过输入打印机的 IP 地址来安装打印机。
  • 打印机将通过 TCP/IP 协议连接到网络。

3. 功能描述

PowerShell 脚本将执行以下任务:

  1. 提示用户输入网络打印机的 IP 地址。
  2. 检查并确保打印机驱动程序已经安装。
  3. 使用 PowerShell 命令将网络打印机添加到系统中。

4. 方案设计

  • 使用 PowerShell cmdlet 添加打印机。
  • Add-PrinterPort 用于创建打印机端口。
  • Add-Printer 用于将打印机添加到系统。

5. 安装步骤及命令说明

步骤 1: 准备工作
  • 确保打印机驱动已经安装且可用。
  • 确保打印机的 IP 地址正确。
步骤 2: 编写 PowerShell 脚本

以下是使用 PowerShell 添加网络打印机的脚本示例:

powershellCopy Code
# 提示用户输入打印机的 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 脚本说明
  1. 输入打印机 IP 地址

    • 使用 Read-Host 提示用户输入打印机的 IP 地址。
  2. 创建打印机端口

    • 使用 Add-PrinterPort 命令来创建基于 IP 地址的 TCP/IP 打印机端口。
    • 使用 Get-WmiObject 检查端口是否已经存在,如果不存在则创建。
  3. 检查打印机驱动程序

    • 使用 Get-WmiObject 检查系统中是否安装了所需的打印机驱动程序。
  4. 安装网络打印机

    • 使用 Add-Printer 命令将打印机添加到系统中。
  5. 设置默认打印机

    • 使用 Set-Printer 设置该打印机为默认打印机。
步骤 4: 文件保存与执行
  1. 将脚本保存为 .ps1 文件,例如 install_network_printer.ps1
  2. 通过 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. 功能描述

批处理文件的功能包括:

  1. 通过 IP 地址添加打印机:根据用户输入的打印机 IP 地址,自动将打印机添加到系统。
  2. 命令行自动配置:使用命令行将打印机与操作系统连接并确保能够正常打印。

4. 方案设计

使用 Windows 提供的命令行工具进行操作:

  • rundll32:用于调用 Windows API 管理打印机。
  • printui.dll:用于打印机管理。
  • net use:用于映射共享打印机(如果是共享网络打印机)。

5. 安装步骤及命令说明

步骤 1: 准备工作
  • 打印机驱动已安装并准备好。
  • 确保打印机的 IP 地址和打印机名称正确。
步骤 2: 批处理命令编写
  1. 添加网络打印机

    • 假设打印机的 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":指定驱动的打印机型号。
  2. 添加共享网络打印机(如果适用) 如果您要添加的是共享打印机,您可以使用以下命令:

    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 打印机已连接并设置为默认打印机
    pause
    • net use \\%PrinterIP%\PrinterName:映射共享打印机。
    • rundll32 printui.dll,PrintUIEntry /y /n "\\%PrinterIP%\PrinterName":将共享打印机设置为默认打印机。
  3. 设置打印机为默认打印机 若需要将已安装的打印机设置为默认打印机,可以使用以下命令:

    Copy Code
    rundll32 printui.dll,PrintUIEntry /y /n "NetworkPrinter"
步骤 3: 批处理文件说明
  • 该批处理文件将提示用户输入打印机的 IP 地址,并根据该地址添加网络打印机。
  • 批处理文件会将指定的打印机设置为默认打印机。
  • printui.dll 和 net use 命令会确保打印机正确添加并能被系统识别。
步骤 4: 文件保存与执行
  1. 将上述内容保存为 .cmd 文件,例如 install_network_printer.cmd
  2. 双击执行该批处理文件,根据提示输入打印机的 IP 地址即可自动安装网络打印机。

6. 错误处理

  • 如果输入的 IP 地址无法连接,批处理文件将显示错误信息,并要求重新输入。
  • 如果驱动程序文件路径错误,系统会提示找不到驱动并退出。

7. 测试

  • 在多台机器上测试批处理文件,确保能根据 IP 地址正确安装并设置打印机。

通过以上的批处理命令,可以在 Windows 系统上自动添加网络打印机,并通过 IP 地址指定连接的打印机。该批处理文件简化了打印机安装的步骤,特别适用于预安装驱动的情况。


 


基于 VBScript 的网络打印机安装需求开发文档,适用于在驱动程序已预安装的情况下,手动添加打印机并通过输入 IP 地址进行配置和安装。


需求开发文档:使用 VBScript 安装网络打印机

1. 目标

开发一个 VBScript 脚本,用于在 Windows 系统上安装网络打印机。该脚本将:

  • 提示用户输入打印机的 IP 地址。
  • 安装打印机并配置打印机端口。
  • 假设打印机驱动程序已经预安装。

2. 需求

  • 打印机驱动程序已预安装。
  • 用户手动输入打印机的 IP 地址,脚本根据输入的 IP 地址配置和安装打印机。

3. 功能描述

VBScript 脚本将执行以下任务:

  1. 提示用户输入网络打印机的 IP 地址。
  2. 创建 TCP/IP 打印机端口。
  3. 将打印机添加到系统。
  4. 将安装的打印机设置为默认打印机。

4. 方案设计

  • 使用 WScript.Network 对象来操作打印机安装。
  • 使用 AddPrinterConnection 方法将打印机添加到系统。
  • 使用 AddPrinterPort 方法创建打印机端口。
  • 提供用户输入 IP 地址的界面。

5. 安装步骤及命令说明

步骤 1: 准备工作
  • 确保打印机驱动程序已在系统中预安装。
  • 确保网络中打印机的 IP 地址是正确的,并且打印机已连接到网络。
步骤 2: 编写 VBScript 脚本

以下是 VBScript 脚本示例:

vbscriptCopy Code
' 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 脚本说明
  1. 输入打印机 IP 地址

    • 使用 InputBox 提示用户输入打印机的 IP 地址。如果用户没有输入 IP 地址,则退出脚本。
  2. 创建打印机端口

    • 通过 WMI(Windows Management Instrumentation)查询当前系统中是否已经存在该 IP 地址的打印机端口。
    • 如果端口不存在,则使用 Win32_TCPIPPrinterPort 创建新的 TCP/IP 打印机端口。
  3. 添加打印机

    • 使用 WScript.Network 对象的 AddPrinterConnection 方法将网络打印机添加到系统中。
    • 使用 SetDefaultPrinter 设置新添加的打印机为默认打印机。
  4. 错误处理

    • 如果 IP 地址无效或用户未输入,则弹出提示框并退出脚本。
    • 如果端口已经存在,脚本会跳过创建端口的步骤。
步骤 4: 文件保存与执行
  1. 将上述脚本保存为 .vbs 文件,例如 install_network_printer.vbs
  2. 通过 Windows 系统上的 脚本执行 运行该文件:
    • 双击 install_network_printer.vbs 文件即可运行。

6. 错误处理

  • 如果用户输入的 IP 地址无效或不可访问,脚本将显示错误提示并终止操作。
  • 如果打印机驱动程序未正确安装,脚本将无法添加打印机。此时需要检查驱动程序安装情况。
  • 如果端口已存在,脚本会跳过创建端口的步骤。

7. 测试

在多台机器上测试该 VBScript,确保能够通过 IP 地址成功安装并配置网络打印机。

通过这个 VBScript 脚本,可以简化网络打印机的安装过程,用户只需输入打印机的 IP 地址,脚本将自动安装并配置网络打印机。此脚本假设驱动程序已预安装在系统中,能够确保网络打印机的自动安装与设置。

posted @ 2025-03-27 01:48  suv789  阅读(909)  评论(0)    收藏  举报