最近在被一个问题困扰很久,我遇到的场景是这样的。
我的应用支持的打印指令包括:ESC/POS、TSPL、ZPL。每当用户通过 USB 连接上打印机后,他需要选择打印机支持的打印指令。如果选错了,可能会乱码或会把打印指令当成内容打印出来。
这样就会显得这个应用很不智能,增加了用户心智负担。
理想的情况是,连接上打印机后,可以通过一条指令查询出当前打印机支持的指令。而本文介绍的就是这条指令。
涉及的关键字有:
- USB 控制指令
- controlTransferIn
- GET DEVICE ID
话不多说,马上进入正题。
前提:这次的示例是基于之前的文章 通过 WebUSB 驱动打印机打印,如果你还没看过,先看再回来看这篇文章。
关键函数如下:
const getInfo = async () => {
if (!selectedDevice) {
return Promise.reject("未连接打印机");
}
const setupParams = {
requestType: "class", // 请求类型
request: 0x00, // 是 GET DEVICE ID 的请求代码(通常根据你的设备文档确定)。
value: 0x0000, // 请求值
index: 0x0000, // 接口索引
recipient: "interface",
};
const { data, status } = await selectedDevice.controlTransferIn(
setupParams,
64
);
if (status != "ok" || !data) {
return Promise.reject("读取打印机信息失败");
}
const decoder = new TextDecoder();
const deviceId = decoder.decode(data) || "";
console.log(`deviceId ${deviceId}`); // 输出,如:1MFG:Printer;MDL:POS-80;CMD:ESC/POS;CLS:PRINTER;
return deviceId;
};
deviceId
是一个字符串,每个字段用;
分割。每个字段是KEY:VALUE
的形式。不同品牌的打印机,这个 deviceId
可能会返回不同格式的内容,要看具体的打印机返回信息。
各个字段的含义:
1MFG: 1 可能是版本号或其它的含义。MFG 是 manufacturer 的缩写,代表的是制造商名称。
MDL: MDL 是 model 的缩写,代表的是打印机的型号。
CMD: CMD 是 command 的缩写,代表的是打印机支持的指令。这是我们最感兴趣的字段。
CLS: CLS 是 class 的缩写,代表的是USB 类型。PRINTER 代表的是打印机。
通过解析出 CMD 字段,我们就可以拿到打印支持的指令,就不需要用户再选一次打印机支持的指令了。
参考
https://developer.mozilla.org/en-US/docs/Web/API/USBDevice/controlTransferIn
chatgpt, 关键字 webusb 发送 ctl GET DEVICE ID