Monday, May 12, 2008

How to Cancel Printing in C# ?

In the previous blog post we have seen How to print a file/string in C#. In this post we would be looking at how to cancel a print job submitted to the printer. These are some of the common functionalities required in most applications.

For cancellation of the printer job we will be using the System.Management namespace of the .NET framework. Using the ManagementObjectSearcher class we will get a list of all the queued printer jobs. Then using the ManagementObject we will delete the appropriate printer job. Please note that for Cancellation of a printer job, the JobName or JobID is required. Please find below the function that accepts a jobID and then deletes that job from the printer queue. A Boolean true value is returned if successful in deleting the job else a false value is returned.

Remember to Add a Reference to the System.Management .Net assembly.

#region CancelPrintJob

/// <summary>
/// Cancel the print job. This functions accepts the job number.
/// An exception will be thrown if access denied.
/// </summary>
/// <param name="printJobID">int: Job number to cancel printing for.</param>
/// <returns>bool: true if cancel successfull, else false.</returns>
public bool CancelPrintJob(int printJobID)
{
// Variable declarations.
bool isActionPerformed = false;
string searchQuery;
String jobName;
char[] splitArr;
int prntJobID;
ManagementObjectSearcher searchPrintJobs;
ManagementObjectCollection prntJobCollection;
try
{
// Query to get all the queued printer jobs.
searchQuery = "SELECT * FROM Win32_PrintJob";
// Create an object using the above query.
searchPrintJobs = new ManagementObjectSearcher(searchQuery);
// Fire the query to get the collection of the printer jobs.
prntJobCollection = searchPrintJobs.Get();

// Look for the job you want to delete/cancel.
foreach (ManagementObject prntJob in prntJobCollection)
{
jobName = prntJob.Properties["Name"].Value.ToString();
// Job name would be of the format [Printer name], [Job ID]
splitArr = new char[1];
splitArr[0] = Convert.ToChar(",");
// Get the job ID.
prntJobID = Convert.ToInt32(jobName.Split(splitArr)[1]);
// If the Job Id equals the input job Id, then cancel the job.
if (prntJobID == printJobID)
{
// Performs a action similar to the cancel
// operation of windows print console
prntJob.Delete();
isActionPerformed = true;
break;
}
}
return isActionPerformed;
}
catch (Exception sysException)
{
// Log the exception.
return false;
}
}

#endregion CancelPrintJob

13 comments:

Unknown said...

Hi Sandeep,

I'm facing the problem while delete or cancel the print job.

I'm getting an error "Cannot cancel the print job"

Can you help me out?

Thanks and regards,
Mahesh C.

Sandeep Aparajit said...

Thanks Mahesh,

Can you please post the exact exception that you are receiving?
I mean the stack trace of the exception and the inner exception?

Thx!
Sandeep

Anonymous said...

Hi,Sandeep There is a Problem i am implementing your code it work's on some machine and for other machines i dosen't work could you plz help me out.
thx
Abhishek

Sandeep Aparajit said...

Can you give me the exact scenario Abhishek? On which machines does it work and on which machines it doesn't? I means any difference such as OS, .NET Fwk version, other settings..

Please let me know so that I can analyse and let you know the solution.

-Sandeep

Anonymous said...

Hi Sandeep
The picture here is that i'hv created a Browser Helper object assembly which is used in the address space of Internet Explorer But when i'hv tried your cancel printing code in a test machine it worked it worked but when I used it on my machine it dosen't .could u let me know the required settings and the dependencies for IE which can be used with your code....
regards
Abhishek

Sandeep Aparajit said...

Hi Abhishek,

What is the exact exception that you are getting? Basically the code uses ManagementObjectSearcher for getting the Print Queue jobs and then Deletes the required job. My initial analysis says that the error might have occurred due to following reasons:
1. Insufficient permissions
2. Printer not configured properly
3. Wrong printJobID

I would request you to analyse the following and let me know the exact exception that you are getting in the code. Thx!

-Sandeep

Anonymous said...

thx for the reply
Are there dependencies required for ManagementObjectSearcher to cancel the printing in Internet explorer(IE6/IE7) actually the output required is that whenever a user gives the print command from internet Explorer it should cancel printing and in the code i'hv just pop up message box before printijob.delete() .Code executes upto that point but when it comes to the deletion function it dosen't cancel the printing .If there is any other way plz help me out
thx
Abhishek

Sandeep Aparajit said...

As such there are no special requirements for using the code in IE6/7, but Internet Explorer might have some special security settings which may prohibit from accessing the Printer object. For this you can check the IE Blog.

As you said the message box pop-up is shown properly and then the cancellation of the Print job is not done. What is the exact exception that you get on prntJob.Delete(); line?

-Sandeep

Anonymous said...

when Catching the exception it gives "Access Denied" for cancel printing.
thx
Abhishek

Sandeep Aparajit said...

Exactly.. It means that the account under which the Internet Explorer (IE) runs does not have sufficient privileges to cancel printing. You need elevated privileges for performing this operation. Go to the IE icon and right click it. Click "Run as Administrator". The IE window will open. Now try your program, it will execute successfully without any errors, since it has admin permissions. But on OS like Vista, Windows 7 the IE runs under the default account without administrative privileges. Hence before executing this piece of code you will have to ask for elevated privileges or impersonate the admin user to execute the code.
Hope this helps you!

-Sandeep

Anonymous said...

Sandeep
I'hv tried working with your solution but got the same exception .Any More suggestions

thx
Abhishek

Kay said...

Hi Sandeep,

Is it possible to creata a print job, but append documents to the print job and then send it to print? Basically this involves holding a print job and sending it to the printer with several documents to print as one print job. This is to prevent other print documents being printed in the middle of a large print job.

Apologies , I am new to C#.

Thanks, Kay.

deacons9 said...

Hi I have done this.Its work good with 32 bit OS but I am not able to delete job in 64 bit OS.I am using windows 8 as OS
can you help me in this?
Thanks in advance

Post a Comment