Delete most recent Windows print job in AutoIT (via WMIC ?)

Posted on 2014-04-03
Last Modified: 2014-04-22
I want to delete the most recently submitted print job with a particular document name.  I will know its submission time to within a second.

I'm working in AutoIT.  Invoking WMIC looks like a promising option...
...however I don't understand how date formats are handled in WMIC yet.
So, I was expecting to be able to do something like
#include <Process.au3>
$ReturnValue = _RunDos('WMIC Printjob WHERE (Document="ScreenPrint32 v3.5" AND TimeSubmitted > 20140404003556.000) Delete')
ConsoleWrite("$ReturnValue = " & $ReturnValue & @CRLF)

Open in new window

No dice.  

So, just working in a command prompt, the following does work if the time value is compared as an '=' and I copy and paste in the exact TimeSubmitted in quotes. ('delete' changed to 'get' for ease of testing)  But I want to be able to do a time comparison of '>' and supply my own date.
WMIC Printjob WHERE (Document="ScreenPrint32 v3.5" AND TimeSubmitted = '20140404003556.912000-240') GET

Open in new window

Is there an easy way to identify & delete the most recent job without even messing with TimeSubmitted?
Even if I get the WMIC aspect sorted out (for which I'd be way grateful), I won't get a return value in AutoIT to know of success.  (When I plug in functional WMIC printjob delete statements, the return value is always 0.)  What's the best overall approach?
Thank you.
Question by:nosliwde99
  • 3
  • 3
  • 2
LVL 53

Assisted Solution

by:Joe Winograd, EE MVE
Joe Winograd, EE MVE earned 50 total points
ID: 39979018
> Is there an easy way to identify & delete the most recent job without even messing with TimeSubmitted?

Seems to me you can simply look for the file with the most recent date/time stamp in <%SystemRoot%\SYSTEM32\SPOOL\PRINTERS>, which is where print jobs are located. The files have .SPL and .SHD file types. Have your AutoIT code look for the most recent of each file type and delete them. Before deleting them, your AutoIT code should stop the spooler with this (elevated) command:

net stop spooler

After deleting them, start the spooler with this (elevated) command:

net start spooler

I use a fork of AutoIT called AutoHotkey, so I can't help you with the AutoIT code for doing the above, but with AutoHotkey in W7, it shouldn't be difficult, and I'm guessing that it's also not tough with AutoIT. Btw, I don't think I'd use WMIC — probably just the built-in file functions (to sort by date and delete) and RunWait to run <net.exe>. Regards, Joe
LVL 29

Accepted Solution

matrixnz earned 450 total points
ID: 39979067
You can use something like this, the original code was written by someone else, I just altered it for your purposes.  You could of course add more conditions to the delete function, for example base it on printer name, or owner etc..   Which is why I left all the object items in the FNC_PRINTJOB_LIST.

Hope that makes sense.


#include <Array.au3>

#Region Global Variables
	Global $STR_COMPUTER = @ComputerName
	Global $wbemFlagReturnImmediately	= 0x10
	Global $wbemFlagForwardOnly			= 0x20
#EndRegion Global Variables

; Request a PrintJob List Sorted by Time Submitted

; Display the PrintJob List

; Delete the Top Listed PrintJob using JobID

; Request an updated PrintJob List Sorted by Time Sumitted

; Display the PrintJob List

; Description:      Returns the PrintJob information in an array.
; Parameter(s):     $aPrintJobInfo - By Reference - PrintJob Information array.
; Requirement(s):   None
; Return Value(s):  On Success - Returns array of PrintJob Information.
;						$aPrintJobInfo[$i][0]	= Name
;						$aPrintJobInfo[$i][1]	= DataType
;						$aPrintJobInfo[$i][2]	= Document
;						$aPrintJobInfo[$i][3]	= DriverName
;						$aPrintJobInfo[$i][4]	= Description
;						$aPrintJobInfo[$i][5]	= ElapsedTime
;						$aPrintJobInfo[$i][6]	= HostPrintQueue
;						$aPrintJobInfo[$i][7]	= JobId
;						$aPrintJobInfo[$i][8]	= JobStatus
;						$aPrintJobInfo[$i][9]	= Name
;						$aPrintJobInfo[$i][10]	= Notify
;						$aPrintJobInfo[$i][11]	= Owner
;						$aPrintJobInfo[$i][12]	= PagesPrinted
;						$aPrintJobInfo[$i][13]	= Parameters
;						$aPrintJobInfo[$i][14]	= PrintProcessor
;						$aPrintJobInfo[$i][15]	= Priority
;						$aPrintJobInfo[$i][16]	= Size
;						$aPrintJobInfo[$i][17]	= StartTime
;						$aPrintJobInfo[$i][18]	= Status
;						$aPrintJobInfo[$i][19]	= StatusMask
;						$aPrintJobInfo[$i][20]	= TimeSubmitted
;						$aPrintJobInfo[$i][21]	= TotalPages
;						$aPrintJobInfo[$i][22]	= UntilTime
;                   On Failure - @error = 1 and Returns 0
;								@extended = 1 - Array contains no information.
;											2 - $colItems isnt an object.
; Author(s):        Jarvis Stubblefield (support "at" vortexrevolutions "dot" com)
; Note(s):
Func FNC_PRINTJOB_LIST(ByRef $aPrintJobInfo)
	Local $colItems, $objWMIService, $objItem
	Dim $aPrintJobInfo[1][23], $i = 1

	$objWMIService = ObjGet("winmgmts:\\" & $STR_COMPUTER & "\root\CIMV2")
	$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_PrintJob", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

	If IsObj($colItems) Then
		For $objItem In $colItems
			ReDim $aPrintJobInfo[UBound($aPrintJobInfo) + 1][23]
			$aPrintJobInfo[$i][0]	= $objItem.Name
			$aPrintJobInfo[$i][1]	= $objItem.DataType
			$aPrintJobInfo[$i][2]	= $objItem.Document
			$aPrintJobInfo[$i][3]	= $objItem.DriverName
			$aPrintJobInfo[$i][4]	= $objItem.Description
			$aPrintJobInfo[$i][5]	= __StringToDate($objItem.ElapsedTime)
			$aPrintJobInfo[$i][6]	= $objItem.HostPrintQueue
			$aPrintJobInfo[$i][7]	= $objItem.JobId
			$aPrintJobInfo[$i][8]	= $objItem.JobStatus
			$aPrintJobInfo[$i][9]	= $objItem.Name
			$aPrintJobInfo[$i][10]	= $objItem.Notify
			$aPrintJobInfo[$i][11]	= $objItem.Owner
			$aPrintJobInfo[$i][12]	= $objItem.PagesPrinted
			$aPrintJobInfo[$i][13]	= $objItem.Parameters
			$aPrintJobInfo[$i][14]	= $objItem.PrintProcessor
			$aPrintJobInfo[$i][15]	= $objItem.Priority
			$aPrintJobInfo[$i][16]	= $objItem.Size
			$aPrintJobInfo[$i][17]	= __StringToDate($objItem.StartTime)
			$aPrintJobInfo[$i][18]	= $objItem.Status
			$aPrintJobInfo[$i][19]	= $objItem.StatusMask
			$aPrintJobInfo[$i][20]	= __StringToDate($objItem.TimeSubmitted)
			$aPrintJobInfo[$i][21]	= $objItem.TotalPages
			$aPrintJobInfo[$i][22]	= __StringToDate($objItem.UntilTime)
			$i += 1
		$aPrintJobInfo[0][0] = UBound($aPrintJobInfo) - 1
		If $aPrintJobInfo[0][0] < 1 Then
			SetError(1, 1, 0)
		_ArraySort($ARR_PRINTJOB, 1, 1, 0, 20)
		SetError(1, 2, 0)

	Local $colItems, $objWMIService, $objItem
	$objWMIService = ObjGet("winmgmts:\\" & $STR_COMPUTER & "\root\CIMV2")
	$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_PrintJob Where JobId = '" &$PAR_PRINTJOB & "'", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
	;$colItems =  $objWMIService.ExecQuery ("Select * from Win32_PrintJob Where JobId =" & $PAR_PRINTJOB)
	For $objItem in $colItems

Func __StringToDate($dtmDate)
	Return (StringMid($dtmDate, 5, 2) & "/" & _
			StringMid($dtmDate, 7, 2) & "/" & StringLeft($dtmDate, 4) _
			& " " & StringMid($dtmDate, 9, 2) & ":" & StringMid($dtmDate, 11, 2) & ":" & StringMid($dtmDate,13, 2))
EndFunc ;__StringToDate Function created by SvenP Modified by JSThePatriot

Open in new window


Author Comment

ID: 39979469
Thank you both.
Joe, I've done this approach before, and the print window has behaved squirrely afterward.  I'm wanting to hang with something rock solid.  Sorry I didn't mention this in the op.
Matrixnz, I think this is just what I'm looking for...will dig in tomorrow.
Ransomware: The New Cyber Threat & How to Stop It

This infographic explains ransomware, type of malware that blocks access to your files or your systems and holds them hostage until a ransom is paid. It also examines the different types of ransomware and explains what you can do to thwart this sinister online threat.  

LVL 53

Expert Comment

by:Joe Winograd, EE MVE
ID: 39979495
> print window has behaved squirrely afterward

Hmmm, interesting! I haven't seen bad behavior after stopping the spooler, deleting spool files, then restarting the spooler. Anyway, good luck with Jarvis Stubblefield's script as modified by matrixnz. I'll keep an eye on this thread to see how it goes for you. Regards, Joe
LVL 29

Expert Comment

ID: 39979582
The original code is part of the following excellent UDF by JSPatriot if anyone is interested.  I find it a good place to start to get references to wmi objects.

LVL 29

Expert Comment

ID: 39989932
Hi nosliwde99

Were you able to test the code above?  Do you require any additional assistance?


Author Comment

ID: 40001457
Sorry for the delay.  Was slammed with a different project that pulled me in a different direction.  Just re-surfacing.

Author Closing Comment

ID: 40016292
matrixnz, this is perfect!  Thank you so much.

Featured Post

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you’re thinking to yourself “That description sounds a lot like two people doing the work that one could accomplish,” you’re not alone.
On some Windows 7 (SP1) computers, Windows Update becomes super slow even the computer is reasonably fast.  There's one solution that seemed to have worked well for me (after trying a few other suggested solutions).
This Micro Tutorial will give you a introduction in two parts how to utilize Windows Live Movie Maker to its maximum editing capability. This will be demonstrated using Windows Live Movie Maker on Windows 7 operating system.

808 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question