1985-2010

articles about

Fun with MSN Messenger's "Now Playing" function

Since version 7, MSN Messenger has the ability to show what music you're listening to in your screenname. The function was made to be used in conjuction with Windows Media Player, but it's also supported by iTunes and, via plugins, by Winamp and Foobar.

How it works

The Now Playing information is sent to MSN by storing it in a string which is put in a COPYDATASTRUCT and sent via a WM_COPYDATA window message. After some experimentation it seems the Now Playing info can be updated about once every six seconds, not faster. The string put into the COPYDATASTRUCT has the following layout:

\\0\\Music\\0[on/off]\\0[format]\\0[title]\\0[artist]\\0[album]\\0\\0

Music The type of Now Playing information. "Office" and "Games" are also valid. The rest of the string stays the same, these only determine which icon is shown in MSN.
[on/off] 1 to activate Now Playing, 0 to disable it and clear the user's name
[format] Formatting string. {0} {1} and {2} are title, artist and album (see examples)
[title] Song title
[artist] Song artist
[album] Song album

For example, to turn Now Playing off the string would be:

\\0\\Music\\00\\0\\0

And to set it to "My Sanctuary by Pig from Praise the Lard":

\\0Music\\01\\0{0} by {1} from {2}\\0My Sanctuary\\0PIG\\0Praise the Lard\\0\\0

Sample code

The following C code snippet includes a function to set and clear the Now Playing info, and sets it using above example: nowplaying.c. Make sure to compile it with Unicode support!

As a bonus example, you can use the following main() code to show what program you're currently using in your MSN name (needs psapi.h and psapi.lib, which are part of the normal Windows SDK). You can download the compiled version of it here.
focused executable in msn name

while(1)
{
	HANDLE currProcH;
	wchar_t currExePath[MAX_PATH+1];
	wchar_t* currExe;
	HWND currWindow; 
	DWORD currProcID;

	currWindow = GetForegroundWindow(); //Get HWND of focused Window
	GetWindowThreadProcessId(currWindow,&currProcID); //Get matching process
	currProcH = OpenProcess(PROCESS_QUERY_INFORMATION,0,currProcID); //Open handle to process 
	GetProcessImageFileName(currProcH,currExePath,MAX_PATH); //Get .exe path for process
	CloseHandle(currProcH); //Close process

	//Get the .exe name from the path
	currExe = wcsrchr(currExePath,'\\')+1;
	if(!currExe) //If there wasn't a directory before the exe name, use the path as-is
		currExe=currExePath;

	_putws(currExe);
	setNowPlaying(L"{0}",currExe,L"John Doe",L""); //Set Now Playing info
	Sleep(6000);
}
Created: Aug 17 2006
Modified: Jun 09 2009