Tuesday, March 08, 2005

How-to: 2 users, 1 iTunes library

iTunes rocks. Those that use it already know this; for those that don't, at some point I'll talk more about why. (I have a vague mental shortlist of "things to write about soon" — compare and contrast to Raymond Chen, whose article queue for The Old New Thing stretches out at least six months...)

However, I do have one significant nit with the Windows version of iTunes (I know nothing about the Mac version, so assume everything's Windows-specific from now on): it's not particularly multi-user friendly. This is a problem for us, as we run Windows XP with multiple user accounts: one for me, one for Melinda, and one for guests. This lets us have our own My Documents folders, email identities, bookmarks, browser home pages, desktop wallpaper, and all that jazz. And we like Fast User Switching: we're often both logged in at the same time and switch users as we sit down to use the PC.

So what are the iTunes problems? Twofold. Firstly, iTunes will only run under one account at any one time. If user A has iTunes running, user B cannot start iTunes; the new instance detects the existing iTunes instance and refuses to start. This one isn't a big problem for us as it's easy enough to switch accounts and quit the unused iTunes.

But secondly, iTunes doesn't fully support sharing its music library between users. Apple's take on this is that you should share the music files between users, but that each user should then build their own iTunes library on those shared files (and any user-specific files the user cares to add).

That's one way to go, but it neglects the fact that in many ways the library metadata — artist, album, genre, year, rating, play counts etc — is the most important part of the library, is fundamentally useful in building playlists, and certainly the hardest part to construct. It's useful for us to share the metadata, as well as the raw music, between users.

Well, it can be done, but it's not easy. Here's the skinny:

Firstly, it's easiest to share the music data from a common location — we use C:\MP3 — and point each user's iTunes at that location. Make sure all users have the same setting for "Keep iTunes Music Folder Organised", so that one user's iTunes doesn't end up reorganising the library when other user's iTunes aren't expecting it. Personally I like the "keep organised" option.

Secondly, the thing to know is that, for each user, the iTunes library lives in the user's My Documents\My Music\iTunes folder. Specifically, the library lives in two files there: iTunes Music Library.xml, an XML file (using Apple's rather unfriendly plist schema) and iTunes 4 Music Library.itl, a binary file which seems to be the cached result of processing the XML file.

My first thought was to use Windows shortcuts to alias one user's iTunes folder, or iTunes Library files, onto the other user. No good. Windows shortcuts are a shell-level thing; most Windows programs, iTunes amongst them, are not shortcut-aware. (Because a shortcut is essentially just a file containing a pointer to the target file, they appear as regular files to Windows programs, unless they use the shell link APIs to resolve them.)

No, the solution is to go deeper. NTFS (on Win2K and up) has a little-known feature called "junction points". A junction point is a filesystem-level hard link, aliasing a directory entry in the filesystem to another tree in the filesystem.

Why little-known? Because they're dangerous. The shell doesn't distinguish junction points from regular files or directories, so you can get yourself confused fast — particularly as you can create recursive filesystems (where points low in the filesystem are junctioned to points higher up, so a traversal unaware of junction points can tend up traversing the filesystem forever).

But junction points are most dangerous because the hard link metaphor isn't carried through to the shell. Junction points are transparent to Explorer: the junction point appears as just another directory. Unfortunately, this means that when you delete a junction point in Explorer, you delete not only the junction point, but the target of the junction point. Not the same behaviour as you'd expect in a Unix shell, where deleting a hard link simply removes a reference from the target, and almost certainly not what you intended. (Doug Harrison complains about this behaviour in a comment on The Old New Thing.)

So, Microsoft keeps junction points firmly out of reach of home users: Windows XP Home contains no tools for creating junction points. Administrators can play with linkd if they buy the Win2K Resource Kit.

The rest of us can hack it with junction, a free tool from SysInternals. Junction lets you create and inspect junction points.

So: pick a location for the shared iTunes library. I put ours in C:\Documents and Settings\All Users\Documents\My Music\, copying the iTunes folder there from the most up-to-date user's My Music folder.

Then, for each user, delete their iTunes folder, and create a junction to the shared iTunes folder:

junction "C:\Documents and Settings\User A\My Documents\My Music\iTunes" "C:\Documents and Settings\All Users\Documents\My Music\iTunes"

Bingo: because the junction points are at the filesystem level, iTunes reads right through them. Many users, one shared library.