Having deployed a new printing solution in a large University environment, we were faced with all sorts of printing errors, slow printing, and out of memory errors on the printers themselves; specifically when printing PDFs. This is related to how the PDFs are processed, which becomes a challenge in a higher education environment where the PDFs can be considerably complex. This was not only providing a poor user experience, it was becoming a support nightmare to manage when you have thousands of Students and Academics creating and printing PDFs. After some advice, research and testing we found that setting the Adobe “Print As Image” (cPrintAsImage) option made a big difference to the quality and stability of the solution, clearing up most of the printing errors previously experienced. This option changes the way Adobe works by sending the output to the printer as an image file rather than a combination of different elements.
As per the following screen shot users can change it manually by selecting the “Advanced” button in the Print window and then selecting the “Print As Image” check box in the Advanced Print Setup pop-up window.
However, the challenge was how to automate this for all users, including the various versions of Adobe Acrobat and Acrobat Reader in use. Furthermore, we had to also ensure that the “Print As Image” (cPrintAsImage) flag was set for all network printers. So I wrote a script, which we implemented to run at logon 🙂
Here is the SetAdobePrintAsImage.vbs script:
' This script will set the Adobe Acrobat and/or Acrobat Reader ' "Print as image" option (cPrintAsImage registry key structure) ' for all valid printers in the user's session. ' There are simple mechanisms in place so that you can easily ' exclude: ' - Printer by name and/or UNC path ' - Printer by port ' - Microsoft RDP Client Printers ' - Citrix ICA Client Printers ' You simply set the registry key structure in the arrKeys array ' up to the version number of the Adobe Acrobat and/or Acrobat ' Reader products you want to check. The default behaviour is to ' check for the following products: ' - Acrobat Reader 9 ' - Adobe Acrobat 9 ' - Acrobat Reader 10 ' - Adobe Acrobat 10 ' If the registry key structure defined in the arrKeys array does ' not exist, no action will be taken. ' Adobe changed the way it stores the value and data under the ' cPrintAsImage key from version 9 onwards. If you need to run ' this against older versions, this script will need further ' modification. ' The value written under the cPrintAsImage key must be a lower ' case t. The "Print as image" option will not be selected if an ' upper case T is used. ' Whilst this script is only checking the registry for valid Adobe ' products, the script can easily be changed to check for files, ' such as Acrobat.exe and AcroRd32.exe. ' Important: There could be two possible timing issues with this ' script: ' 1) The "HKCU\Software\Adobe" registry key structure does not ' exist at the time the script runs for new logons/profiles. ' A possible solution for this would be to use the HKLM ' structure in the array. ' 2) The Printers pushed out by Group Policy Preferences (GPPs) ' or Deployed Printers have not been created at the time the ' script runs. This script may therefore need to be added to ' the "Items to run at logon" policy, or added as a value to ' the registry "Run" key. Either way, it must be setup so that ' it runs after the network printers have been deployed. ' Release 1.0 ' Written by Jeremy@jhouseconsulting.com on 30th May 2012. Option Explicit Dim objShell, objNetwork, objPrinter, intCounter, arrKeys, strKey Dim arrExcludePrinters, arrExcludePrinterPorts,i, blnDebug Dim blnExcludeRDPClientPrinters, blnExcludeCitrixClientPrinters Dim blnExcludePrinter '******************* Variables to set ************************* ' Add the key structures to the array to represent the products ' and versions deployed in the environment. arrKeys = Array("HKCU\Software\Adobe\Acrobat Reader\9.0", _ "HKCU\Software\Adobe\Adobe Acrobat\9.0", _ "HKCU\Software\Adobe\Acrobat Reader\10.0", _ "HKCU\Software\Adobe\Adobe Acrobat\10.0") ' These are the printers we want to exclude. arrExcludePrinters = Array("Microsoft XPS Document Writer","Generic / Text Only") ' These are the printer ports we want to exclude. arrExcludePrinterPorts = Array("XPSPort") ' Exclude Microsoft RDP Client Printers blnExcludeRDPClientPrinters = True ' Exclude Citrix ICA Client Printers blnExcludeCitrixClientPrinters = True ' Do not set blnDebug to True when in production unless launching it using cscript.exe blnDebug = False '************************************************************** set objShell = WScript.CreateObject("WScript.Shell") Set objNetwork = CreateObject("WScript.Network") Set objPrinter = objNetwork.EnumPrinterConnections For Each strKey in arrKeys If RegKeyExists(strKey & "\General\cPrintAsImage") Then Call DeleteValues(strKey & "\General\cPrintAsImage") End If If RegKeyExists(strKey) Then If objPrinter.Count <> 0 Then i = 0 For intCounter = 0 To (objPrinter.Count -1) Step 2 If blnDebug Then WScript.Echo "UNC Path " & objPrinter.Item(intCounter) & " = " & _ objPrinter.Item(intCounter +1) End If blnExcludePrinter = False If Instr(1,objPrinter.Item(intCounter +1),"redirected",1) > 0 Then If blnExcludeRDPClientPrinters Then blnExcludePrinter = True End If End If If Instr(1,objPrinter.Item(intCounter +1),"in session",1) > 0 Then If blnExcludeCitrixClientPrinters Then blnExcludePrinter = True End If End If If IsArray(arrExcludePrinters) Then If InArray(objPrinter.Item(intCounter +1),arrExcludePrinters) Then blnExcludePrinter = True End If End If If IsArray(arrExcludePrinterPorts) Then If InArray(objPrinter.Item(intCounter),arrExcludePrinterPorts) Then blnExcludePrinter = True End If End If If NOT blnExcludePrinter Then objShell.RegWrite strKey & "\General\cPrintAsImage\t" & i, objPrinter.Item(intCounter +1), "REG_SZ" i = i + 1 End If Next Else If blnDebug Then WScript.Echo "No printers are mapped in this session." End If End If Else If blnDebug Then WScript.Echo "The " & strKey & " registry key structure does not exist." End If End If Next set objShell = Nothing Set objNetwork = Nothing Set objPrinter = Nothing Wscript.Quit(0) Function InArray(stritem,myarray) Dim i For i=0 To UBound(myarray) If strComp(stritem,myarray(i),1) = 0 Then InArray=True Exit Function End If Next InArray=False End Function Sub DeleteValues(strKeyPath) Dim strComputer, objReg, i, arrValueNames, arrValueTypes, return Dim strKeyRoot, HIVE CONST HKEY_LOCAL_MACHINE = &H80000002 CONST HKEY_CURRENT_USER = &H80000001 strComputer = "." Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &_ strComputer & "\root\default:StdRegProv") If instr(1,strKeyPath,"HKEY_LOCAL_MACHINE\",1) > 0 Then strKeyPath = Replace(strKeyPath,"HKEY_LOCAL_MACHINE\","") strKeyRoot = "HKLM" HIVE = HKEY_LOCAL_MACHINE End If If instr(1,strKeyPath,"HKLM\",1) > 0 Then strKeyPath = Replace(strKeyPath,"HKEY_LOCAL_MACHINE\","") strKeyRoot = "HKLM" HIVE = HKEY_LOCAL_MACHINE End If If instr(1,strKeyPath,"HKEY_CURRENT_USER\",1) > 0 Then strKeyPath = Replace(strKeyPath,"HKEY_CURRENT_USER\","") strKeyRoot = "HKCU" HIVE = HKEY_CURRENT_USER End If If instr(1,strKeyPath,"HKCU\",1) > 0 Then strKeyPath = Replace(strKeyPath,"HKCU\","") strKeyRoot = "HKCU" HIVE = HKEY_CURRENT_USER End If return = objReg.EnumValues (HIVE, strKeyPath,_ arrValueNames, arrValueTypes) If return = 0 and IsArray(arrValueNames) Then For i = 0 To UBound(arrValueNames) objReg.DeleteValue HIVE, strKeyPath, arrValueNames(i) Next End If Set objReg = Nothing End Sub Function RegKeyExists(ByVal sRegKey) ' Returns True or False based on the existence of a registry key. Dim sDescription, oShell Set oShell = CreateObject("WScript.Shell") RegKeyExists = True sRegKey = Trim (sRegKey) If Not Right(sRegKey, 1) = "\" Then sRegKey = sRegKey & "\" End If On Error Resume Next oShell.RegRead "HKEYNotAKey\" sDescription = Replace(Err.Description, "HKEYNotAKey\", "") Err.Clear oShell.RegRead sRegKey RegKeyExists = sDescription <> Replace(Err.Description, sRegKey, "") On Error Goto 0 Set oShell = Nothing End Function
Enjoy!