You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Electron JS搭配React JS获取局域网已连接打印机名称列表

Electron + React 获取局域网已连接打印机列表最佳实践

核心思路:所有系统级API调用全部放在Electron主进程处理,通过安全IPC通道和React渲染层通信,优先使用Electron官方内置API,减少第三方依赖,兼顾安全性、跨平台兼容性和稳定性。

方案选型逻辑

不要一开始就写局域网端口扫描、跨平台调用系统命令的冗余逻辑,Electron官方已经封装了和系统打印模块打通的API,可以直接拿到系统枚举的所有可用打印机,包括本地直连、局域网共享、网络连接的设备,和系统打印面板展示的列表完全一致,拿到的设备都是已经安装驱动、可以直接发起打印的,比自己扫描出来的未安装驱动的设备实用性高很多。

  • 核心API:Electron 11+ 版本内置的webContents.getPrintersAsync(),异步非阻塞,支持Windows/macOS/Linux全平台
  • 通信方式:基于contextBridge做安全的IPC通信,不开启nodeIntegration,遵循Electron安全规范
  • 扩展场景:如果需要识别还没被用户添加到系统的局域网打印机,再额外按平台加扫描逻辑即可

具体实现步骤

1. 主进程逻辑编写

在Electron主进程中注册IPC处理函数,统一处理打印机列表获取逻辑,不要把系统API直接暴露给渲染层。

const { ipcMain, BrowserWindow } = require('electron')
const path = require('path')

// 注册IPC处理通道
ipcMain.handle('fetch-network-printers', async () => {
  const currentWin = BrowserWindow.getFocusedWindow()
  if (!currentWin) return []
  // 调用内置API获取全量打印机列表
  const allPrinters = await currentWin.webContents.getPrintersAsync()
  // 按需过滤:只返回在线的局域网/网络打印机,过滤掉离线设备、虚拟打印机(如PDF导出、OneNote虚拟打印等)
  return allPrinters
    .filter(printer => {
      return printer.status !== 0 // 0代表离线
      && printer.isNetworkPrinter // 只留网络/局域网打印机,要拿全量可以去掉这个条件
    })
    .map(printer => ({
      name: printer.name, // 发起打印时直接传这个名称即可
      displayName: printer.displayName,
      isShared: printer.isShared,
      location: printer.location
    }))
})

// 主窗口初始化配置
function createMainWindow() {
  const mainWin = new BrowserWindow({
    width: 1280,
    height: 800,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      contextIsolation: true, // *必须开启*,隔离渲染层和主进程上下文
      nodeIntegration: false, // *必须关闭*,避免渲染层拿到全量node权限带来安全风险
      sandbox: false
    }
  })
  // 加载React页面,开发环境可以加载本地dev服务地址,生产环境加载打包后的html
  mainWin.loadURL(/* 你的React页面地址 */)
}

如果需要获取未添加到系统的局域网打印机,再在主进程加对应平台的扫描逻辑,不要放到渲染层执行:

  • Windows:通过PowerShell执行Get-Printer命令枚举域内、局域网共享的打印设备
  • macOS:通过lpstat -p命令或者Bonjour服务扫描mDNS广播的打印设备
  • Linux:通过lpstat -a或者avahi服务扫描局域网打印设备
    扫描到的结果和内置API拿到的已安装列表去重合并即可。

2. Preload预加载脚本配置

通过预加载脚本,只把需要的方法暴露给React渲染层,避免暴露过多系统能力:

const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('desktopAPI', {
  getPrinters: () => ipcRenderer.invoke('fetch-network-printers')
})

3. React层调用

React侧不需要引入任何node相关依赖,直接调用预加载脚本暴露的全局方法即可:

import { useEffect, useState } from 'react'

export default function PrinterSelect() {
  const [printerList, setPrinterList] = useState([])
  const [activePrinter, setActivePrinter] = useState('')

  useEffect(() => {
    const getPrinters = async () => {
      const list = await window.desktopAPI.getPrinters()
      setPrinterList(list)
    }
    getPrinters()
  }, [])

  return (
    <div className="printer-selector">
      <label>选择局域网打印机:</label>
      <select 
        value={activePrinter} 
        onChange={e => setActivePrinter(e.target.value)}
      >
        {printerList.map(printer => (
          <option key={printer.name} value={printer.name}>
            {printer.displayName}
          </option>
        ))}
      </select>
    </div>
  )
}

避坑说明

  • 不要使用年久失修的第三方打印相关npm包(比如老旧的electron-printer类库),这类包大多不支持新版Electron,跨平台bug多,没有维护价值,官方内置API稳定性最高
  • 不要在React渲染层直接调用node模块或者执行系统命令,会打破Electron的安全隔离模型,容易出现权限报错和安全漏洞
  • 如果遇到枚举不到目标打印机的情况,先检查系统自带的打印面板是否能看到该设备,Electron的枚举结果和系统打印面板完全一致,系统识别不到的设备Electron也无法获取
  • 如果你的应用需要兼容Electron 11以下的老旧版本,可以把getPrintersAsync()换成同步的webContents.getPrinters(),但同步API会阻塞主进程,不推荐使用

内容的提问来源于stack exchange,提问作者Rajashree Saste

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 12:21:20