Mac OS X : Adobe Reader XI deployment

how-to

Adobe is probably the software editor I dislike the most. There is Flash, there are those patches almost every week, there is all that licensing stuff. And there is Adobe Reader. I really can't imagine how they work at Adobe. I bet their engineers are kept in some kind of cave somewhere, without the Internet or any open window on the outside world. What is sure is that the guys never had to deploy one of their bloatware on several computers at the same time. I just can't believe they once had to.

The other day, I found out that they had released Adobe Reader XI. Since my users absof!ckinglutly need it, I started to have a look at it. I downloaded the .pkg file and tried to deploy it via Apple Remote Desktop (ARD). Well, I have to admit that I was on fire that day. I don't know why I tried this, probably because I don't have all my mind those days (but that's another story). Obviously, the install miserably failed. That's where my journey started. And it took me a whole day to figure out how to deploy it properly. A whole f*ckin' day. Here is the result, I hope it will save someone else's time.

Step one : Build a custom package

Adobe Reader XI comes with that crappy plugin for web browsers which allows one to view PDF files in the browser. For security reasons and for the sake of usability, I always chose not to install this. So, the first challenge was to disable this stuff. To do that, we'll have to build our own .pkg file.

Once you've downloaded the installer from Adobe website, fire up a Terminal, cd to the directory that contains the downloaded .pkg and extract the files stored in it :

pkgutil --expand ./Adobe\ Reader\ Installer.pkg ./AdobeReader

You should get this :

ls -l ./AdobeReader
total 8
-rw-r--r--   1 francoiskubler  staff  2339 24 sep 07:07 Distribution
drwxr-xr-x  24 francoiskubler  staff   816 16 nov 14:52 Resources
drwxr-xr-x   6 francoiskubler  staff   204 16 nov 14:52 application.pkg
drwxr-xr-x   6 francoiskubler  staff   204 16 nov 14:52 browserPlugin.pkg
drwxr-xr-x   5 francoiskubler  staff   170 16 nov 14:52 support.pkg

We are going to edit the Distribution file. Open it with your favorite text editor. I'm not talking about Word !

The Distribution file contains 3 choices. One for the core application (keep it), one for the support package (keep it too) and another one for the browser plugin (the one we want to drop). The entries look like this one :

<choice description="DESCRIPTION_APPLICATION" id="coreapp" start_enabled="false" title="CoreApplication">

You just have to edit each choice entry and add start_selected="true" to install the corresponding package, or start_selected="false" to skip it. In my case, I want to disable the browser plugin, so my choices lines look like that :

[snip]
<choice description="DESCRIPTION_APPLICATION" id="coreapp" start_enabled="false" title="CoreApplication" start_selected="true">
[snip]
<choice description="DESCRIPTION_BROWSER" id="browserplugin" title="AcroBrowserPlugIn" start_selected="false">
[snip]
<choice customLocation="/Library/Application Support" id="appsupport" start_visible="false" title="Application Support" start_selected="true">
[snip]

Don't touch anything else and save the file. We now have to repackage the stuff :

pkgutil --flatten ./AdobeReader ./CustomAdobeReaderInstaller.pkg

Good, we have a ready-to-install package. Well, mostly...

Step two : Lock down the updater

As everyone knows, people at Adobe loves to release patches. And Adobe Reader gets a security update almost once per month. Needless to say, the updates are NOT cumulative. You have to install all of them. You can't miss one. Since my users don't have the rights to update their softwares (well, what kind of sysadmin let his users do that ?), I have to handle this for them. And they also don't want to be disturbed by the popup messages when an update is available - which I can understand.

Surprisingly, there must be one clever guy at Adobe that dediced to make my dream come true (I suspect the dude did that because he was also annoyed by the popup messages, but I've got no evidence). Starting with the XI version of their softwares, Adobe decided that people like me would be able to create a single file (well, one for each sofware) to lock down features.

In our precise case, the feature is called bUpdater and the file is /Library/Preferences/com.adobe.Reader.plist If you want to lock down the updater in Acrobat, the file would be called /Library/Preferences/com.adobe.Acrobat.plist.

Here is a little script I wrote to build the file :

#!/bin/sh

plistbuddy=/usr/libexec/PlistBuddy

BUPDATER_KEY_11=":11:FeatureLockdown:bUpdater"
PLIST="/Library/Preferences/com.adobe.Reader.plist"

$plistbuddy -c "Add :11 dict" $PLIST
$plistbuddy -c "Add :11:FeatureLockdown dict" $PLIST
$plistbuddy -c "Add :11:FeatureLockdown:bUpdater bool false" $PLIST

exit 0

Just run it and voilà ! You'll get the proper file in /Library/Preferences/com.adobe.Reader.plist. And you know what's the best ? It actually works. Good bye updater :D

Some of you might have noticed the 11 in the lines above. That's because we are dealing with Reader 11. So you'll probably have to edit the /Library/Preferences/com.adobe.Reader.plist file when Adobe will release Reader 12. If we are a bit lucky (and if they decide not to mimick Mozilla), that's not going to be soon, so we should be ok for a while.

Remember you'll also have to copy the built file on all others computers. But that should be a matter of minutes with ARD.

Step three : Set users prefs

This 3rd step is something you may want to skip. I don't like my users to be disturbed by popups. But Adobe loves them. Run Adobe Reader for the first time and you'll get : splashscreen, license stuff, information message, "do you want Reader to be the default viewer for PDF ?", "Do you want to import your old certificates ?", ... D!mn I just want to open that f!ckin' PDF !

Okay, the fact is that some of my users would also call me to know what they have to answer. So, I prefer to keep things quiet. Here is how to tell Reader not to ask for that stuff.

Adobe Reader stores a whole bunch of preferences in ~/Library/Preferences/com.adobe.Reader.plist. We'll have to edit this one for each user. I tried to import a modified .plist in Workgroup Manager but it doesn't seem to be working properly. I don't know why and didn't take the time to try to sort this out. I instead wrote a little script :

#!/bin/sh

plistbuddy=/usr/libexec/PlistBuddy

# Where your users home directories are :
HOMES="/Users"

# EULA agreement :
EULA_KEY=":11:EULAAccepted"

# Splash Screen :
SPLASH_KEY=":11:ShowSplashScreen"

# Messages when Reader launches :
MSG_LAUNCH_KEY=":11:IPM:ShowMsgAtLaunch"

# Updater :
GEN_UPDATES_KEY=":11:AVGeneral:CheckForUpdatesAtStartup"

# Welcome screen :
GEN_WELCOME_KEY=":11:AVGeneral:ShowWelcomeScreen"

# Ask to become the default PDF viewer :
DEFAULT_APP=":11:AVAlert:Checkbox"

for p in $(ls $HOMES)
do
    adobe_plist="$HOMES/$p/Library/Preferences/com.adobe.Reader.plist"

    $plistbuddy -c "Add :11 dict" $adobe_plist

    $plistbuddy -c "Delete $EULA_KEY_11" $adobe_plist
    $plistbuddy -c "Delete $SPLASH_KEY_11" $adobe_plist
    $plistbuddy -c "Delete $MSG_LAUNCH_KEY_11" $adobe_plist
    $plistbuddy -c "Delete $GEN_UPDATES_KEY_11" $adobe_plist
    $plistbuddy -c "Delete $GEN_WELCOME_KEY_11" $adobe_plist
    $plistbuddy -c "Delete $DEFAULT_APP_11" $adobe_plist

    $plistbuddy -c "Add $EULA_KEY_11 bool true" $adobe_plist
    $plistbuddy -c "Add $SPLASH_KEY_11 bool false" $adobe_plist

    $plistbuddy -c "Add $MSG_LAUNCH_KEY_11 array" $adobe_plist
    $plistbuddy -c "Add $MSG_LAUNCH_KEY_11:0 integer 0" $adobe_plist
    $plistbuddy -c "Add $MSG_LAUNCH_KEY_11:1 bool false" $adobe_plist

    $plistbuddy -c "Add $GEN_UPDATES_KEY_11 array" $adobe_plist
    $plistbuddy -c "Add $GEN_UPDATES_KEY_11:0 integer 1" $adobe_plist
    $plistbuddy -c "Add $GEN_UPDATES_KEY_11:1 integer 0" $adobe_plist

    $plistbuddy -c "Add $GEN_WELCOME_KEY_11 array" $adobe_plist
    $plistbuddy -c "Add $GEN_WELCOME_KEY_11:0 integer 0" $adobe_plist
    $plistbuddy -c "Add $GEN_WELCOME_KEY_11:1 bool false" $adobe_plist

    $plistbuddy -c "Add $DEFAULT_APP_11 array" $adobe_plist
    $plistbuddy -c "Add $DEFAULT_APP_11:0 integer 8" $adobe_plist
    $plistbuddy -c "Add $DEFAULT_APP_11:1 dict" $adobe_plist
    $plistbuddy -c "Add $DEFAULT_APP_11:1:optionToOwn array" $adobe_plist
    $plistbuddy -c "Add $DEFAULT_APP_11:1:optionToOwn:0 integer 1" $adobe_plist
    $plistbuddy -c "Add $DEFAULT_APP_11:1:optionToOwn:1 integer 1" $adobe_plist
done

exit 0

There is probably an easier way, but this one works well too. Just edit HOMES to fit your need !

Step four : Deploy

Now we have everything ready for deployment. Yay ! Well, there is still a little detail we have to handle. In my case, we already have Adobe Reader X installed everywhere. And we'll have to get rid of it before installing XI.

Adobe thought about it. Yep, they did. But they did half the stuff. Here is the output I got when I first tried to deploy the .pkg file I downloaded :

Nov 15 09:11:35 imac-125 installer[128]: ./preinstall: Moving existing Adobe Reader.app to Trash as Adobe Reader.app
Nov 15 09:11:35 imac-125 installer[128]: ./preinstall: mv: rename /Applications/Adobe Reader.app to /var/empty/.Trash/Adobe Reader.app: No such file or directory
Nov 15 09:11:35 imac-125 installer[128]: ./preinstall: ERROR: Could not move existing Adobe Reader.app to Trash.

Yep... Thank you Adobe. You could have added a little mkdir -p /var/empty/.Trash just before moving the existing app to a trash that doesn't exist. I wonder if they also throw stuff in a non-existent trash in their cave. Well, they probably do. The mkdir thing would have made the magic happen. Sadly, they didn't put it.

To fix this, I personnaly chose to rm -Rf /Applications/Adobe\ Reader.app before deploying the custom .pkg built in step 1. Fast and efficient.

I was finally able to deploy the custom .pkg everywhere.

Thank you Adobe. Really. I mean, you guys are wonderful. That whole bunch of stuff just to deploy a PDF viewer that's not going to annoy users with silly questions. I hope you'll someday enjoy to eat your own dogfood.