1

TASK

When user print the document ,pause the pop will appear then fill the form click enter the form will closed and job has been resumed.

We have 50 Network Printers , 2000 Client Machine and one print server.

EACH CLIENT had 3 or 4 printers

PROBLEM

If user print the document locally (EX:PDF PRINTER, XPS DOCUMENT WRITER) (or) using network printer (CANON,HP) the print-job was immediately PAUSE.

MY TRIES

When print any of the document the event listener watching and return the print job.

  • In First Pause Method sometimes work and mostof time doesn't work properly.Because, Its searching for the printjob but its not there is already printed.

  • In Second Pause Method doesn't work Because,event listener return the Managementbaseobject but If want to pause the Print Job need ManagementObject How to convert ManageBaseObject to ManageObject

PRINTJOB EVENT LISTENER CODE

    managementEvent = new ManagementEventWatcher();
    managementEvent.Query = new EventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 0.1 WHERE TargetInstance ISA 'Win32_PrintJob'");
    managementEvent.Scope = new ManagementScope(@"\root\cimv2");
    managementEvent.EventArrived += new EventArrivedEventHandler(printJobArrived_EventArrived);
    managementEvent.Start();

MAIN ACTION CODE

private void printJobArrived_EventArrived(object sender, EventArrivedEventArgs e)
{
  try
     {
CurrentprintJob = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value;
    }
    catch(Exception ex){

                       }
}

TO PAUSE THE PRINTJOB METHOD 1

 public bool PausePrintJob(string jobname)
            {
                bool isActionPerformed = false;
                try
                { 
                    string searchQuery = "SELECT * FROM Win32_PrintJob WHERE Name LIKE '%"+jobname+"%'";

                    ManagementObjectSearcher searchPrintJobs = new ManagementObjectSearcher(searchQuery);
                    ManagementObjectCollection prntJobCollection = searchPrintJobs.Get();
                    foreach (ManagementObject prntJob in prntJobCollection)
                    {
                                prntJob.InvokeMethod("Pause", null);
                                isActionPerformed = true;
                   }
                }
                catch (Exception ex)
                {
                    new LogFile().WriteErrorLog(ex.StackTrace, ex.Message);
                }
                return isActionPerformed;
            }

TO PAUSE THE PRINTJOB METHOD 2

 public bool PausePrintJob(ManagementObject currentPrintJob, bool makePause)
        {
            bool isActionPerformed = false;
            try
            {
                {
                    if (makePause == true && currentPrintJob != null)
                    {
                        currentPrintJob.InvokeMethod("Pause", null);
                        isActionPerformed = true;
                    }
                    else if (makePause == true && currentPrintJob != null)
                    {
                        currentPrintJob.InvokeMethod("Resume", null);
                        isActionPerformed = false;
                    }

                }
            }
            catch (Exception ex)
            {
                new LogFile().WriteErrorLog(ex.StackTrace, ex.Message);

            }
            return isActionPerformed;
        } 

2 Answers2

3

WMI is too slow for this. You probably need to use FindFirstPrinterChangeNotification and FindNextPrinterChangeNotification.

You might find these examples useful.

Nick Westgate
  • 3,088
  • 2
  • 34
  • 41
  • We have 50 network printers and 200 clients (means user) and one print server..... The client machine printing with in the any network printer.. how to monitoring the 50 machine at the time when client click to print... – Karthikeyan Sekar Sep 20 '16 at 11:30
  • 1
    I'm not quite sure I understand you. If the print is not through the print server you need your software on the client. If on the server you need to monitor multiple printers. The second example link I gave you covers this. It has a Threadpool thread waiting on each notification handle. The other way you can do it is to have an array of notification handles and wait on all of them. – Nick Westgate Sep 20 '16 at 23:20
  • Ya i saw the example link.. but they do pause the printer then resume the printer....that's only confused... Suppose first user already use the printer and the second user want to use the same printer... Ok... Will read again... @Nick.am very beginner in Windows application...so.. i stucked everywhere – Karthikeyan Sekar Sep 21 '16 at 03:03
  • 1
    Pausing a printer or a job is different. Pausing a printer will print no jobs. Pausing a job will stop that job; other jobs will print. If you are a beginner then this is a lot to learn. It won't be easy. Maybe you can use some third-party software to accomplish your goal. Google "windows print management software". – Nick Westgate Sep 21 '16 at 05:04
  • Thanks... I have an another doubt .. all the printers are shared ,,i just call monitoring via NOTITICATION return 5digit job id and the original printer create the (0-255) job id. I tried the findfirstprinterchangenotification but they returned the 5 digit job id only... How to get the original job id from client system. In WMI return the 2 job (5digit and 3 digit) also.. – Karthikeyan Sekar Sep 21 '16 at 10:48
  • I don't know. Maybe you can't get this from the server. Maybe only on the client. If you pause the job can you still use WMI to get that? And do you still need it? – Nick Westgate Sep 21 '16 at 22:02
  • Oh, Thanks. Now, am move my `Print Queue Monitor` code to server. am stuck again on `WIN32_Methods`. In Spooler API to get PrintJob Data using `EnumJobs` but i cant to get that how to get the `JobInfo , JOBINFO1, JOBINFO2` using any other methods or can you share any samples using ENUMJOBS ..Please Suggest me. @Nick Westgate – Karthikeyan Sekar Sep 23 '16 at 12:16
  • If I have answered your original question please accept the answer. This sounds like a new question. – Nick Westgate Sep 23 '16 at 19:28
  • Actually i can't to pause the printjob using find next printer change notification and findfirstprinterchangenotification.. am using these then get the job id and pause the printjob using set job. But it doesn't working.. printjob some time paused but again i try to resume.. its can't to resume again.. automatically. Deleted. – Karthikeyan Sekar Sep 26 '16 at 13:48
  • @KarthikeyanSekar Accept the answer and upvote it already. Your reluctance to do that one simple thing is why people quit answering questions here. – Carey Gregory Nov 21 '16 at 06:52
  • @CareyGregory Sorry.. I Accept this answer. and My problem also solved I can't to ask any new question.. that's only i delete this question – Karthikeyan Sekar Nov 25 '16 at 11:35
  • @KarthikeyanSekar You apparently don't understand how to accept an answer. See the check mark under the vote total on this question? Click it. Then click the up arrow to upvote the question. There is no need to delete anything. – Carey Gregory Nov 25 '16 at 15:25
-1

Finally, I've found a solution on MSDN official documentation website for controlling printer, here is the link: https://www.codeproject.com/Articles/6592/A-Simple-Approach-for-Controlling-Print-Jobs-using

It shows that how to Pause, Resume and Delete a print job. The core class is Win32_PrintJob. The variable of printJob is from ManagementObjectSearcher object which searched one printer instance.

printJob.InvokeMethod("Pause", null);
printJob.InvokeMethod("Resume", null);
printJob.Delete()

I still found that its Python implementation of code : http://timgolden.me.uk/python/wmi/cookbook.html#watch-for-new-print-jobs

import wmi
c = wmi.WMI ()

print_job_watcher = c.Win32_PrintJob.watch_for (
  notification_type="Creation",
  delay_secs=1
)

while 1:
  pj = print_job_watcher ()
  print "User %s has submitted %d pages to printer %s" % \
    (pj.Owner, pj.TotalPages, pj.Name)
Johnny
  • 1,112
  • 1
  • 13
  • 21