Update file location through iTunes COM SDK

I’m working on a little app to automate some management tasks in iTunes (primarily the ability to locate a “dead” file in iTunes and look for its new location).  I downloaded the Apple iTunes COM SDK documentation, and have built a little C# application to iterate through the library to find dead files.

What I’d like to be able to do is search the music directory for possible matches (artist, album, file size, etc.) and update the iTunes library with the new location.  The code to loop through the library is pretty straightforward:

public static Hashtable GetInvalidFileList(iTunesAppClass iTunesAppObject)
{
bool CloseWhenDone = (null == iTunesAppObject);
if (CloseWhenDone)
{
iTunesAppObject = new iTunesAppClass();
}

Hashtable InvalidFileList = new Hashtable();

// Get the full library
IITLibraryPlaylist MyLibrary = iTunesAppObject.LibraryPlaylist;

// Get the track collection
IITTrackCollection MyTrackCollection = MyLibrary.Tracks;

for (int i = 0; i < MyTrackCollection.Count; i++)
{
// Get the track
IITTrack MyTrack = MyTrackCollection[i + 1];

// See if it's a file track
if (ITTrackKind.ITTrackKindFile == MyTrack.Kind)
{
// Cast it as a file track
IITFileOrCDTrack MyFileTrack = (IITFileOrCDTrack)MyTrack;

// Inspect the location
if (String.IsNullOrEmpty(MyFileTrack.Location))
{
int TrackDatabaseID = MyFileTrack.TrackDatabaseID;
string TrackName = "Artist: " + MyFileTrack.Artist + " Album: " + MyFileTrack.Album + " Song: " + MyFileTrack.Name;
InvalidFileList.Add(TrackDatabaseID, TrackName);
}
}
}

if (CloseWhenDone)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(iTunesAppObject);
iTunesAppObject = null;
GC.Collect();
}

return InvalidFileList;
}

However, updating the location appears to be problematic, as IITFileOrCDTrack.Location is read-only.  It seems that the only way to do this through the COM interface is to add a new track, copy the meta from the old track, add the new track to all playlists that the old track was a member of, and delete the old track.  That will set DateAdded to the time the application was run, and it’s a little kludgey as well.  Is there a better way to do this?

Advertisements

15 thoughts on “Update file location through iTunes COM SDK

  1. I also looked at this problem. I considered closing iTunes, then having my app load the Library.XML file and edit the path there.

    There’s an odd relationship between the XML file and the .itl file. The .itl file contains data not in the XML file, but I think it may also contain data that IS in the XML file. So, it’s hard to predict which will take preference. You would need to investigate.

  2. It doesn’t work in my tests at least. It looks to me like the file location in the XML file is always overridden by the ITL file. One trick that I’ve seen to make the change is to corrupt the ITL file and iTunes will then rebuild the ITL file from the contents of the XML file (but that sets the Date Added of EVERY track to the time when the library was rebuilt).

    Thanks for the suggestion!

  3. Along the same lines: look at

    IITFileOrCDTrack::UpdateInfoFromFile ()

    Quote:

    Update this track’s information with the information stored in its file.

    If you have edited this track’s metadata (such as song name, album, artist, etc.) with another program outside of iTunes, you can call this method to force iTunes to update its internal information with the current information stored in the track’s file.

    End Quote

    So there’s a third source of data, the file itself. I don’t know if DateAdded is stored there, but if so, and you can figure out a way to edit it directly, then you should be able to force iTunes to reload that field…

  4. By the way, I stole these lines of code from you:

    System.Runtime.InteropServices.Marshal.ReleaseComObject(iTunesAppObject);
    iTunesAppObject = null;
    GC.Collect();

    I had been using just

    iTunesAppObject = null;

    which worked fine on Windows XP (iTunes was able to close without complaining that a scripting interface was being held open). However, on Windows Vista, with the exact same exe’s, the interface was not being released.

    However, your code forces all issues immediately, solving my problem.

    Thanks!

  5. If you’re interested, I’ve written a program that lists all the dead tracks in your iTunes database and lets you re-map them. It lists them in a treeview according to the folders where they used to be. If you moved the folder you just re-map the whole folder, or you can do it file by file.

  6. Hi guys,

    Here is the URL: http://homepages.internet.lu/fraser/iWake/iwake.msi

    You’ll need .Net framework 2.0.

    I’d be happy to share bits of the source code. (VB.net)

    I’m afraid the Help is necessary, because the user interface isn’t exactly self-explanatory.

    One word of warning: when you revive a track, check that it is the right one afterwards. I came across a strange case yesterday – I was moving a couple of tracks around to test behaviour and the wrong files were listed in the mapping tree. I don’t know whether they or the correct files would have been linked to in iTunes if I’d proceeded with the update. I’ve only seen this once in a considerable amount of testing and can’t reproduce it.

    A prior back-up of the two iTunes databases would seem appropriate.

    I’d appreciate any feedback.

    Enjoy,
    Colin

  7. Are you willing to disclose the source code to your iWake program so I am able to change it to suit my needs?

    There’s no point re-inventing the wheel eh!

    thanks,
    mark (C# app developer)

  8. Have any one successfully added file/track thru the iTunes COM SDK to iPod Shuffle?

    It works for most of iPod (even iPod touch), yet, no matter how I tried on iPod Shuffle,
    the IITLibraryPlaylist::AddFile() will return 0xA0040203 (ITUNES_E_OBJECTLOCKED)!

    Any idea?
    Thanks.
    — Dale

  9. Hi, maybe this has nothing to do with the original post, anyway here it goes:

    I have a blog which updates itself from my iTunes to show last updated information about CD’s. I’m using the iTunes COM library with C# .NET Framework 3.5 on Windows Vista Business.

    I needed an extra database, outside iTunes enviroment to manage which albums have been uploaded to my blog.

    I thought TrackDatabaseID was the field that could identify each song as unique. I was wrong because, when I updated the artwork for a track iTunes marked the original songs as not enabled and created a new ones, forcing my program to INSERT new rows in my database.

    I would to know if anyone has been through this issue before and which field can serve as primary key for all the songs in the library playlist.

    Any advice will be welcome. Thanks.

  10. The link to the app in the comments is now dead. Are there any other apps around that allow you to modify the itunes .itl file? I have a ton of podcasts that have broken paths and I cant use the .xml route as that won’t recover info on podcasts.

    Any one help?

  11. I had written a very similar program to yours back in 2008, utilizing the COM interface to iTunes, modifying track properties. My reason for doing it was that I was moving my music librar from one server to another, and wanted to not lose the bulk of the metadata that wasn’t part of the files. (such as the playcount or lastplayed dates)

    Now I’m moving to a new server and revisiting the code for the first time in 4 years. I can add a track in the new location, but when I attempt to add the extra properties, such as PlayedCount, it throws a COM error 0xa0040203 and doesn’t allow modification. All of this worked four years ago, so I’m wondering if you’ve revisited this topic and might have any suggestions?

    I will supply a code snippet if it helps at all.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s