Print Spool monitoring

I am trying to make an application that monitors my printer and when the user sends a print, of whatever program it is, it captures this information, pauses the print and opens a new window for the user to enter a code. If the code is correct it continues printing. Otherwise, printing is canceled.

At the moment I'm just trying to get the application to pause printing. I can get her to monitor the spool and return the job information submitted. But I can't pause printing (no error appears, I just can't find the necessary function for this. I've tried using InvokeMethod ("Pause") but it just appears that there is no such option).

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Management;

namespace Listar_Servicos
{
    public partial class frmMonitor : Form
    {
        public frmMonitor()
        {
            InitializeComponent();
        }

        private void frmMonitor_Load(object sender, EventArgs e)
        {
            EventWatch("localhost");
        }

        private ManagementEventWatcher manEWatch;

            public void EventWatch(string host)
            {

                ManagementScope oMs = new ManagementScope(@"\\" + host + @"\root\cimv2");
                oMs.Connect();
                manEWatch = new ManagementEventWatcher(oMs, new EventQuery("SELECT * FROM    __InstanceCreationEvent WITHIN 0.1 WHERE TargetInstance ISA 'Win32_PrintJob'"));
                manEWatch.EventArrived += new EventArrivedEventHandler(mewPrintJobs_EventArrived);
                manEWatch.Start();
            }

            static void mewPrintJobs_EventArrived(object sender, EventArrivedEventArgs e)
            {
                foreach (PropertyData prop in e.NewEvent.Properties)
                {
                    string val = prop.Value == null ? "null" : prop.Value.ToString();

                }

                ManagementBaseObject printJob = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value;
                string v = "";

                foreach (PropertyData propp in printJob.Properties)
                {

                    string name = propp.Name;
                    string val = propp.Value == null ? "null" : propp.Value.ToString();
                    val += "\n";
                    v += name + ":" + val;

                }
                MessageBox.Show(v);
            }

        private void btnNovoMonitor_Click(object sender, EventArgs e)
        {
            frmMonitor2 novoMonitor = new frmMonitor2();
            novoMonitor.Show();
        }
    }
}

Could anyone help me?

Author: Leticia Rosa, 2018-06-13

1 answers

Really a solution to your problem would be to use what Marcelo colocouima put in the comments.

However, this form of programming, according to Microsoft itself:

To maintain type security and security, C# does not support pointer arithmetic by default. However, using the keyword unsafe, you can define an unsafe context in which the pointers they can be used.

Also according to them, these are some of the features of using unsafe code:

  • in some cases, unsafe code can increase the performance of an application by removing array boundary checks.
  • using unsecured code presents security and stability risks.

Depending on what you are going to do, despite the security risks, if you want a higher performance you can use this method.

If you do not have large performance problems, using event monitoring itself is the best option.

In this code, you cannot Invoke the method because your foreach is fetching the properties of the query information. Just create a foreach as follows:

foreach (ManagementObject prntJob in prntJobCollection)

And you will be able to use prntJob.InvokeMethod("Pause", null); (similar syntax to continue, only changing from Pause to Resume).

 2
Author: Nicolas Souza, 2018-07-05 20:25:59