DesireDenied Posted August 27, 2020 Share Posted August 27, 2020 (edited) Hey Guys, I have noticed something really interesting. All though actually every single application works perfectly fine with all possible show flags, acrobat reader does not really care about them. The thing is I am trying to run printing multiple documents in background, but reader is always showing the window, instead of keeping it hidden or minimized as I would wish. ShellExecute($sFile, '', '', 'print', @SW_HIDE) Has anyone else experienced same problem on windows 10? If not, do you have any suggestions, how to solve the problem to run printing pdf files completely in background? Thanks Edited August 27, 2020 by DesireDenied Link to comment Share on other sites More sharing options...
Marc Posted August 28, 2020 Share Posted August 28, 2020 I feel your pain. Tried to print pdfs via acrobat from python - the god-damn window always opens. Only idea I have is to wait for the window and then minimize it Any of my own codes posted on the forum are free for use by others without any restriction of any kind. (WTFPL) Link to comment Share on other sites More sharing options...
Maximus1 Posted August 28, 2020 Share Posted August 28, 2020 You can try this. it is unfinished but works well. It has some elements i will insert in the next weeks if i need them. expandcollapse popup#include <Constants.au3> #include <GuiConstants.au3> #include <FileConstants.au3> #include <EditConstants.au3> #include <file.au3> Opt("MustDeclareVars", 1) Opt("TrayIconHide", 1) Local $dropFile_1, $dropFile_2, $label, $msg, $dropFile_txt, $szDrive, $szDir, $szFName, $szExt, $print_pid, $default, $Printer,$Printer_setback ;Abfrage Standard Drucker $default = RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows", "Device") ;default Printer auslesen $Printer_setback = $default If Not StringInStr($default, "FinePrint") Then If Not IsDeclared("iMsgBoxAnswer") Then Local $iMsgBoxAnswer $iMsgBoxAnswer = MsgBox(52, "Fineprint", "Ich benötige Fineprint als Standard Drucker." & @CRLF & "Jetzt setzen?", 15) Select Case $iMsgBoxAnswer = 6 ;Yes RunWait('RUNDLL32 PRINTUI.DLL,PrintUIEntry /y /n "FinePrint"') ;default printer setzen $default = RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows", "Device") ;default Printer auslesen Case $iMsgBoxAnswer = 7 ;No Case $iMsgBoxAnswer = -1 ;Timeout EndSelect EndIf ;Ende - Abfrage Standard Drucker ; Gui erstellen GUICreate('Drag and Drop', 150, 170, @DesktopWidth / 2 - 192, _ @DesktopHeight / 2 - 235, -1, $DS_MODALFRAME + $WS_EX_ACCEPTFILES + $WS_EX_TOPMOST) GUICtrlCreateGroup("", 5, 5, 140, 90) $dropFile_1 = GUICtrlCreateLabel($dropFile_1, 10, 20, 130, 70, -1) GUICtrlSetData($dropFile_1, @LF & @LF & "Datei hier ablegen") GUICtrlSetState($dropFile_1, $GUI_DROPACCEPTED) GUICtrlSetTip($dropFile_1, 'Zu druckende Datei in dieses Feld ziehen') $Printer = GUICtrlCreateLabel($default, 10, 150, 140, 60, -1) Local $idStart = GUICtrlCreateButton("Start", 15, 110, 100, 25) GUICtrlSetState($idStart, 128) Local $idset = GUICtrlCreateButton("", 130, 120, 15, 15) GUICtrlSetTip($idset, 'Drucker auf FinePrint umstellen') Local $sFile1 GUISetState() ;Ende - Gui erstellen While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE GUIDelete() ExitLoop Case $GUI_EVENT_DROPPED If @GUI_DropId = $dropFile_1 Then Dim $Path = @GUI_DragFile _PathSplit(@GUI_DragFile, $szDrive, $szDir, $szFName, $szExt) GUICtrlSetData($dropFile_1, $szFName & $szExt) GUICtrlSetState($idStart, 64) EndIf Case $idStart $sFile1 = GUICtrlRead($dropFile_1) If $sFile1 Then GUICtrlSetState($idStart, 128) GUICtrlSetData($dropFile_1, "In Arbeit...") ShellExecute(@GUI_DragFile, "", "", "Print") If @error Then Exit Sleep(5000) GUICtrlSetState($idStart, 64) GUICtrlSetData($dropFile_1, "Datei hier ablegen") Else MsgBox($MB_SYSTEMMODAL, "Error", "Keine Datei zum Drucken eingefügt") EndIf Case $idset RunWait('RUNDLL32 PRINTUI.DLL,PrintUIEntry /y /n "FinePrint"');default printer setzen $default = RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows", "Device") ;default Printer auslesen GUICtrlSetData($Printer, $default) MsgBox(262192, "", "Der Drucker wurde auf FinePrint umgestellt.") ;MsgBox features: Title=No, Text=Yes, Buttons=OK, Icon=Warning, Miscellaneous=Top-most attribute EndSwitch WEnd DesireDenied 1 Link to comment Share on other sites More sharing options...
Nine Posted August 28, 2020 Share Posted August 28, 2020 You could also try to use COM object to print. I have been using it successfully like this : expandcollapse popup#include <Constants.au3> #include <GUIConstants.au3> Global $oMyError = ObjEvent("AutoIt.Error", "_ComErrFunc") _Print_PDF() Func _Print_PDF() Local $hGUI = GUICreate("Example") Local $idPrint = GUICtrlCreateButton("&Print", 310, 370, 85, 25) GUISetState() Local $sFile While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idPrint $sFile = FileOpenDialog("Choose a PDF File", @ScriptDir, "PDF Files(*.pdf)", $FD_FILEMUSTEXIST+$FD_PATHMUSTEXIST) If Not @error Then _AcroPrint ($sFile) EndSwitch WEnd EndFunc ;==>_Print_PDF Func _AcroPrint($sFile) If Not FileExists($sFile) Then Return SetError(1) Local $oPDF = ObjCreate("AcroPDF.PDF.1") If Not IsObj($oPDF) Then Return SetError(2) ConsoleWrite($oPDF.GetVersions & @CRLF) $oPDF.src = $sFile GUICreate("") GUICtrlCreateObj($oPDF, 0, 0) $oPDF.PrintAll() EndFunc ;==>_AcroPrint Func _ComErrFunc() MsgBox($MB_SYSTEMMODAL, "AutoItCOM Error", _ "We intercepted a COM Error !" & @CRLF & @CRLF & _ "Description is: " & @TAB & $oMyError.description & @CRLF & _ "Win Description:" & @TAB & $oMyError.windescription & @CRLF & _ "Number is: " & @TAB & Hex($oMyError.number, 8) & @CRLF & _ "Last Dll Error is: " & @TAB & $oMyError.lastdllerror & @CRLF & _ "Script Line is: " & @TAB & $oMyError.scriptline & @CRLF & _ "Source is: " & @TAB & $oMyError.source) SetError(100) EndFunc ;==>_ComErrFunc Marc and DesireDenied 1 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
seadoggie01 Posted August 28, 2020 Share Posted August 28, 2020 Thank you, Nine! (I know, not my topic, but I haven't been able to find the Acrobat Reader object before.) The documentation for AcroPDF.PDF.1 appears to be here (page 106) under AxAcroPDFLib.AxAcroPDF This might be helpful because there are a few more methods for printing without using a dialog box: PrintAllFit, PrintPages, and PrintPagesFit DesireDenied 1 All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types Link to comment Share on other sites More sharing options...
Nine Posted August 28, 2020 Share Posted August 28, 2020 @seadoggie01 Yes I have found this documentation. After quite a bit of trial/error, I had come to the conclusion that we need to launch the ActiveX in order to successfully use the object. seadoggie01 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
DesireDenied Posted August 29, 2020 Author Share Posted August 29, 2020 Thanks a lot Nine, it works like a charm. Link to comment Share on other sites More sharing options...
DesireDenied Posted August 31, 2020 Author Share Posted August 31, 2020 @Nine The only thing is, I can't use PrintAllFit method at work, and its really hard to tell what is going wrong. getVersions() output Accessibility=20.12,AcroForm=20.12,Annots=20.12,Checkers=20.12,DigSig=20.12,DropboxStorage=20.12,DVA=20.12,eBook=20.12,EScript=20.12,IA32=20.12,MakeAccessible=20.12,Multimedia=20.12,PDDom=20.12,PPKLite=20.12,ReadOutLoud=20.12,reflow=20.12,SaveAsRTF=20.12,Search=20.12,SendMail=20.12,Spelling=20.12,StorageConnectors=20.12,Updater=20.12,weblink=20.12, error Testing.au3" (59) : ==> The requested action with this object has failed.: $oPDF.PrintAllFit() $oPDF^ ERROR Any suggestions what is going on? Link to comment Share on other sites More sharing options...
Nine Posted August 31, 2020 Share Posted August 31, 2020 Use : $oPDF.PrintAllFit(True) DesireDenied 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
DesireDenied Posted September 7, 2020 Author Share Posted September 7, 2020 (edited) @Nine All works perfectly fine but after some number of printed documents I am getting an error that too many documents are currently opened, and I have to close some of them to be able to print another one, and I am not sure how to properly close the document through acrobat pdf object. If I try to clear $oPDF object just right away after $oPDF.PrintAllFit(True) most of the documents wont print or blank pages are printed. Func _AcroPrint($sFile) If Not FileExists($sFile) Then Return SetError(1) Local $oPDF = ObjCreate("AcroPDF.PDF.1") If Not IsObj($oPDF) Then Return SetError(2) ConsoleWrite($oPDF.GetVersions & @CRLF) $oPDF.src = $sFile $hGUI = GUICreate("") $hObj = GUICtrlCreateObj($oPDF, 0, 0) $oPDF.PrintAllFit(True) Sleep(500) GuiCtrlDelete($hObj) GuiDelete($hGUI) $oPDF = 0 EndFunc ;==>_AcroPrint So I came up with the idea to make an array of $oPDF objects, activeX handles (gui, ctrl) and timestamps, and to clear them all in a single function: Func flushPrintQueue() Local $aItemsToRemove[0] For $i=0 To UBound($aPrintQueue)-1 If TimerDiff($aPrintQueue[$i][3]) > 10000 Then ; object creation timestamp _ArrayAdd($aItemsToRemove, $i) $aPrintQueue[$i][0] = 0 ; activeX object GUICtrlDelete($aPrintQueue[$i][2]) ; activeX control handle GUIDelete($aPrintQueue[$i][1]) ; activeX gui handle EndIf Next _ArrayInsert($aItemsToRemove, 0, UBound($aItemsToRemove)) _ArrayDelete($aPrintQueue, $aItemsToRemove) EndFunc But it does not work. Am I even passing to array my $oPDF by refference, or is this just some copy of an object? Edited September 7, 2020 by DesireDenied misspellings, code errors Link to comment Share on other sites More sharing options...
Nine Posted September 18, 2020 Share Posted September 18, 2020 Not exactly sure what seems to be the problem, but maybe using a persistent object ? #include <Constants.au3> #include <GUIConstants.au3> Global $oPDF = ObjCreate("AcroPDF.PDF.1") GUICreate("") GUICtrlCreateObj($oPDF, 0, 0) _Print_PDF() Func _Print_PDF() Local $hGUI = GUICreate("Example") Local $idPrint = GUICtrlCreateButton("&Print", 310, 370, 85, 25) GUISetState() Local $sFile While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idPrint $sFile = FileOpenDialog("Choose a PDF File", @ScriptDir, "PDF Files(*.pdf)", $FD_FILEMUSTEXIST+$FD_PATHMUSTEXIST) If Not @error Then _AcroPrint ($sFile) EndSwitch WEnd EndFunc ;==>_Print_PDF Func _AcroPrint($sFile) If Not FileExists($sFile) Then Return SetError(1) If Not IsObj($oPDF) Then Return SetError(2) ConsoleWrite($oPDF.GetVersions & @CRLF) $oPDF.src = $sFile $oPDF.PrintAll() EndFunc ;==>_AcroPrint I tested on a few files and it works for me... DesireDenied 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
Nine Posted September 20, 2020 Share Posted September 20, 2020 Additional information (after tests) : There is some memory usage increases using the first approach (one creating object at each print). That's corroborate your issue about too many opened documents after awhile. With the last approach (creating a persistant object), there is no more increase in memory usage. I would assume that this should solve your problem. DesireDenied 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
DesireDenied Posted October 10, 2020 Author Share Posted October 10, 2020 (edited) @Nine Once again, many thanks for your reply. We are using my script to print artworks in pdf files. Size of each file can vary from 1-600MB or even more, but for most of the time its around couple of megabytes. In most cases its not just one or two documents but, lets say, number of printed documents per order goes like this: 4, 11, 8, 3, 27, 13 and we want to queue them all for print in one minute. I have also already tried to use persistent object but it did not worked as expected. Same message appeared after short while. It does not really matters if its single global object or an array of objects. Single Acrobat Reader process handle all of them. Another problem with single PDF object is that, it does not really wait to be done or return anything if its done, and if you try to use fixed sleep time between documents, you can slow down entire process or whats worst, you can overwrite buffering / rastering current document ending up with blank pages printed out in case of complex artworks. So I came up with another idea: don't let my script to have opened more than 15 activex pdf objects, and if there is still something to print, wait in a loop until at some of the objects will be cleared out by flushPrintQueue function running in the background. And finally, after 60 seconds from last printed document, close entire AcrRdr32 process (the one which have no own window handles) and it works. Edited October 11, 2020 by DesireDenied my english is really bad 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