Monitoring of Printing Spool

Asked

Viewed 458 times

0

I’m trying to make an application that monitors my printer and when the user sends a print of any program, it captures that 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 the printing. I get her to monitor the spool and return the job information sent. But I can’t pause the printing (no error appears, I just can’t find the necessary function for it. I have 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 someone help me?

  • 1

    You may want to use Winapi, follow Print Spool API documentation: https://msdn.microsoft.com/en-us/library/windows/desktop/dd162861(v=vs.85). aspx#print_job_functions

  • 1

    @Marcelouchimura everything I found there is only in C++... The Findfirstprinterchangenotification feature, which by my researches would be the most suitable to use, I cannot find in C# either.

  • 1

    No need to program in C++ to use this method FindFirstPrinterChangeNotification(). What you have to see is the Decorator [DllImport] of C# and the reserved word extern: https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/keywords/extern . This is just the beginning!

  • 1

    @Marcelouchimura helped me a lot. Want to put this answer?

  • 1

    No, just knowing it was useful already comforts me. Thank you!

1 answer

0

Really a solution to your problem would be the use of what Marcelo Uchima 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 a unsafe context in which pointers can be used.

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

  • In some cases, unsecured code can boost an application’s performance by removing matrix boundary checks.
  • Using the unsafe 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 don’t have major performance problems, using event monitoring is the best option.

In this code, you cannot perform Invoke in the method because your foreach is searching the query information properties. Create only one foreach as follows:

foreach (ManagementObject prntJob in prntJobCollection)

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.