Click here to Skip to main content
15,038,237 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Good afternoon,

I'm currently developing a kiosk system making use of a BOCA printer on USB port for ticket printing purposes.

I communicate with the printer using winspool.drv functionality.

Sometimes when the application starts up with no tickets loaded in the printer a test print file will be in the printer queue but will usually be removed after the code has returned out of ticket status from the printer buffer. If you restart the application before this is done, or end task it, the print job will stay in the queue and not be removed. When you then restart the application the same steps will be followed and it will add a new job to the queue which in turn will then return an error when trying to execute StartDocPrinter (this function times out) and the application will then not start-up.

What I would like to do is when the application starts up, clear all jobs found in the print queue for the local attached printer.

I have been looking for code and tried using SetJob (winspool.drv) but I don't have the JobID's associated with the jobs in the queue so I can't set them to cancel.

I'm either not understanding the cancel process or it's just not possible to cancel the jobs.

Does anybody maybe have any suggestions to my problem?

Thanks.
Posted
Updated 23-Feb-21 17:03pm

PrintQueue.Purge Method

http://msdn.microsoft.com/en-us/library/system.printing.printqueue.purge.aspx[^]

Be aware, this will clear everything in the queue.
   
Comments
trucido79 26-May-11 11:24am
   
Thank you for the reply.

I have looked at the purge method but I can't seem to be able to create a printqueue object without a printserver.

If you look at http://msdn.microsoft.com/en-us/library/system.printing.printserver.aspx the following piece of code can't work for a local printer which is not shared.

' Create a PrintServer
' "theServer" must be a print server to which the user has full print access.
Dim myPrintServer As New PrintServer("\\theServer")

Am I missing something obvious or can't you connect to a local printer and purge the queue? What would the path be to my local printer? "\\localhost\printername" doesn't work either even if I enable sharing on the printer, the error returned is: The Printer name is invalid.

Thanks for having a look.
S Houghtelin 26-May-11 12:02pm
   
You can try using LocalPrintServer to access the ConnectToPrintQueue(PrintQueue) and purge the queue that way. (I haven't tried this myself)

link(http://msdn.microsoft.com/en-us/library/system.printing.localprintserver(v=VS.100).aspx)
trucido79 27-May-11 4:54am
   
Hi there,

I have tried the above link you posted about the local print server. I can now access the print queue, thanks.

Although the accessing of the queue part is now sorted I still can't purge it. Error now returned is Access Denied.

Here is the code I use to check the queue and then if there are jobs to purge I try and purge it:

Dim localPrintServer As New System.Printing.LocalPrintServer(PrintSystemDesiredAccess.AdministrateServer)
Dim printerQueue As PrintQueue = localPrintServer.GetPrintQueue("Boca FGL 26/46 200 DPI")

If printerQueue.NumberOfJobs > 0 Then
printerQueue.Purge()
End If

Exception returned:
System.Printing.PrintQueueException was caught
Message=An exception occurred while the queue was purged. Win32 error: Access is denied.

As you can see above I've setup the print server with admin privs.
I also run visual studio in administrator mode
I've got the admin rights for the application set in the manifest file.
My users have rights on the printer itself.

What can I change to get past this issue, any ideas perhaps?

Thanks for the replies so far you've helped me a great deal.
S Houghtelin 27-May-11 7:39am
   
Hello,

I know this sounds stupid simple, but the error you describe can be generated if the printer is either not connected or it is turned off.

Another thing to look at would be to assure that all the printserver and queue properties have been initialized. It sounds like you have made the connection, can you access the properties?

I'm sure that you have looked this article over, but this covers how to copy and set the proerties to clone a local print server. (http://msdn.microsoft.com/en-us/library/ms573300.aspx#Y605)

Good luck, almost there :)
trucido79 31-May-11 8:21am
   
Hi again,

I have 2 printers attached to my machine at the moment, 1. Ticket Printer 2. Epson receipt Printer. Both of them are switched on and I can print tickets + receipts without a problem (except when there's print jobs in the queue, but that's understandable). I tried the code on both of the printers and receive the same errors - access denied. All I can think is it's not actually seeing the queue (although I can see the number of jobs in the queue).

I have looked at the link and I believe I can access the properties. I don't exactly know what you mean when saying I need to initialize the properties, is there something I missed in the earlier documentation?

I don't think I will be spending much more time on this as I don't have much time to struggle with it.

Thank you kindly for the effort you put it, I will have a look one more time.
CzBonfire 4-Jun-15 8:09am
   
hello, very old topic but i've found solution:

Dim ps = New LocalPrintServer(PrintSystemDesiredAccess.AdministrateServer)
Dim pq = New PrintQueue(ps, ps.DefaultPrintQueue.FullName, PrintSystemDesiredAccess.AdministratePrinter)

If pq.NumberOfJobs > 0 Then
pq.Purge()
End If


and it's working ;)
hope it will help somebody.
I concur with comment by CzBonfire, 4-Jun-15 8:09am.
His code also worked for me!

Seems strange to declare a "new PrintQueue(ps, ...)", but if I try to simply do "ps.GetPrintQueue(strPrintQueueName)", I get a valid PrintQueue object, but when trying to do the "pq.Purge()" it fails with an access violation.

My code (in C#) is below. I have a couple application settings that are referenced (PrinterQueueName and QueueClearTimeout_sec).
I found that if you want to confirm that the jobs have been cleared, you need to call pq.Refresh() to update the NumberOfJobs property. I built in a timeout to wait for the jobs to be cleared.... not sure if this is necessary or not. After the timeout, if NumberOfJobs is still>0, it would be possible to inform user that it failed to clear the queue (not implemented in my code here).


C#
static void Main(string[] args)
{
	using (LocalPrintServer ps = new LocalPrintServer(PrintSystemDesiredAccess.AdministrateServer))
	{
		Console.WriteLine(String.Format("Print Server name: {0}", ps.Name));
		using (PrintQueue pq = new PrintQueue(ps, Settings.Default.PrinterQueueName, PrintSystemDesiredAccess.AdministratePrinter))
		{
			Console.WriteLine(String.Format("Print Queue name: {0}", pq.Name));
			Console.WriteLine(String.Format("    Number of jobs: {0}", pq.NumberOfJobs));
			if (pq.NumberOfJobs > 0)
			{
				pq.Purge();
				pq.Refresh();
				DateTime datTimeout = DateTime.Now.AddSeconds(Settings.Default.QueueClearTimeout_sec);
				while ((pq.NumberOfJobs > 0) && (DateTime.Now < datTimeout))
				{
					Thread.Sleep(500);
					pq.Refresh();
				}
				Console.WriteLine(String.Format("    After Purge(), number of jobs: {0}", pq.NumberOfJobs));
			}
		}
	}
}
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900