You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何监控打印机单页打印事件?解决Win32_PrintJob TotalPages计数不准问题

我之前折腾打印监控的时候也踩过Win32_PrintJob的坑——TotalPages这个属性其实是作业的总页数预估值,在打印过程中可能不会实时更新,甚至有些驱动一开始根本不会填充这个值,所以用来统计已打印页数肯定不准。要实现逐页监控打印事件,靠计数器累加才是靠谱的路子,这里给你两个可行的方案:

方案一:用WMI事件订阅实时监听打印页数变化

WMI的__InstanceModificationEvent可以帮你捕获Win32_PrintJob对象的属性变更,我们只需要关注PagesPrinted的增量变化就能准确统计已打印页数。这个方法实现起来简单,不用调用复杂的原生API。

举个C#的实现例子:

using System;
using System.Management;

class PrintPageMonitor
{
    static void Main(string[] args)
    {
        // 构造WMI查询:每1秒检查一次,只监听PagesPrinted增加的作业变更
        string wmiQuery = @"SELECT * FROM __InstanceModificationEvent WITHIN 1 
                            WHERE TargetInstance ISA 'Win32_PrintJob' 
                            AND TargetInstance.PagesPrinted > PreviousInstance.PagesPrinted";

        var watcher = new ManagementEventWatcher(wmiQuery);
        watcher.EventArrived += OnPrintPageUpdated;
        
        Console.WriteLine("打印页面监控已启动...按任意键停止");
        watcher.Start();
        Console.ReadKey();
        watcher.Stop();
    }

    private static void OnPrintPageUpdated(object sender, EventArrivedEventArgs e)
    {
        var jobInstance = (ManagementBaseObject)e.NewEvent["TargetInstance"];
        int currentPrinted = Convert.ToInt32(jobInstance["PagesPrinted"]);
        string jobId = jobInstance["JobId"].ToString();
        string printerName = jobInstance["PrinterName"].ToString();

        Console.WriteLine($"打印机 [{printerName}] 作业 {jobId} 已打印页数:{currentPrinted}");
        // 在这里把currentPrinted同步到你的计数器,或者做后续业务处理
    }
}

注意事项:

  • 运行程序时需要足够的权限:最好以管理员身份启动,否则可能无法访问WMI的打印事件
  • 部分打印机驱动可能会批量更新PagesPrinted(比如每打印5页才更新一次),这时候你需要根据增量来累加计数器,而不是只取当前值

方案二:调用Windows打印池原生API(更可靠)

如果WMI的监控不够灵敏,或者遇到某些特殊驱动不兼容的情况,可以直接调用Windows Print Spooler的原生API,比如FindFirstPrinterChangeNotificationGetJob来监听打印作业的页面推进事件。这个方法更底层,兼容性更好,但实现起来稍复杂。

核心思路是:

  • 注册打印机的作业变更通知(监听PRINTER_CHANGE_JOB事件)
  • 当收到通知时,调用GetJob获取作业的最新信息,提取PagesPrinted字段
  • 根据字段的变化来更新你的计数器

关键提醒

别再用TotalPages来统计已打印页数了!它的作用是告诉你这个作业一共要打多少页,而不是已经打了多少页。真正能反映打印进度的是PagesPrinted,通过监听它的变化才能得到准确的已打印页数。

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

火山引擎 最新活动