detect print job completion from vbscript

  • Thread starter Thread starter Bruce Hensley
  • Start date Start date
B

Bruce Hensley

Using a loop of vbscript code like this, I am sending large collections of
files (of different types) to print on a network printer ...

oFolder.ParseName(File.name).InvokeVerb("&Print")

It is important that they print in the order they are sent from the script.
This does not happen unless I make the script pause for a period of time
between files. I suspect this is because they are sent asynchronously and
some get through the open application-load-spool process faster.

If the files are about the same size and type, setting a pause slightly
greater than the time to print an average job seems to work. However, as
the conditions of the jobs vary, they get out of order without a large pause
(which makes all jobs take far longer than needed, and requires prediction
of an adequate pause length).

Is there a way to detect "completion" of each job sent with InvokeVerb so
that the next job can be sent when the last "completes"? I suspect that in
this sense "completion" means that it has completed spooling to the print
queue.

TIA,
Bruce
 
Bruce,
If you "know" what the name of the document is in the print queue, you
can use WMI to "pole" the print queue and determine when the document
leaves.

Here is an example (written in Object Rexx) - it should be easy to
convert to VBScript. Watch for line wraps!

strComputer = '.'
objWMIService =
..OleObject~GetObject("winmgmts:{impersonationLevel=impersonate}!\\"strComputer"\root\cimv2")

do until found_N_Q = .False
colPrintJobs=objWMIService~ExecQuery("SELECT * FROM Win32_PrintJob")
found_N_Q = .False
do objPrintJob over colPrintJobs
say objPrintJob~Document
if objPrintJob~Document = DocumentIAmLooking
found_N_Q = .True
end
call SysSleep 1
end

Hope this helps

Lee Peedin
VP RexxLA
 
Lee,

Thanks for the help. I've looked into WMI, but can't seem to make it work.
The salient pieces look like this ...

FileName = "MyTestFile.pdf"
FolderPath = "c:\temp"
Dim oShellApp
Set oShellApp = CreateObject("Shell.Application")
Dim oFolder
Set oFolder = oShellApp.Namespace(FolderPath)
oFolder.ParseName(FileName).InvokeVerb("&Print")
TempTime = Now()
print oWindow, TempTime & " Starting to watch"
WatchForStart
print oWindow, TempTime & " Finished"

Sub WatchForStart()
TempTime = Now()
TimeToQuit = DateAdd("s", 10, TempTime)
Do
Dim Status
If InQueue(FileName) <> "" Then
TempTime = Now()
print oWindow, TempTime & " Found in queue" & Status
WatchForEnd
Exit Do
End If
TempTime = Now()
print oWindow, TempTime & " Job didn't start yet"
Loop Until (Now > TimeToQuit)
End Sub

Function InQueue(lFileName)
InQueue = ""
On Error Resume Next
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_PrintJob",,48)
For Each objItem In colItems
If objItem.Name = lFileName Then
InQueue = " - S: " & objItem.Status & " JS: " & objItem.JobStatus
Exit For
End If
Next
End Function

As a result I get a "Starting to watch", a long string of "Job didn't start
yet"s, and a "Finished". The job prints a single page in under 2 seconds
during the 10 second monitoring period. So, it doesn't seem to be
recognizing the job or the job comes and goes before it can be caught by the
script (I tried sending a bigger job, but got the same response).

I'm also wondering if it would make sense to set up an event sink with WMI,
since what I'm after is to trap a print event? I've looked at some code for
this, but gotten lost in it.

Thanks again,
Bruce
 
You might want to try this query. The query interval (2) is in seconds.

SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA
Win32_PrintJob

There is also a __InstanceDeletion event which is fired when the print job
is completed.

Suresh
 
Back
Top