使用c#和WMI计算客户端打印的页数

目标就像我在主题中说的那样。 我知道有很多关于这个特定问题的文章,我尝试了所有这些问题。 但是由于它们不适合我,我现在正试图找出为什么这个有时会起作用, 有时甚至没有发生任何事情,尽管印刷了许多东西。 所以这是我的代码,现在应该等待打印作业,然后告诉我它。 而已。

private void StartMonitor() { try { var opt = new ConnectionOptions { EnablePrivileges = true }; var scope = new ManagementScope("root\\CIMV2", opt); scope.Connect(); var query = new WqlEventQuery("SELECT * FROM __InstanceOperationEvent WITHIN 60 WHERE TargetInstance ISA \"Win32_PrintJob\""); var watcher = new ManagementEventWatcher(query); Console.WriteLine("Ready to receive Printer Job events..."); var pjEvent = watcher.WaitForNextEvent(); if (pjEvent != null) Console.WriteLine("Event occured: " + pjEvent.Properties["PagesPrinted"]); } catch (ManagementException e) { Console.WriteLine(e.StackTrace); Console.WriteLine(e.ErrorCode); Console.WriteLine(e.ErrorInformation); _Error = e.Message; throw; } } 

要获取特定作业的打印页面的进度,请尝试使用较小的轮询间隔,并使用附加到WMI事件的EventArrivedEventHandler委托以异步方式处理传入的数据。

试试这个样本。

 using System; using System.Collections.Generic; using System.Management; using System.Text; namespace GetWMI_Info { public class EventWatcherAsync { private void WmiEventHandler(object sender, EventArrivedEventArgs e) { Console.WriteLine("TargetInstance.Caption : " + ((ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)["Caption"]); Console.WriteLine("TargetInstance.JobStatus : " + ((ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)["JobStatus"]); Console.WriteLine("TargetInstance.PagesPrinted : " + ((ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)["PagesPrinted"]); Console.WriteLine("TargetInstance.Status : " + ((ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value)["Status"]); } public EventWatcherAsync() { try { string ComputerName = "localhost"; string WmiQuery; ManagementEventWatcher Watcher; ManagementScope Scope; if (!ComputerName.Equals("localhost", StringComparison.OrdinalIgnoreCase)) { ConnectionOptions Conn = new ConnectionOptions(); Conn.Username = ""; Conn.Password = ""; Conn.Authority = "ntlmdomain:DOMAIN"; Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), Conn); } else Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), null); Scope.Connect(); WmiQuery ="Select * From __InstanceOperationEvent Within 1 "+ "Where TargetInstance ISA 'Win32_PrintJob' "; Watcher = new ManagementEventWatcher(Scope, new EventQuery(WmiQuery)); Watcher.EventArrived += new EventArrivedEventHandler(this.WmiEventHandler); Watcher.Start(); Console.Read(); Watcher.Stop(); } catch (Exception e) { Console.WriteLine("Exception {0} Trace {1}", e.Message, e.StackTrace); } } public static void Main(string[] args) { Console.WriteLine("Listening {0}", "__InstanceOperationEvent"); Console.WriteLine("Press Enter to exit"); EventWatcherAsync eventWatcher = new EventWatcherAsync(); Console.Read(); } } } 

为了获得作业打印的总页数,我会尝试监视__InstanceDeletionEvents,我相信当时Win32_PrintJob.TotalPages应准确显示打印页面(现在无法测试,抱歉)。 这里还有一个不错的选择:

从VB.NET监视打印机队列

如果您查看文章注释,作者还建议监视JOB_WRITTEN事件以获取打印的总页数。

如果您尝试监视大型打印作业的进度,请在创建作业后尝试监视__InstanceModificationEvents,如下所示:

 Select * From __InstanceModificationEvent Within 1 Where TargetInstance Isa "Win32_PrintJob" And TargetInstance.PagesPrinted > PreviousInstance.PagesPrinted