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

PrintQueue.Refresh无法显示打印机状态,求助Windows Service获取状态方案

我明白你现在的痛点——靠手动移除纸张、打测试页来检测打印机状态完全不现实,尤其是还要覆盖那些没装在服务运行机器上的打印机。咱们一步步来拆解解决这个问题:

核心问题先理清楚

首先得明确两个关键限制:

  • 本地已安装打印机:拿不到状态大概率是服务权限不够,或者用的API没抓住精准的错误状态字段;
  • 未安装在本机的网络打印机:这类设备的状态信息根本不会存在于本地系统里,必须走网络协议去直接查询打印机本身。
针对性解决方案

1. 修复本地打印机的状态获取

先搞定权限问题

别让服务用Local System账户跑,换成有打印机管理权限的本地管理员或域账户——Local System对部分打印机资源的访问是受限的,这很多时候是隐形的坑。

换个精准的API查询

别只盯着笼统的打印机状态,用WMI的Win32_Printer类,重点看DetectedErrorState字段(这才是反映缺纸、无墨粉这类硬件错误的关键),而不是PrinterStatus(只是整体运行状态)。给你个C#示例(假设你用C#写服务):

using System.Management;

public void FetchLocalPrinterStatus()
{
    var printerSearcher = new ManagementObjectSearcher("SELECT Name, PrinterStatus, DetectedErrorState FROM Win32_Printer");
    foreach (var printerObj in printerSearcher.Get())
    {
        string printerName = printerObj["Name"].ToString();
        uint errorState = (uint)printerObj["DetectedErrorState"];
        
        string errorDesc = errorState switch
        {
            0 => "无错误",
            3 => "缺纸",
            4 => "无墨粉/碳粉不足",
            5 => "卡纸",
            9 => "打印机离线",
            10 => "打印机过热",
            _ => "未知错误"
        };

        Console.WriteLine($"[{printerName}] 当前状态: {errorDesc}");
    }
}

如果WMI查询还是有问题,试试直接调用Windows打印池API(OpenPrinter+GetPrinter),这个是系统级别的,权限够的话更可靠。

2. 搞定非本地安装的网络打印机

这类打印机只能通过网络协议直接查询,最通用的方案是SNMP:

第一步:确认打印机开启SNMP

大部分品牌的网络打印机默认开启SNMP(社区版可能需要手动在打印机Web管理界面打开),社区字符串默认是public。

第二步:用SNMP查询状态

借助SNMP库(比如SnmpSharpNet),查询打印机MIB库中的指定OID来获取错误状态:

  • 缺纸OID:.1.3.6.1.2.1.43.10.2.1.4.1.1
  • 无墨粉OID:.1.3.6.1.2.1.43.11.1.1.9.1.1
  • 卡纸OID:.1.3.6.1.2.1.43.10.2.1.5.1.1

示例代码:

using SnmpSharpNet;

public string GetNetworkPrinterStatus(string printerIp, string community = "public")
{
    var snmpClient = new SimpleSnmp(printerIp, community);
    if (!snmpClient.Valid) return "SNMP连接失败,请检查打印机设置";

    // 查询缺纸状态
    var paperOid = new Oid(".1.3.6.1.2.1.43.10.2.1.4.1.1");
    var result = snmpClient.Get(SnmpVersion.Ver2, new Oid[] { paperOid });

    if (result != null && result.ContainsKey(paperOid))
    {
        var paperStatus = (Integer32)result[paperOid];
        return paperStatus.Value == 1 ? "纸张充足" : "缺纸";
    }
    return "无法获取打印机状态";
}

如果打印机支持REST API或者有标准的Web管理接口,也可以用HTTP请求抓取状态页面,但SNMP是跨品牌最通用的方案。

3. 服务运行的关键配置

  • 权限兜底:服务账户必须同时具备本地打印机管理权限和网络访问权限(访问打印机IP的权限),域账户是最优选择;
  • 实时监控替代轮询:别定时去查状态,用WMI事件监听打印机状态变化,效率更高:
    var statusWatcher = new ManagementEventWatcher(
        new WqlEventQuery("SELECT * FROM __InstanceModificationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Printer'"));
    statusWatcher.EventArrived += (sender, e) =>
    {
        var changedPrinter = (ManagementObject)e.NewEvent["TargetInstance"];
        // 在这里处理状态变化逻辑
    };
    statusWatcher.Start();
    
避坑提醒
  • 防火墙要开:服务运行机器和打印机的防火墙都要允许UDP 161端口(SNMP默认端口);
  • 本地打印机驱动要完整:如果驱动安装不完整,WMI根本读不到正确的状态,建议重装官方驱动;
  • 别碰“允许服务与桌面交互”:这个选项不安全,权限问题还是靠配置正确的服务账户解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:14:17