在一个项目中,我尝试使用Chrome中提供的WebUSB API来使用Zebra LP2844打印机进行打印。
我在没有问题的情况下成功完成了OSX,最终在Ubuntu和ChromeOS上取得了成功,感谢this post谈到解除内核驱动程序的绑定,以便Chrome能够访问该设备。
我正在使用的页面通过 https 提供,因为文档需要它。
在Windows 10上,我可以使用navigator.usb.requestDevice连接到打印机,如下所示
但是当我在打印例程期间在连接的打印机上调用open()时,我不断收到下一个错误
错误 DOMException:访问被拒绝。
这是打印方法代码:
print : async function(printString) {
let startTime = new Date().getTime();
if (!this.pairedPrinter) {
console.log("No printer connected");
return;
}
try {
if (!this.pairedPrinter.opened) {
await this.pairedPrinter.open();
}
await this.pairedPrinter.claimInterface(0);
let encoder = new TextEncoder();
const printBuffer = encoder.encode(printString);
let printResult = await this.pairedPrinter.transferOut(6, printBuffer);
await this.pairedPrinter.releaseInterface(0);
await this.pairedPrinter.close();
} catch (err) {
console.log("Error");
console.log(err);
} finally {
let endTime = new Date().getTime();
let printTime = endTime - startTime;
console.log("Print time: " + printTime + " ms");
}
}
我发现了类似的问题here,指向this other answer。当我插入打印机时,Windows安装的默认驱动程序阻止Chrome访问它(就像Ubuntu一样),这是完全合理的。
因此,我将自定义.inf文件实现为described here。
这是我的inf文件
;
;
; Installs WinUsb
;
; =================== Strings ===================
[Strings]
ManufacturerName = "Zebra"
ClassName = "Universal Serial Bus devices"
DeviceName = "Aeropost Zebra LP2844"
SourceName = "Aeropost Zebra LP2844 Install Disk"
DeviceID = "VID_0A5F&PID_0009"
DeviceGUID = "{c3bd2e26-7e03-4189-8c9d-852faf628494}"
REG_MULTI_SZ = 0x00010000
[Version]
Signature = "$Windows NT$"
Class = Printer
ClassGuid = {4d36e979-e325-11ce-bfc1-08002be10318}
Provider = %ManufacturerName%
CatalogFile = zebrawinusb.cat
DriverVer = 03/02/2018,1.0.0.0
; ========== Class definition ===========
[ClassInstall32]
AddReg = ClassInstall_AddReg
[ClassInstall_AddReg]
HKR,,,0,"Universal Serial Bus devices"
HKR,,Icon,,-20
; ========== Manufacturer/Models sections ===========
[Manufacturer]
%ManufacturerName% = Standard,NTx86
%ManufacturerName% = Standard,NTamd64
[Standard.NTx86]
%DeviceName% = USB_Install, USB\%DeviceID%
[Standard.NTamd64]
%DeviceName% = USB_Install, USB\%DeviceID%
; =================== Installation ===================
[USB_Install]
Include = winusb.inf
Needs = WINUSB.NT
[USB_Install.Services]
Include = winusb.inf
Needs = WINUSB.NT.Services
[USB_Install.Wdf]
KmdfService = WINUSB, WinUsb_Install
[WinUSB_Install]
KmdfLibraryVersion = 1.11
[USB_Install.HW]
AddReg=Dev_AddReg
[Dev_AddReg]
HKR,,DeviceInterfaceGUIDs,0x10000,%DeviceGUID%
[USB_Install.CoInstallers]
AddReg = CoInstallers_AddReg
CopyFiles = CoInstallers_CopyFiles
[CoInstallers_AddReg]
HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01011.dll,WdfCoInstaller","WinUsbCoInstaller2.dll"
[CoInstallers_CopyFiles]
WinUsbCoInstaller2.dll
WdfCoInstaller01011.dll
[DestinationDirs]
; If your INF needs to copy files, you must not use the DefaultDestDir directive here.
CoInstallers_CopyFiles=11
; ================= Source Media Section =====================
[SourceDisksNames]
1 = %SourceName%
[SourceDisksFiles.x86]
WinUSBCoInstaller2.dll = 1,x86
WdfCoInstaller01011.dll = 1,x86
[SourceDisksFiles.x64]
WinUSBCoInstaller2.dll = 1,x64
WdfCoInstaller01011.dll = 1,x64
使用inf2cat构建驱动程序,对其进行测试签名,当我尝试更新打印机驱动程序以使用它时,它失败并显示错误&#34;找不到指定的文件(0x00000002)&#34;。< / p>
setupapi.dev.log文件未提供有关未找到哪个文件的任何信息。
这是驱动程序更新过程的日志文件:
>>> [Device Install (DiShowUpdateDevice) - USBPRINT\ZEBRA_LP2844_\6&3295E28F&3&USB001]
>>> Section start 2018/03/02 16:14:00.023
cmd: "C:\WINDOWS\system32\mmc.exe" C:\WINDOWS\system32\devmgmt.msc
dvi: {DIF_UPDATEDRIVER_UI} 16:14:00.023
dvi: Class installer: Enter 16:14:00.023
dvi: Class installer: Exit
dvi: Default installer: Enter 16:14:00.039
dvi: Default installer: Exit
dvi: {DIF_UPDATEDRIVER_UI - exit(0xe000020e)} 16:14:00.054
ndv: {Update Driver Software Wizard - USBPRINT\ZEBRA_LP2844_\6&3295E28F&3&USB001}
dvi: {DIF_SELECTDEVICE} 16:14:05.662
dvi: Class installer: Enter 16:14:05.678
dvi: Class installer: Exit
dvi: {DIF_SELECTDEVICE - exit(0xe000020e)} 16:14:05.678
dvi: {DIF_SELECTDEVICE} 16:14:12.148
dvi: Class installer: Enter 16:14:12.148
dvi: Class installer: Exit
dvi: {DIF_SELECTDEVICE - exit(0xe000020e)} 16:14:12.163
ndv: Driver package 'C:\WINDOWS\System32\DriverStore\FileRepository\zebrawinusb.inf_amd64_ddcc3ed00fd3e8a8\zebrawinusb.inf' is already imported.
sto: {Setup Import Driver Package: c:\zebrawinusbdriver\zebrawinusb.inf} 16:14:16.158
sto: Driver package already imported as 'oem20.inf'.
sto: {Setup Import Driver Package - exit (0x00000000)} 16:14:16.180
dvi: Searching for hardware ID(s):
dvi: usbprint\zebra_lp2844_5bc4
dvi: zebra_lp2844_5bc4
dvi: Class GUID of device remains: {4d36e979-e325-11ce-bfc1-08002be10318}.
dvi: {Plug and Play Service: Device Install for USBPRINT\ZEBRA_LP2844_\6&3295E28F&3&USB001}
dvi: Driver INF Path: C:\WINDOWS\INF\oem20.inf
dvi: Driver Node Name: zebrawinusb.inf:c14ce8840c48fa1f:USB_Install:1.0.0.0:usb\vid_0a5f&pid_0009,
dvi: Driver Store Path: C:\WINDOWS\System32\DriverStore\FileRepository\zebrawinusb.inf_amd64_ddcc3ed00fd3e8a8\zebrawinusb.inf
dvi: Searching for hardware ID(s):
dvi: usbprint\zebra_lp2844_5bc4
dvi: zebra_lp2844_5bc4
dvi: Class GUID of device changed to: {4d36e979-e325-11ce-bfc1-08002be10318}.
dvi: {Core Device Install} 16:14:16.313
! pol: Selected driver node does not match this device (force-install)
dvi: {Install Device - USBPRINT\ZEBRA_LP2844_\6&3295E28F&3&USB001} 16:14:16.316
dvi: Device Status: 0x0180200a, Problem: 0x0 (0x00000000)
dvi: Parent device: USB\VID_0A5F&PID_0009\42J113802152
! dvi: Unable to determine matching device ID for oem20.inf. Error = 0xE0000228
! dvi: Unable to configure device, falling back to standard device installation.
dvi: {DIF_ALLOW_INSTALL} 16:14:16.324
dvi: Using exported function 'ClassInstall32' in module 'C:\WINDOWS\system32\ntprint.dll'.
dvi: Class installer == ntprint.dll,ClassInstall32
dvi: Class installer: Enter 16:14:16.336
dvi: Class installer: Exit
dvi: Default installer: Enter 16:14:16.340
dvi: Default installer: Exit
dvi: {DIF_ALLOW_INSTALL - exit(0xe000020e)} 16:14:16.342
dvi: {DIF_INSTALLDEVICEFILES} 16:14:16.343
dvi: Class installer: Enter 16:14:16.344
!!! dvi: Class installer: failed(0x00000002)!
dvi: {DIF_INSTALLDEVICEFILES - exit(0x00000002)} 16:14:16.383
! dvi: Queueing up error report for device install failure.
dvi: {Install Device - exit(0x00000002)} 16:14:16.383
dvi: {Core Device Install - exit(0x00000002)} 16:14:16.383
dvi: {DIF_DESTROYPRIVATEDATA} 16:14:16.383
dvi: Class installer: Enter 16:14:16.383
dvi: Class installer: Exit
dvi: Default installer: Enter 16:14:16.399
dvi: Default installer: Exit
dvi: {DIF_DESTROYPRIVATEDATA - exit(0xe000020e)} 16:14:16.399
ump: {Plug and Play Service: Device Install exit(00000002)}
!!! ndv: Device install failed for device.
ndv: {Update Driver Software Wizard exit(00000002)}
<<< Section end 2018/03/02 16:15:14.498
<<< [Exit status: FAILURE(0x00000002)]
我甚至尝试使用zadig替换打印机驱动程序,结果相同(访问被拒绝错误)。
此时,我们非常感谢您的任何帮助。
更新03/05/2018
今天,我设法通过以下步骤成功完成自定义inf安装程序:
驱动程序安装成功,regedit反映设备现在正在使用WinUSB
可悲的是,当我尝试从网页上打印时,我继续收到&#34; DOMException:访问被拒绝。&#34; 错误...所以我仍然需要帮助:(< / p>
ps:这可能是我所知道的stackoverflow上最长的帖子(或者至少是前10名)。
更新03/06/2018
根据Reilly Grant的要求,我包括USBView的输出(lsusb等效于Windows)
[Port1] : Aeropost Zebra LP2844
Is Port User Connectable: yes
Is Port Debug Capable: no
Companion Port Number: 10
Companion Hub Symbolic Link Name: USB#ROOT_HUB30#4&4f0abe8&0&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}
Protocols Supported:
USB 1.1: yes
USB 2.0: yes
USB 3.0: no
Device Power State: PowerDeviceD0
---===>Device Information<===---
*!*ERROR: No String Descriptor for index 4!
ConnectionStatus:
Current Config Value: 0x01 -> Device Bus Speed: Full (is not SuperSpeed or higher capable)
Device Address: 0x01
Open Pipes: 2
===>Device Descriptor<===
bLength: 0x12
bDescriptorType: 0x01
bcdUSB: 0x0100
bDeviceClass: 0x07
*!*ERROR: unknown bDeviceClass 7
bDeviceSubClass: 0x01
*!*ERROR: bDeviceSubClass of 1 is invalid
bDeviceProtocol: 0x02
*!*ERROR: bDeviceProtocol of 2 is invalid
bMaxPacketSize0: 0x08 = (8) Bytes
idVendor: 0x0A5F = Zebra Technologies
idProduct: 0x0009
bcdDevice: 0x0001
iManufacturer: 0x02
*!*ERROR: No String Descriptor for index 2!
iProduct: 0x04
*!*ERROR: No String Descriptor for index 4!
iSerialNumber: 0x06
*!*ERROR: No String Descriptor for index 6!
bNumConfigurations: 0x01
---===>Open Pipes<===---
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x85 -> Direction: IN - EndpointID: 5
bmAttributes: 0x02 -> Bulk Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x00
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x06 -> Direction: OUT - EndpointID: 6
bmAttributes: 0x02 -> Bulk Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x00
---===>Full Configuration Descriptor<===---
===>Configuration Descriptor<===
bLength: 0x09
bDescriptorType: 0x02
wTotalLength: 0x0020 -> Validated
bNumInterfaces: 0x01
bConfigurationValue: 0x01
iConfiguration: 0x00
bmAttributes: 0xC0 -> Self Powered
-> Bus Powered
MaxPower: 0x00 = 0 mA
===>Interface Descriptor<===
bLength: 0x09
bDescriptorType: 0x04
bInterfaceNumber: 0x00
bAlternateSetting: 0x00
bNumEndpoints: 0x02
bInterfaceClass: 0x07 -> This is a Printer USB Device Interface Class
bInterfaceSubClass: 0x01
bInterfaceProtocol: 0x02
iInterface: 0x00
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x85 -> Direction: IN - EndpointID: 5
bmAttributes: 0x02 -> Bulk Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x00
===>Endpoint Descriptor<===
bLength: 0x07
bDescriptorType: 0x05
bEndpointAddress: 0x06 -> Direction: OUT - EndpointID: 6
bmAttributes: 0x02 -> Bulk Transfer Type
wMaxPacketSize: 0x0040 = 0x40 bytes
bInterval: 0x00
有趣的是(实际上很奇怪),在尝试获取这些新信息时,我的Google Chrome开始投掷
TypeError: Cannot read property 'getDevices' of undefined
控制台中出现错误,并在控制台中输入navigator.usb返回 undefined 。
由于这没有任何意义,我重新安装了Chrome,但错误仍在继续
因此我安装了Chrome Canary(其中存在navigator.usb)并且证明了PRINTER STARTED PRINTING并且Access Denied错误消失了。
我卸载了Chrome Canary,不知何故GA Chrome也有效。直到我关闭Chrome并再次打开它。然后我得到了&#34;无法读取属性&#39; getDevices&#39;未定义&#34;再次出错。
我注意到删除了AppData / Local / Google中的Chrome用户数据文件夹(整个配置文件夹)会让Chrome再次运行,直到我关闭它并再次打开它。
也许在我的打印代码中有些东西会留下一些东西&#34;持有&#34;尽管我正在调用releaseInterface并关闭?
现在问题似乎有所改变了吗?
答案 0 :(得分:2)
也许您可以在这里使用我的WebUSB测试器进行快速测试:https://larsgk.github.io/webusb-tester/它应该显示系统声明了哪些接口(如果这是它失败的原因)。
答案 1 :(得分:2)
在其他Windows机器上进行了一些测试之后,我设法使用Zadig软件使一切工作,用WinUSB替换Windows安装的驱动程序。
关键是在更换驱动程序后重新启动计算机。
我开发的自定义驱动程序也有效,但Zadig的程序使事情变得更容易;)