ADC Home > Reference Library > Technical Q&As > Carbon > Process Management >

ICLaunchURL, "file:///" URLs and Mac OS X


Q: My application wants to launch the user's default browser to display help content. In Mac OS 9 I do this by constructing a "file:///" URL and passing it to ICLaunchURL. However, on Mac OS X ICLaunchURL returns an error. What's the problem?

A: The error is probably the result of a change in the "file:///" URL format. Given that you're porting code from Mac OS 9 to Mac OS X, you're probably generating your "file:///" URL in the format used in Mac OS 9, that is, the volume name followed by path components, each separated by a "/". For example, if you have two volumes each with a "index.html" file in the root, the URLs might be:

file:///Boot%20Disk/index.html

file:///Applications%20Disk/index.html

These "file:///" URLs will not work on Mac OS X, which uses the standard UNIX-style "file:///" URL format. To continue the above example, the Mac OS X URLs would be:

file:///index.html

file:///Volumes/Applications%20Disk/index.html

The obvious difference between these URLs is that Mac OS X mounts the startup disk in the root of the directory hierarchy and all non-startup disks in the "Volumes" directory. However, there are some more subtle differences.

  • Ambiguity -- Mac OS 9 allows you to mount two volumes of the same name, so the Mac OS 9-style "file:///" URLs can be ambiguous.
  • Text Encodings -- In Mac OS 9 the URL components are assumed to be percent-encoded PStrings, as returned by PBGetCatInfo. This is inadequate for Mac OS X, where the File Manager fully supports Unicode file names. In Mac OS X the URL components are defined as percent-encoded UTF-8.

One possible workaround is to change your code to generate the "file:///" URL in the right format. You can do this with a sequence of File Manager, CFURL, and CFString calls.

An easier workaround is to avoid ICLaunchURL entirely and change your code to call the Launch Services routine LSOpenCFURLRef. This code is very simple.

  1. If you're starting with an FSRef, just skip to step 2. If you're starting with an FSSpec, convert it to an FSRef using FSpMakeFSRef.
  2. Create a CFURL based on the FSRef using CFURLCreateFromFSRef.
  3. Pass that CFURL to LSOpenCFURLRef.
  4. Release your reference to the CFURL.

ICLaunchURL is actually layered on top of LSOpenCFURLRef, so this workaround should not change the behaviour of your code.


[Apr 20 2001]


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.