以编程方式测量打印作业时间

时间:2014-11-08 04:49:37

标签: vbscript

我需要测量打印作业时间,这意味着“发送打印命令”之间的时间。和'打印作业从打印队列中消失'

所以我试图通过脚本来做这些事情

  1. 搜索所有pdf文件
  2. 打印文件
  3. 获取打印时间(如上所述)
  4. 转到下一个文件并为所有文件执行以上操作
  5. 到目前为止这是我的工作(我省略了一些部分)

    For Each file In objFolder.Items
    '   check for the extension
        if objFSO.GetExtensionName(file.name) = "pdf" then
    '       invoke to print 
            file.InvokeVerbEx( "Print" )
    '       select print jobs
            Set Printers =  objWMIService.ExecQuery _
        ("Select * from Win32_PrintJob")
    
            For Each objPrinter in Printers     
                DateTime.Value = objPrinter.TimeSubmitted
                TimeinQueue = DateDiff("n", actualTime, Now)
                Wscript.Echo TimeinQueue
            Next
        end if
    next
    

    主要是我需要问一下如何从打印队列中消除打印作业的时间。

    我需要保留下一份工作,直到一份打印作业结束。 有任何想法吗 ?

2 个答案:

答案 0 :(得分:2)

没有简单的方法可以从脚本中获取该信息,因为当从打印队列中删除作业时,它就消失了。您可以为打印假脱机程序设置事件监视器,如下所示:

Set wmi = GetObject("winmgmts://./root/cimv2")
Set wbemDateTime = CreateObject("WbemScripting.SWbemDateTime")

qry = "SELECT * FROM __InstanceOperationEvent WITHIN 1 " & _
      "WHERE TargetInstance ISA 'Win32_PrintJob'"
Set mon = wmi.ExecNotificationQuery(qry)

Do
  Set evt = mon.NextEvent
  If evt.Path_.Class = "__InstanceDeletionEvent" Then
    wbemDateTime.Value = evt.TargetInstance.TimeSubmitted
    WScript.Echo evt.TargetInstance.Document & ": " & _
                 DateDiff("n", wbemDateTime.GetVarDate, Now)
  End If
Loop

但是,您必须从不同的脚本运行它,因为VBScript不支持多线程(即并行运行),因此事件处理程序循环将阻止其余的脚本操作。

如果你想在你的脚本中有一个粗略的值,你可以尝试这样的东西,但不要期望排队时间非常准确:

'singleton SWbemDateTime instance for time conversions
Set wbemDateTime = CreateObject("WbemScripting.SWbemDateTime")

'global list to keep track of printing documents
'MUST NOT BE MODIFIED FROM ANYWHERE EXCEPT CheckPrintQueue!
Set printingDocs = CreateObject("Scripting.Dictionary")

Function CheckPrintQueue
  Set printJobs = objWMIService.ExecQuery("SELECT * FROM Win32_PrintJob")
  Set currentDocs = CreateObject("Scripting.Dictionary")

  'get currently printing jobs from queue
  For Each job In printJobs
    currentDocs.Add job.Document, job.TimeSubmitted
  Next

  'compare global list to current list, print the queue time for documents
  'that are no longer queued, and remove them from the global list
  For Each doc In printingDocs.Keys
    If Not currentDocs.Exists(doc) Then
      wbemDateTime.Value = printingDocs(doc)
      WScript.Echo doc & ": " & DateDiff("n", wbemDateTime.GetVarDate, Now)
      printingDocs.Remove doc
    End If
  Next

  'add new documents to global list
  For Each doc In currentDocs.Keys
    If Not printingDocs.Exists(doc) Then printingDocs.Add doc, currentDocs(doc)
  Next

  CheckPrintQueue = printJobs.Count
End Function

For Each file In objFolder.Items
  If objFSO.GetExtensionName(file.name) = "pdf" Then
    file.InvokeVerbEx "Print"
    CheckPrintQueue
  End If
Next

'wait until all jobs finished printing
Do While CheckPrintQueue > 0
  WScript.Sleep 100
Loop

答案 1 :(得分:1)

我一直在寻找确切的东西,我简单地总结了ansgar的剧本以获得我想要的东西。 它获取每个pdf文件并打印5次(因此我可以获得更好的平均值),同时获取时间。最终将它们打印到csv文件中。直到一个人从打印队列中消失,其他人等待等待。不是100%的精确度,但足以进行性能比较 可能有用(请纠正我的错误,如果有的话)

Dim objFSO, outFile
const forAppending = 8
const useDefault = -2

'Output File name
fileName = ".\output.csv"

Set objFSO = CreateObject("Scripting.FileSystemObject")
set outFile = objFSO.OpenTextFile(fileName, forAppending, true, useDefault)

'write heading to output file
outFile.WriteLine("Filename,1,2,3,4,5")

'get current Folder
strFolder = Replace(wscript.scriptfullname,wscript.scriptname,".\")
strFolder = objFSO.getFolder(strFolder)

'Open the Shell Folders object
Set objShell  = CreateObject( "Shell.Application" )

'Create an object for the specified file's parent folder
Set objFolder = objShell.Namespace( strFolder )

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

For Each file In objFolder.Items
  If objFSO.GetExtensionName(file.name) = "pdf" Then
    'write in to out file
    outFile.write(file.name)
    outFile.writeLine ""

    'outer loop for 5 times per each file
    index = 0
    do while index < 5
      'if already doing a printing do not start a new one
      if CheckPrintQueue() = 0 then
         file.InvokeVerbEx "Print"
         startTime = timer
         waitTostart
      'if first time on outer loop it should be empty queue
      else 
        if index = 0 then 
          wscript.echo "queue doesnt empty"
          finish
        end if
      end if
      'wait until all jobs finished printing
      waitToEnd
      'count time
      ellapsTime = timer - startTime
      'write in to out file   
      outFile.write(",")
      outFile.Write(ellapsTime)   
      index = index + 1
    loop
  End If
Next

outFile.Close
'----------------function CheckPrintQueue-----------------------
Function CheckPrintQueue()
  Set printJobs = objWMIService.ExecQuery("SELECT * FROM Win32_PrintJob")
  Set currentDocs = CreateObject("Scripting.Dictionary")

  CheckPrintQueue = printJobs.Count
End Function
'----------------end of function-----------------

sub waitTostart
  Do 
    WScript.Sleep 100
    'check print queue
    printJobCount = CheckPrintQueue()
  Loop until printJobCount > 0
end sub

sub waitToEnd
  Do 
    WScript.Sleep 100
    'check print queue
    printJobCount = CheckPrintQueue()
  Loop until printJobCount = 0
end sub

sub finish
  outFile.Close
  objFSO = nothing
  objFolder = nothing
  objShell = nothing
  objWMIService = nothing
  wscript.quit 1
end sub