Solved

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

Posted on 2014-04-03
8
1,044 Views
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.
Ed
0
Comment
Question by:nosliwde99
  • 3
  • 3
  • 2
8 Comments
 
LVL 51

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
0
 
LVL 29

Accepted Solution

by:
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.

Cheers

#include <Array.au3>

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

; Request a PrintJob List Sorted by Time Submitted
FNC_PRINTJOB_LIST($ARR_PRINTJOB)

; Display the PrintJob List
_ArrayDisplay($ARR_PRINTJOB)

; Delete the Top Listed PrintJob using JobID
If $ARR_PRINTJOB[0][0] >= 1 Then FNC_PRINTJOB_DELETE($ARR_PRINTJOB[1][7])

; Request an updated PrintJob List Sorted by Time Sumitted
FNC_PRINTJOB_LIST($ARR_PRINTJOB)

; Display the PrintJob List
_ArrayDisplay($ARR_PRINTJOB)

;===============================================================================
; 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
		Next
		$aPrintJobInfo[0][0] = UBound($aPrintJobInfo) - 1
		If $aPrintJobInfo[0][0] < 1 Then
			SetError(1, 1, 0)
		EndIf
		_ArraySort($ARR_PRINTJOB, 1, 1, 0, 20)
	Else
		SetError(1, 2, 0)
	EndIf
EndFunc ;FNC_PRINTJOB_LIST

Func FNC_PRINTJOB_DELETE($PAR_PRINTJOB)
	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
		$objItem.Delete_
	Next
EndFunc

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

0
 

Author Comment

by:nosliwde99
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.
0
 
LVL 51

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
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 29

Expert Comment

by:matrixnz
ID: 39979582
The original code is part of the following excellent UDF by JSPatriot if anyone is interested.
http://www.autoitscript.com/forum/topic/29404-computer-info-udfs/.  I find it a good place to start to get references to wmi objects.

Cheers
0
 
LVL 29

Expert Comment

by:matrixnz
ID: 39989932
Hi nosliwde99

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

Cheers
0
 

Author Comment

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

Author Closing Comment

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

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Suggested Solutions

When you start your Windows 10 PC and got an "Operating system not found" error or just saw  "Auto repair for startup". After a while, you have entered a loop for Auto repair which does not fix anything and you will be in a  panic as all your work w…
Possible fixes for Windows 7 and Windows Server 2008 updating problem. Solutions mentioned are from Microsoft themselves. I started a case with them from our Microsoft Silver Partner option to open a case and get direct support from Microsoft. If s…
This Micro Tutorial will give you a basic overview of Windows DVD Burner through its features and interface. This will be demonstrated using Windows 7 operating system.
The viewer will learn how to successfully download and install the SARDU utility on Windows 7, without downloading adware.

747 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now