前言
在electron项目中使用的pdf-to-printer这个插件获取打印机并且打印pdf文件,后来测试发现在部分win7电脑上无法获取打印机,查看源码发现是通过powershell的命令来获取打印机:
Get-CimInstance Win32_Printer -Property DeviceID,Name,PrinterPaperNames
查看文档得知Get-CimInstance这个命令依赖高版本的powershell,win7默认的powershell版本是2,自然就没这个命令。
一开始给客户远程升级powershell到5.1,首先对系统有要求,必须是sp1的版本,然后安装.net 4.8,最后安装powershell,在安装的过程中还遇到各种问题,比如证书失效、系统缺少补丁等等,大部分都升级成功了,但是有些电脑满足了要求,而且.net和powershell都安装成功了,最后在重启配置更新的时候失败了,所有的操作都还原了,试了很多次都不行,于是作罢。
解决方法
不得已只能思考其他的方式,后面发现cmd有直接获取打印机的命令:
wmic printer
而且经过测试,在win7上也是可以的。最终修改代码如下:
// 安装iconv-lite解决中文乱码的问题
const iconv = require('iconv-lite');
class Printer {
constructor({ name, isDefault = false }) {
this.name = name;
this.isDefault = isDefault;
}
}
const { exec } = require('child_process');
export function getPrinterList() {
return new Promise((resolve, reject) => {
const cmd = 'wmic printer get name,default';
exec(cmd, { encoding: 'binary' }, (error, stdout, stderr) => {
if (error) {
console.log(decode(error));
reject(decode(error));
return;
}
if (stderr) {
console.log(decode(stderr));
reject(decode(stderr));
return;
}
const output = decode(stdout);
const originPrinters = output
.split('\r\r\n')
.filter(item => item.trim());
originPrinters.shift();
const printerList = originPrinters.map(item => {
// 原始输出示例: "FALSE OneNote for Windows 10"
const [isDefault, name] = item.split(/\s{2,}/);
const printer = new Printer({ name, isDefault: isDefault === 'TRUE' });
return printer;
});
const defaultPrinter = printerList.find(item => item.isDefault);
resolve({ printers: printerList, defaultPrinter });
});
});
}
function decode(data) {
const buffer = Buffer.from(data, 'binary');
// 解决中文乱码
const output = iconv.decode(buffer, 'cp936');
return output;
}
getPrinterList 方法返回的就是一个打印机数组和默认打印机对象,然后就可以为所欲为了。
其他
如果想要获得更多打印机信息,比如打印机端口、打印机支持的纸张尺寸、打印状态等等,可以在wmic printer get name,default后面继续加参数就行了,具体的参数可以直接在cmd中执行wmic printer命令获取。
评论区