Counting printed Pages by Clients with c# and WMI

2020-07-25 09:25发布

the goal is like i said in the Topic. I know there are a lot of articles on that specific Problem and i tried all most all of them. But since non of them worked out for me, I'm now trying to find out why this one just works sometimes and sometimes nothing is happening although many things are printed. So this is my code which right now should wait for a job to be printed and just tell me about it. Nothing more.

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;
        }
    }

标签: c# printing wmi
2条回答
Rolldiameter
2楼-- · 2020-07-25 09:41

To get the total pages printed by a job I would try monitoring __InstanceDeletionEvents, I believe that at that time Win32_PrintJob.TotalPages should show the printed pages accurately (can't test this right now, sorry). There is also a nice alternative here:

Monitoring a Printer Queue from VB.NET

If you look at the article comments, the author also advises to monitor JOB_WRITTEN events to get the total number of pages printed.

If you are trying to monitor the progress of large print jobs, try monitoring __InstanceModificationEvents once the job is created, something like this:

Select * From __InstanceModificationEvent Within 1 
Where TargetInstance Isa "Win32_PrintJob" 
And TargetInstance.PagesPrinted > PreviousInstance.PagesPrinted
查看更多
乱世女痞
3楼-- · 2020-07-25 09:42

To get the progress of the printed pages for a particular job, try using a smaller polling interval and use the EventArrivedEventHandler delegate attached to the WMI event for handling the incoming data in a asynchronous way.

Try this sample.

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();
        }
    }
}
查看更多
登录 后发表回答