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!

