Access Denied tries to clear print in C #

I am trying to make a method in C # that empties all the elements in a print queue. Below is my code:

LocalPrintServer localPrintServer = new LocalPrintServer(PrintSystemDesiredAccess.AdministratePrinter); PrintQueue printQueue = localPrintServer.GetPrintQueue(printerName); if (printQueue.NumberOfJobs > 0) { printQueue.Purge(); } 

When this code works, in the localPrintServer local constructor, the application throws this error: "An exception occurred while creating the PrintServer object. Win32 error: access is denied."

This constructor has several overloads (including sending parameters). Having tried any of them, I pass this line, but when I go to the printQueue.Purge () call, I get the same access denied message as above.

Looking for suggestions on how / what I can do to get around this. I can manually delete print jobs from my computer. I'm not sure if the application works with the same access as mine and how to check it.

+7
source share
6 answers

This problem is caused because the GetPrintQueue method is slightly evil, as it does not allow you to pass at the right access level. When using your code, you connect to the print server with AdministratePrinter rights (which makes no sense) and connect to the print queue with default user rights. Thus, the operation will fail even if everyone has administrator rights in the print queue. A.

To fix this, use the constructor for PrintQueue instead to specify the correct access level:

 using (PrintServer ps = new PrintServer()) { using (PrintQueue pq = new PrintQueue(ps, printerName, PrintSystemDesiredAccess.AdministratePrinter)) { pq.Purge(); } } 

This can still cause permission errors if you are not working in the context of a member of the Administrators group (or if you are not running with elevated permissions), so surrounding it with a try / catch block is a good idea for production code.

+13
source

Do you use your site as 4.0? I ran into problems when I upgraded our site from 3.5 to 4.0 Framework. The Print Purging feature has stopped working in the 4.0 Framework. I ended up creating a web service that used the 3.5 framework and had a 4.0 site that links the printer that it wants to clean up to a 3.5 web service.

(Sorry to revive this thread, it was one of the topics that I came across when I was looking for an answer. I realized that I would post this if it helps someone who gets into the same situation)

+2
source

// use this as an example to get you started ...

  /// <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; } } 
0
source

If you do not mind clearing all the queues on the local computer, you can use the following snippet. It requires administrator rights, but will not throw exceptions:

 System.ServiceProcess.ServiceController controller = new System.ServiceProcess.ServiceController("Spooler"); controller.Stop(); System.IO.DirectoryInfo info = new System.IO.DirectoryInfo(@"C:\Windows\System32\spool\PRINTERS"); var files = info.GetFiles(); foreach (var file in files) { file.Delete(); } controller.Start(); 
0
source

I recently encountered the same problem after upgrading the .NET Framework from 4.0 to 4.6.1. Oddly enough, my .net application worked on .net 3.5, but somehow it affected this change.

In any case, the way to launch my application was through the task scheduler, and the fix was to right-click on the task, the general one, check the box "Run with the highest privileges".

I think that if you run it on the console, you need to run "Run as administrator" when opening the cmd window.

0
source

I tried using the @mdb solution, but it did not work (access is denied using Framework.NET 4.6.1). I ended up using the following solution:

 void CleanPrinterQueue(string printerName) { using (var ps = new PrintServer()) { using (var pq = new PrintQueue(ps, printerName, PrintSystemDesiredAccess.UsePrinter)) { foreach (var job in pq.GetPrintJobInfoCollection()) job.Cancel(); } } } 
0
source

All Articles