Introduction
This article describes another alternative for reading and displaying ID3 tags in MP3 files. There are various well documented methods of extracting ID3 tag information from MP3 files available. One of the most useful sites regarding this information is http://www.id3.org. This article will explore the possibility of extracting the same information using Win32 Shell functions.
Background
The Shell32.dll is responsible for a host of functions from launching applications to creating shortcuts and managing printers. You can read more about all the wonderful functionality it offers here. With Windows XP, users get the option of selecting a wide variety of columns to display when Explorer is in "Detail" view. Most of the extra columns are centered around multimedia files such as MP3 tracks and digital pictures. By way of the functionality provided in Shell32.dll, it is possible to display ID3 tag information for MP3 audio files and embedded EXIF information in JPEG picture files.
Using the code
The basic functionality of the ID3 tag reader is implemented as a struct
with a single static ReadID3Tags
method that returns a user defined MP3File
object. It is beneficial to implement legacy COM wrapper functionality in a struct
, as struct
types get allocated in the heap and hence are exempt from garbage collection. They are also lightweight (compared to object instances), as they relieve the CLR from the task of reference counting.
We begin by adding a reference to Shell32.dll.
The MP3File
class is basically a skeleton placeholder for the ID3 information returned from our Shell32 wrapper.
using System;
namespace ShellID3Reader {
public class MP3File {
private string fileName;
private string artistName;
private string albumName;
private int trackNumber;
private string songTitle;
public string FileName {
get{return this.fileName;}
set{this.fileName = value;}
}
public string ArtistName {
get{return this.artistName;}
set{this.artistName = value;}
}
public string AlbumName {
get{return this.albumName;}
set{this.albumName = value;}
}
public int TrackNumber {
get{return this.trackNumber;}
set{this.trackNumber = value;}
}
public string SongTitle {
get{return this.songTitle;}
set{this.songTitle = value;}
}
public MP3File(){
}
}
}
The ShellID3TagReader
struct
is responsible for reading the ID3 tags from MP3 files. Its takes the full file path and name as an input parameter and returns an instance of MP3File
after decorating its properties, with information extracted from the Windows shell.
using System;
namespace ShellID3Reader
{
public struct ShellID3TagReader
{
public static MP3File ReadID3Tags(string FileFullPath){
MP3File mp3File = new MP3File();
string fileName =
FileFullPath.Substring(FileFullPath.LastIndexOf("\\")+1);
//parse file path
string filePath =
FileFullPath.Substring(0,FileFullPath.LastIndexOf("\\"));
//create shell instance
Shell32.Shell shell = new Shell32.ShellClass();
//set the namespace to file path
Shell32.Folder folder = shell.NameSpace(filePath);
//get ahandle to the file
Shell32.FolderItem folderItem = folder.ParseName(fileName);
//did we get a handle ?
if (folderItem !=null){
mp3File.FileName = fileName;
//query information from shell regarding file
mp3File.ArtistName = folder.GetDetailsOf(folderItem,9);
mp3File.AlbumName = folder.GetDetailsOf(folderItem,17);
mp3File.SongTitle = folder.GetDetailsOf(folderItem,10);
mp3File.TrackNumber =
Int32.Parse(folder.GetDetailsOf(folderItem,19));
}
//clean ip
folderItem = null;
folder = null;
shell = null;
//return mp3File instance
return mp3File;
}
}
}
And finally we add the MP3File
instance to a ListView
for display.
private void cmdReadTags_Click(object sender, System.EventArgs e) {
listViewFiles.Columns.Clear();
listViewFiles.Items.Clear();
listViewFiles.Columns.Add("FileName",100,HorizontalAlignment.Left);
listViewFiles.Columns.Add("ArtistName",100,HorizontalAlignment.Left);
listViewFiles.Columns.Add("AlbumName",100,HorizontalAlignment.Left);
listViewFiles.Columns.Add("TrackNumber",100,HorizontalAlignment.Left);
listViewFiles.Columns.Add("SongTitle",100,HorizontalAlignment.Left);
DirectoryInfo dir = new DirectoryInfo(textBoxFilePath.Text);
FileInfo[] files = dir.GetFiles("*.mp3");
foreach(FileInfo fi in files){
MP3File mp3File = ShellID3TagReader.ReadID3Tags(fi.FullName);
ListViewItem itm = new ListViewItem();
itm.Text = mp3File.FileName;
itm.SubItems.Add(mp3File.ArtistName);
itm.SubItems.Add(mp3File.AlbumName );
itm.SubItems.Add(mp3File.TrackNumber.ToString()) ;
itm.SubItems.Add(mp3File.SongTitle);
listViewFiles.Items.Add(itm);
}
}
History
- Sept 23 2003 - Initial version (1.0.0)