If you've ever searched the web for things like "How to make a specific application open files with a specific extension", then you've probably seen references to a Macintosh utility called "lsregister" buried within the System's Frameworks directory. The problem with this is that is has a very long path leading to it, AND that path can vary from one version of Mac OS X to another.
To solve that problem, I've created my own script (executed from Terminal.app) that finds the utility for you, and then passes it the parameters you pass to my utility. To makes things even easier, so you can execute any of your own scripts from almost any directory, I recommend you add the following directive to your ".bash_login" script that is executed when you open a new Terminal window, assuming you have Terminal configured to use "bash" as your login shell.
export PATH=$PATH:/usr/local/bin:/usr/local/sbin:.:$HOME
This directive appends a couple of "local" bin's, and then "dot" (.) and $HOME. What these last two do is make your "current" directory a choice for executable scripts, followed by your HOME directory. If you need to skip the "current" directory, just execute using "~/" before the script's name. Otherwise, just give the script's name to execute anything located in the PATH directories.
Now, here's my executable script for finding and executing "lsregister" on any Mac OS X system:
#!/bin/bash
myapp=$(find /System/Library/Frameworks -name lsregister)
if [ -z "$myapp" ]; then
echo "isregister not found."
elif [ -n "$1" ]; then
$myapp $@
fi
exit 0
As you can see, this is a very transportable method for executing "lsregister".
OK, so why do you need "lsregister"? Well, it comes in handy to refresh the lsregister archive when an application's Info.plist is modified by either add or delete of type extensions. I had a case recently where ".aspx" files were being downloaded when I expected to get ".pdf" files. My bank was encrypting the pdf-data and calling it aspx. Unfortunately, I had at least two applications that included "aspx" as a file-extension within their Info.plist file (inside "Contents" of the application).
There are several minor problems when dealing with plist files. Sometimes they a binary in nature, and other times they are xml-files. You must convert a binary to xml, and you can do it using Terminal.app something like this:
cd "/Applications/path/to/application/Contents"
plutil -convert xml1 Info.plist
That's it. You now have an xml-file you can edit with any editor that feels comfortable to you. If you have installed the Developer's Tools, you should find a "Property List Editor" in the /Developer/Applications/Utilities directory. Since Finder doesn't search there for applications, I created a symlink in /Applications that points to this utility:
cd /Applications
ln -s "/Developer/Applications/Utilities/Property List Editor.app" . <- terminating dot.
Be sure to include the terminating dot in the command above.
If you "man plist" you'll see samples of the xml involved. You can launch the Property List Editor and Open an Info.plist by following the path to where it is located, and then click "Open" to view it. You may have to click the "Dump" button to get an expanded view in the bottom pane, but you can only edit in the top pane by navigating into xml arrays. I find this to be difficult, so most of the time I resort to editors like BBEdit or TextEdit or Word, but to use them I have to copy the Info.plist out of the application and onto my Desktop where I can easily access it. Word shows the tab-characters, which is handy to keep things lined up properly.
Whichever editor you use. You'll still have to navigate, but at least everything is visible and you can "Find" your way through it. I had "aspx" defined in two applications, neither of which could deal with encoded pdf. They were: Dreamweaver and the Citrix ICA Client. For them, I decided I was never going to deal with network files with aspx extensions, so I deleted those defined extension within the plist, saved them back to my Desktop, and compared them to the originals (still within the application's Contents) using "diff" in Terminal. Once I was satisfied that they were OK, I copied my Desktop versions back into their corresponding applications.
I then proceeded to add the aspx extension to "Adobe Reader". Again, I copied the Info.plist to my Desktop (as xml-text), and edited it. Since I had to find where to add the extension, I searched for a "pdf" entry. It was inside the first CFBundleDocumentTypes array, within the 2nd <dict>. There were three sub-sections: CFBundleTypeExtensions, CFBundleTypeMIMETypes and finally CFBundleTypeOSTypes. When I was finished, it looked like this:
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>pdf</string>
<string>aspx</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>ACP_PDF.icns</string>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/pdf</string>
<string>application/aspx</string>
</array>
<key>CFBundleTypeName</key>
<string>Adobe PDF document</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>PDF </string>
<string>ASPX</string>
</array>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSIsAppleDefaultForType</key>
<string>Yes</string>
</dict>
Notice the LSIsAppleDefaultForType at the end that says "Yes". This indicates that this is the default application for handling these extensions. I prefer Adobe Reader to Preview. I could have made these changes to Preview instead, but that application gets updated more often than Adobe Reader, at least on my machines. Which brings me to my last point ... An "update" of any of the apps I've modified will have to be modified again.
Once you are done modifying the app, navigate to it (just before Contents), and issue this command in Terminal: lsreg -f -r . <- terminating dot.
Is there an easier way? Well, maybe this would be enough ... For any file you have that you want handled by a specific app, Get Info for it, and "Open with:" the "Other..." choice by navigating to the app, Select it, and then click on the "Change All..." option within the Get Info window. That creates a "handler" entry in the lsregister archive, which should direct any file with this same extension to your chosen app. Is it guaranteed? No, because handlers are hard to eliminate, even if "lsregister" is called to -kill the archive. However, it may be useful to rebuild the archive with these four steps:
1) lsreg -kill
2) lsreg -r -domain system -domain local -domain user
3) lsreg -r /Developer/Applications
4) lsreg -r /Users
The following script, which I saved as an executable file called "lsreg.rebuild", does all these steps safely:
#!/bin/bash
mylsreg="$HOME/lsreg"
if [ -x "$mylsreg" ]; then
$mylsreg -kill
$mylsreg -r -domain system -domain local -domain user
if [ -d "/Developer/Applications" ]; then
$mylsreg -r /Developer/Applications
fi
$mylsreg -r /Users
else
echo "lsreg not found"
fi
exit 0
Another handy script I call "lsreg.dump" is as following:
#!/bin/bash
myapp=$(find /System/Library/Frameworks -name lsregister)
if [ -z "$myapp" ]; then
echo "isregister not found."
else
$myapp -dump >$HOME/lsreg.txt
echo "Created $HOME/lsreg.txt"
fi
exit 0
That created "lsreg.txt" which is a complete dump of the registry. It contains tab-characters which I change to single blanks.