USB 双向扩展程序

重要

建议使用 Microsoft 的 IPP 收件箱类驱动程序以及打印支持应用 (PSA) ,自定义 Windows 10 和 11 中的打印体验,以便进行打印机设备开发。

有关详细信息,请参阅 打印支持应用设计指南

Windows 允许制造商使用双向通信, (Bidi) 支持 USB 设备的双向通信,方法是结合使用 Bidi XML 文件和称为 USB Bidi 扩展器的 Javascript 文件。

USB Bidi 扩展器允许应用程序使用带有 USB 的 Bidi 作为传输机制。 Javascript 实现不支持任何设备流控制,也不支持在打印过程中使用打印作业对控制信息进行任何多路复用。

默认情况下,Bidi 查询和状态请求通过用于打印的 USB 设备接口进行路由。 这允许使用 getSchemas JavaScript 方法对状态进行完全双向通信,并允许使用 setSchema JavaScript 方法执行 Set 操作。 在没有将打印作业发送到打印设备时,可以实现完全双向通信。

在打印期间,打印作业数据会阻止写入,因此 getStatus 方法用于仅使用读取通道从设备获取未经请求的状态。 但是,如果设备支持辅助 USB 接口,则 requestStatus 方法函数用于在设备打印时从打印机获取状态。

在Windows 8.1 v4 驱动程序模型已扩展,以提供对基于主机的设备的支持。 此外,USBMon 已更新,允许 IHV 使用 JavaScript 代码更好地控制打印路径并执行基于打印作业的操作。 此更新包括添加提供新 Bidi JavaScript 入口点的 API。 这些 API 与 USBMon 中的现有函数保持一致。

startPrintJob。 此新函数与 USBMon 中的 startDocPort 保持一致。 当每个新的 USB 打印作业在连接到Host-Based打印设备的端口上启动时,USBMon 将调用 IHV 提供的 JavaScript,以允许它执行所需的任何作业前处理。 这可能包括在作业属性包中设置作业全局属性、查询设备以获取当前状态和配置数据,或者查询任何内容。 完成的任务完全依赖于设备和 IHV。

writePrintData。 此新函数与 USBMon 中的 writePort 保持一致。 当 USBMon 在打印过程中从后台处理程序接收每个 writePort 函数调用时,需要通过 IHV JavaScript 函数将提供的打印数据发送到基于主机的设备。 这允许 IHV JS 决定此时应发送到设备的内容。 IHV 可以根据需要删除、添加或保存部分数据缓冲区。 这允许 IHV 完全控制何时发送到设备的内容。 这样,IHV 就有机会在打印作业的偶数页中保存一个永久性流) 中的 (,以便在从后台处理程序收到所有数据后进行处理,从而启用手动双工等方案。 IHV 还可以使用 printerBidiSchemaResponses 对象在作业处理期间返回打印作业状态或设备状态。

endPrintJob。 此新函数与 USBMon 中的 endDocPort 保持一致。 当 USBMon 在连接到Host-Based打印设备的端口上收到每个 USB 打印作业的 endDocPort 调用时,USBMon 将调用 IHV 提供的 JavaScript,以允许它执行所需的任何作业后处理。 这可能包括将任何保留的数据发送到设备,返回 Bidi 架构值以启动手动双工或 IHV/设备所需的任何其他内容。

下图概述了 USB Bidi 扩展体系结构,显示了使用 getStatus 方法通过 USBPrint 接口从设备获取未经请求的状态的方案。

使用 getstatus 方法的 usb bidi 扩展器体系结构。

有关使用 USB 打印机的详细信息,请参阅 USB 打印

USB Bidi 扩展程序 API 参考

USB Bidi 扩展器中的 JavaScript 代码使用以下函数与打印设备通信:

  • getSchemas

  • setSchema

  • getStatus

  • requestStatus

  • startPrintJob

  • writePrintData

  • endPrintJob

有关这些 API 的详细信息,请参阅 JavaScript API 参考

USBMon Bidi 扩展 XML 架构

USBMon Bidi Extension 文件使用与 SNMP Bidi Extension 文件和 WSDMon Bidi Extension 文件相同的基本结构。 XML 架构文件在 Windows 驱动程序工具包中发布,USBMon Bidi 扩展文件将在 INFGate WHCK 测试期间自动进行架构验证。 开发 Bidi 扩展架构并使用 USB 总线时,请务必注意以下信息:

  • 值可以指定 Get、Set 或 GetSet 的 accessType。 这指示在 Bidi Get 或 Set 操作类型中支持所描述的架构元素的位置。

  • 值可以指定 queryKey。 这应该用于表示用于从设备获取数据的物理操作。 打印驱动程序 USB 监视器和 Bidi 示例演示了支持两个不同的 queryKey 的 USB 设备。 同一 queryKey 下的所有属性都应可在一个 USB 读/写操作中检索。

  • 如果在 Bidi API 调用中请求了 Bidi 值,则会立即轮询它们。 refreshInterval 值是初始值,指示何时轮询设备,以获取特定 Bidi 架构值的更新。 每次轮询后,refreshInterval 都会增加,直到我们停止轮询。 以下公式显示 refreshInterval 是如何递增的:

    currentRefreshInterval = refreshInterval * (3 * numPolls);
    

USBMon 和 USB Bidi 扩展文件交互

创建或打开每个新 USB 端口时,USBMon 将确定附加设备和关联的驱动程序是否包含新的 Bidi 扩展文件和 Bidi 扩展 JavaScript 文件。 USBMon 搜索 v4 驱动程序清单或驱动程序 INI 文件,并检索文件的名称。 如果 USBMon 找到相关文件,它将使用这些文件来确定此设备支持的扩展 Bidi 架构值的列表,然后与设备通信以查询其值。 此时,USBMon 通过现有的打印后台处理程序 API 支持 IHV 指定的 Bidi 架构操作。

GitHub 上的 Windows 驱动程序示例

USBMon Bidi XML 文件示例 - 此文件提供 USBMon Bidi 扩展 XML 文件的示例。 它使用标准 Bidi 架构属性 DeviceInfo、Configuration 和 Memory,还定义了一些自定义扩展。 有关详细信息,请参阅 打印驱动程序 USB 监视器和 Bidi 示例

有关 Bidi 扩展文件的详细信息,请参阅 双向通信架构

USBMon Bidi JavaScript 文件示例。 此示例包含 USBMon Bidi Extender JavaScript 文件。 它演示了如何支持 Bidi SET 和 GET 操作,以及如何在打印机打印时侦听事件。 有关详细信息,请参阅 打印驱动程序 USB 监视器和 Bidi 示例

调试

可以通过创建以下注册表项来启用交互式调试。 对于 USB Bidi JavaScript,必须重启打印后台处理程序,然后才能启用调试。

密钥名称: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print

值名称: EnableJavaScriptDebugging

类型: Dword

值: 1

创建上一部分所示的注册表项并重启托管进程后,可以按如下所示调试脚本:

  1. 将调试器附加到托管进程。 对于 USB Bidi JavaScript,这是spoolsv.exe。

  2. 将调试器设置为脚本调试模式。

  3. 选择“ 全部中断 ” (Ctrl + Alt + 中断) ,以在下次运行脚本时中断进程。

  4. 运行方案以重现问题。

  5. 调试器进入 JavaScript 函数后,设置任何必要的断点并单步执行代码。

双向通信架构

IPrinterBidiSchemaElement

IPrinterScriptContext

IPrinterScriptableSequentialStream

JavaScript API 参考

打印驱动程序 USB 监视器和 Bidi 示例

USB 打印

V4 打印机驱动程序连接