JeffL Posted January 8, 2010 Share Posted January 8, 2010 (edited) I'm really stumped here. I feel like i've tried everything. Basically I wrote a script to run through a mailbox and print out all attachments of a certain document type. The other documents work, but not PDFs via Adobe Reader. It works via Foxit, but I'm the only one that uses this and it is a script for other people. What I tried to run originally was: ShellExecuteWait($sFilePath, "", "", "print", @SW_HIDE) but Reader doesn't close when complete so it Waits indefinitely. I tried some switches such as ShellExecuteWait($sFilePath, " /h /p", "", "print", @SW_HIDE) but no differing behavior and through my research, I am led to believe it is the Reader version suppressing this silent print behavior. The main problem here is that it NEEDS to wait for the process to complete or it won't print at all, but it also needs to close Reader. So I looked for methods for waiting for the print... I got this function working: func getPrintInfo($sFileName, $sInfo) ;$sinfo = caption,host,id,owner $wbemFlagReturnImmediately = 0x10 $wbemFlagForwardOnly = 0x20 $colItems = "" $strComputer = "localhost" $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_PrintJob", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) if IsObj($colItems) then for $objItem In $colItems if $objItem.Document = $sFileName then switch $sInfo Case "caption" return $objItem.Caption Case "host" return $objItem.HostPrintQueue Case "id" return $objItem.JobId Case "owner" return $objItem.Owner endswitch endif next endif return 0 endfunc Then did some while loops to see when the job existed in the queue or not. The output works if you pause a job and do the query, but it fails in my implementation and i have a feeling the print job is not even popping into the queue long enough for a successful query. Then I tried: ProcessWait("AcroRd32.exe", 5) ProcessClose("AcroRd32.exe") But again it kills the print with the process before it can begin. I'm completely stumped. Obviously I could just put a regular Sleep after the ShellExecute, but I want as clean a method as possible for this, but it seems like I'm getting intercepted at every turn. Anyone? :\ Edited January 8, 2010 by JeffL Link to comment Share on other sites More sharing options...
gte Posted January 9, 2010 Share Posted January 9, 2010 Not 100% sure what this function does, maybe polls the print service or print queue? Couldn't you do a do/until calling the function do getPrintInfo($sFileName, $sInfo) ; sleep 100 if it loops through to quickly until return = 0 ProcessClose("AcroRd32.exe") I'm really stumped here. I feel like i've tried everything. Basically I wrote a script to run through a mailbox and print out all attachments of a certain document type. The other documents work, but not PDFs via Adobe Reader. It works via Foxit, but I'm the only one that uses this and it is a script for other people. What I tried to run originally was: ShellExecuteWait($sFilePath, "", "", "print", @SW_HIDE) but Reader doesn't close when complete so it Waits indefinitely. I tried some switches such as ShellExecuteWait($sFilePath, " /h /p", "", "print", @SW_HIDE) but no differing behavior and through my research, I am led to believe it is the Reader version suppressing this silent print behavior. The main problem here is that it NEEDS to wait for the process to complete or it won't print at all, but it also needs to close Reader. So I looked for methods for waiting for the print... I got this function working: func getPrintInfo($sFileName, $sInfo) ;$sinfo = caption,host,id,owner $wbemFlagReturnImmediately = 0x10 $wbemFlagForwardOnly = 0x20 $colItems = "" $strComputer = "localhost" $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_PrintJob", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) if IsObj($colItems) then for $objItem In $colItems if $objItem.Document = $sFileName then switch $sInfo Case "caption" return $objItem.Caption Case "host" return $objItem.HostPrintQueue Case "id" return $objItem.JobId Case "owner" return $objItem.Owner endswitch endif next endif return 0 endfunc Then did some while loops to see when the job existed in the queue or not. The output works if you pause a job and do the query, but it fails in my implementation and i have a feeling the print job is not even popping into the queue long enough for a successful query. Then I tried: ProcessWait("AcroRd32.exe", 5) ProcessClose("AcroRd32.exe") But again it kills the print with the process before it can begin. I'm completely stumped. Obviously I could just put a regular Sleep after the ShellExecute, but I want as clean a method as possible for this, but it seems like I'm getting intercepted at every turn. Anyone? :\ HP OpenView ServiceCenter keep alive scriptRemote Desktop Login Script Link to comment Share on other sites More sharing options...
IQ9003 Posted January 11, 2010 Share Posted January 11, 2010 I've also created a script to print PDF's from a mailbox. (I wasn't able to create a full silent print). But I came up with the following: ShellExecuteWait ("C:\Program Files\Adobe\Reader 9.0\Reader\AcroRd32.exe" ,"/t " & $tempdir & $file & " " & $PrinterName, @SW_MINIMIZE) WinWait($file,"") Winwait("Adobe Reader") When Acrobat Reader prints the file (commandline switch: "/t") the windowtitle of adobe Reader changes to the filename, when the print is completed/queued it changes back to "Adobe Reader". At that point it's safe to continue you're code. (I use winkill to close de AcroRd32.exe) Link to comment Share on other sites More sharing options...
ReFran Posted January 12, 2010 Share Posted January 12, 2010 (edited) You can use DDE printing. HTH, Reinhard #include <DDEML.au3> ;<= load down from examples #include <DDEMLClient.au3> ;<= load down from examples $FnToPrt = "C:\Test.pdf" ShellExecute("AcroRD32.exe","/h") Opt("WinTitleMatchMode", 2) WinWait("Reader","",10) sleep(500) $szService = "Acroview" $szTopic = "Control" $szCommand = '[FilePrintSilent("'&$FnToPrt&'")][AppExit()]' _DDEMLClient_Execute($szService, $szTopic, $szCommand) Edited January 12, 2010 by ReFran Link to comment Share on other sites More sharing options...
JeffL Posted January 13, 2010 Author Share Posted January 13, 2010 (edited) the logic here is sound but the execution gives me the same results. processclose("acrord32.exe") kills adobe before it can send the job to the print queue. not sure why.... if i put a msgbox or sleep before the process close, itll print I've also created a script to print PDF's from a mailbox. (I wasn't able to create a full silent print). But I came up with the following: ShellExecuteWait ("C:\Program Files\Adobe\Reader 9.0\Reader\AcroRd32.exe" ,"/t " & $tempdir & $file & " " & $PrinterName, @SW_MINIMIZE) WinWait($file,"") Winwait("Adobe Reader") When Acrobat Reader prints the file (commandline switch: "/t") the windowtitle of adobe Reader changes to the filename, when the print is completed/queued it changes back to "Adobe Reader". At that point it's safe to continue you're code. (I use winkill to close de AcroRd32.exe) Edited January 13, 2010 by JeffL Link to comment Share on other sites More sharing options...
JeffL Posted January 13, 2010 Author Share Posted January 13, 2010 (edited) I have no idea what DDE is, but this worked! Thank you! I'll have to do some studying up on this UDF. You can use DDE printing. HTH, Reinhard #include <DDEML.au3> ;<= load down from examples #include <DDEMLClient.au3> ;<= load down from examples $FnToPrt = "C:\Test.pdf" ShellExecute("AcroRD32.exe","/h") Opt("WinTitleMatchMode", 2) WinWait("Reader","",10) sleep(500) $szService = "Acroview" $szTopic = "Control" $szCommand = '[FilePrintSilent("'&$FnToPrt&'")][AppExit()]' _DDEMLClient_Execute($szService, $szTopic, $szCommand) Edited January 13, 2010 by JeffL Link to comment Share on other sites More sharing options...
ReFran Posted January 13, 2010 Share Posted January 13, 2010 I have no idea what DDE is, but this worked! Thank you!I'll have to do some studying up on this UDF.DDE is an older method for interapplications communication (before ActiveX).You can work with that for example in the File associations. So you can do a little bit more then only command line option. Adobe complicate in every new version the using of Javascript and ActiveX because of security reasons. But they didn't touch old DDE for years. So DDE printing is treated as the only reliable method for silent/hidden printing using Reader, if you want to close after printing.Another method, according to your first post, would be to check only if printing startet: if Winexists('CLASS:PrintUI_PrinterQueue]',"")=0 then ;msgbox(0,"","printing") WinClose($Readerhandle)endifIf printing startet you can Reader ask to close (Winclose).Reader will only close if printing is finished.If you interested in this method I may extract the complete code/loop from a bigger script.best regards, Reinhard Link to comment Share on other sites More sharing options...
JeffL Posted January 13, 2010 Author Share Posted January 13, 2010 DDE is an older method for interapplications communication (before ActiveX).You can work with that for example in the File associations. So you can do a little bit more then only command line option. Adobe complicate in every new version the using of Javascript and ActiveX because of security reasons. But they didn't touch old DDE for years. So DDE printing is treated as the only reliable method for silent/hidden printing using Reader, if you want to close after printing.Another method, according to your first post, would be to check only if printing startet: if Winexists('CLASS:PrintUI_PrinterQueue]',"")=0 then ;msgbox(0,"","printing") WinClose($Readerhandle)endifIf printing startet you can Reader ask to close (Winclose).Reader will only close if printing is finished.If you interested in this method I may extract the complete code/loop from a bigger script.best regards, ReinhardThanks for that last tip as well. I tried doing that with my function that queried the print queue, but couldnt get it to work. Is PrintUI_PrinterQueue the notification bubble that pops up when a print has been sent? Link to comment Share on other sites More sharing options...
ReFran Posted January 15, 2010 Share Posted January 15, 2010 ... Is PrintUI_PrinterQueue the notification .... Yes and it closes automatic is print job is done. Excuse the delay. I work in a finance department and we are on the way to finalise our closing. Attached an quick example, extracted from an older, big script. But DDE should work better. best regards, Reinhard Opt("WinTitleMatchMode", 2) $FnToPrt = "C:\Test.pdf" ShellExecute("AcroRD32.exe","/h /p"&" """&$FnToPrt&"""" ,"","", @SW_HIDE ) $OK = ProcessWait("AcroRd32.exe",20) if $OK = 0 Then msgbox(0,"","Coudn't start process") ;return 0 exit endif GLOBAL $PID = WinGetProcess ("Reader") GLobal $handle = WinGethandle ("Reader") $timer = 0 Do sleep(1000) $timer +=+1 if Winexists('[CLASS:PrintUI_PrinterQueue]',"")=0 then ;msgbox(0,"","Printing finished") WinClose($handle) endif if $timer = 60 then msgbox(0,"","Timeout") ;return 0 exitloop endif until ProcessExists($PID) = 0 Link to comment Share on other sites More sharing options...
ijourneaux Posted July 8, 2010 Share Posted July 8, 2010 You can use DDE printing. HTH, Reinhard #include <DDEML.au3> ;<= load down from examples #include <DDEMLClient.au3> ;<= load down from examples $FnToPrt = "C:\Test.pdf" ShellExecute("AcroRD32.exe","/h") Opt("WinTitleMatchMode", 2) WinWait("Reader","",10) sleep(500) $szService = "Acroview" $szTopic = "Control" $szCommand = '[FilePrintSilent("'&$FnToPrt&'")][AppExit()]' _DDEMLClient_Execute($szService, $szTopic, $szCommand) How would you structure the $szCommand to specify the printer to be used? Link to comment Share on other sites More sharing options...
tpek Posted August 9, 2010 Share Posted August 9, 2010 Hello. Full silent pdf print example. You need Foxit Reader only. $def = RegRead("HKCU\Software\Microsoft\Windows Nt\CurrentVersion\Windows", "Device") $printer = "HP Color LaserJet CP1215,winspool,Ne01:" RegWrite("HKCU\Software\Microsoft\Windows Nt\CurrentVersion\Windows", "Device", "REG_SZ", $printer) $file = "C:\a.pdf" RunWait('C:\Program Files\Foxit Software\Foxit Reader\Foxit Reader.exe /p "' & $file & '"') RegWrite("HKCU\Software\Microsoft\Windows Nt\CurrentVersion\Windows", "Device", "REG_SZ", $def) Enjoy Link to comment Share on other sites More sharing options...
wysocki Posted August 19, 2010 Share Posted August 19, 2010 I tried the DDE example and got a ton of errors. Then I updated my AutoIt installation and still had a ton until I commented out the two includes. Now I only get one error but I can't find anything on it when I search. Here's my code and the error message. ;#include <DDEML.au3> ;<= load down from examples ;#include <DDEMLClient.au3> ;<= load down from examples $FnToPrt = "x:\Temp2\1.pdf" ShellExecute("C:\Program Files\Adobe\Acrobat 9.0\Acrobat\Acrobat.exe","/h") Opt("WinTitleMatchMode", 2) WinWait("Acrobat","",10) sleep(500) $szService = "Acroview" $szTopic = "Control" $szCommand = '[FilePrintSilent("'&$FnToPrt&'")][AppExit()]' _DDEMLClient_Execute($szService, $szTopic, $szCommand) Exit --------------------------------------------------------------------------------------- ERROR: _DDEMLClient_Execute(): undefined function. _DDEMLClient_Execute($szService, $szTopic, $szCommand) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ Link to comment Share on other sites More sharing options...
ReFran Posted August 22, 2010 Share Posted August 22, 2010 (edited) For me it works furtheron: AdobeReader v9.3 / AutoIt v3.3.5.3 (beta) Because I saved a backup I made a textcomparison: in DDEML.au3 I changed line 604: from: If @ProcessorArch = "IA64" Or @ProcessorArch = "X64" Then $res = 64 to: If @autoItx64 = 1 Then $res = 64 HTH, Reinhard Edited August 22, 2010 by ReFran Link to comment Share on other sites More sharing options...
wysocki Posted August 23, 2010 Share Posted August 23, 2010 Hmm, I didn't have that on my line 604, then I downloaded the latest version and it's not on line 604 there either. In fact, $ProcessorArch isn't even found in the file! However, the latest version of ddeml.au3 did fix the problem I was having, I must have clicked on the wrong download link when I got the include file. Now the problem is that the DDE command still fails once in a while (no error message, it just doesn't print). I have Adobe Acrobat Pro instead of the Reader so maybe that's the issue. The first time I run the app, it flashes an Acrobat window then minimizes it - nothing prints. The next time I run the app, the Acrobat window does NOT minimize - but it prints! If I remove the "/h" parameter from the shellexecute, it doesn't minimize - and nothing prints. I give up. I'll just put a send('^p{enter}') in and sleep for a few seconds. Link to comment Share on other sites More sharing options...
ReFran Posted August 24, 2010 Share Posted August 24, 2010 Hi, DDE printing should work for Acrobat Pro and Reader, like the command-line option. However if you want to print via AcrobatPro you can use ActiveX, how it is described in the SKD (Interapplication Communication = IAC section). Attached a script which should do what you want (for AcrobatPro). HTH, Reinhard $fileIn = "C:\Test.pdf" ;; state the full path of the file to print $App = ObjCreate("AcroExch.App") ;; start Adobe Acrobat ;$App.Show ;; show Acrobat or comment out for hidden mode $AVDoc = ObjCreate("AcroExch.AVDoc") ;; connect to Ac Viewer $AVDoc.Open($fileIn,"") ;; Open a file into viewer $PDDoc = $AVDoc.GetPDDoc ;; Get the Doc opened in the viewer $JSO = $PDDoc.GetJSObject ;; Connect to Acrobat JS $JSO.app.alert("Hi, file is open.Press Ok for printing") ;; Display a MsgBox ;$JSO.print("bUI","nStart","nEnd","bSilent","bShrinkToFit",..) $nEnd=$jso.numPages-1 ;;$nEnd zeroBase $JSO.print(False,0,$nEnd,False,True) ;; print with some options $JSO.closeDoc(True) ;; close active document $App.CloseAllDocs ;; - or - close all docs $App.exit Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now