Damian Mehers' Blog Xamarin from Geneva, Switzerland.

12Jun/080

Using mdbg to debug at the MSIL level instead of assembly code.

Windows Media Center (MCE) lets you create addins to provide new functionality.  There are two kinds of addins -- normal addins, and background addins.  Background addins run continuously as soon as MCE starts up, and are limited in the user-interaction they provide.

One thing they are allowed to do is to pop up a dialog message to the user using the AddInHost.Current.MediaCenterEnvironment.Dialog(...) method call.

I was doing this in my background addin, but I was getting an error from MCE saying that I was not allowed to make that call.

Addins run in separate processes to the main MCE process, which is ehshell.exe, and the Dialog call is remoted into the ehshell.exe process.

Using Reflector I could see that the call was eventually failing in MediaCenter.Extensibility.ExtensibilityAutomation.EnforceApplicationPermission(...) which was calling through to Microsoft.MediaCenter.Hosting.Infrastructure.RegisteredApps.IsBackgroundEntryPoint which looks like this:

public static bool IsBackgroundEntryPoint(ExtensibilityEntryPointInfo epi)
{
    return (0 == string.Compare(epi.Category, "Background", true,
CultureInfo.InvariantCulture));
}

Somehow I needed a way to use the debugger to see what the epi.Category value was when the call was failing.

The standard Visual Studio debugger just drops you through to x86 assembly code if it has no debugging symbols.  I needed a debugger which shows .NET IL instead.

This is where mdbg comes in. Mdbg is a command line debugger created by Mike Stall.

Once you have downloaded it and started running it, then you can use the 'a' command to list available processes, and then 'a <pid>' to attach to a specific process.

Once attached, you can set a breakpoint using 'br <module name>!<type>.<method name>", and then 'go' to resume:

image

Once the breakpoint is hit, you can use the 'print' command to display a parameter value:

image

There is also a GUI which can be invoked using 'load gui':

 image

7Jun/080

Attending PDC 2008

Last year Microsoft announced the 2007 Professional Developers Conference (PDC) and I immediately booked the flights and hotel.  They then canceled the PDC.  Nevertheless I flew out to LA and had a great time spending a week immersed in technology, doing my very own "Personal" PDC, with no interruptions, spending all the hours I wanted.  It took me right back to the days before I was married, before I had kids, and I guess before I had a life.

Microsoft have just announced the 2008 PDC in LA, and I've signed up for it.  I'm pretty sure this one won't get canceled.

If you are attending and feel like a chat about anything, including any of the products I've created such as MceFM, the ListSearch Extender, PromptSQL or J-Integra or anything else please email me at damian at atadore.com.

Filed under: Uncategorized No Comments
6Jun/080

MceFM 1.0 Beta 6 released

I'm finally feeling as though I am getting very close to the first non-beta release of MceFM.

I decided to remove MceFM's Queue page (which was by all accounts rather ugly anyway) and just to use the standard Windows Media Center music related pages (Now Playing, and View Queue).

MSAS Fun

I needed to detect Media Center events in order to know when a song changes, etc.

The standard way to do this is using the Media State Aggregation Service (MSAS), and I got this working.  However it is rather flaky, and in the end I threw away the MSAS code I'd written, and took a different approach.  The code is here if anyone wants it.

I'm embedding an instance of the Windows Media Player (WMP) ActiveX Control in a hidden window attached to the MceFM background application.  The WMP control runs in "remote" mode, so that it reflects what is happening with the WMP instance used by Media Center.  Using this control I can detect when songs start playing.

Detecting Remote Control button pushes

I also went through a weird and wonderful journey with regards to allowing users mark songs as Loved or Banned in Last.fm.  Since I no longer have my own Queue page, I somehow needed to let the user press unused keys on the remote control when the Media Center "Now Playing" page was displayed.  Two things were needed -- how to detect when the key is pressed, and how to know when the Now Playing page is being displayed.

I initially decided to use the colored buttons that appear on my remote control (Red, Green, Yellow, Blue) which are used for teletext.  These buttons can't be intercepted using the normal techniques (low level system hooks), but can be detected using RegisterRawInputDevices and looking for RAWINPUT Windows Messages.  I got this working fine on my computer (RAWINPUT 91=Red, 92=Green, 93=Yellow, 94=Blue).

My idea was to let people press the Red button to Ban a song, and the Green button to Love a song.  I got this all working great.  Then I hit two issues.

The first issue is that the RegisterRawInputDevices mechanism didn't work at all for extenders.

The second issue is that only European Media Center remote controls appear to have the colored buttons.  D'oh.

I had to throw the whole approach overboard and start again from scratch.

I ended up letting you press the Left or Right arrow buttons on the remote control, which can be detected using low level system hooks, and do work on Extenders.  Whew.

Filed under: Media Center No Comments
6Jun/080

When Resharper isn’t so sharp

One of the things I wanted to add to MceFM was to let users tell Last.fm to Love/Ban songs.

I was using the RegisterRawInputDevices Windows call to listen for events generated by the remote control.  This takes a RAWINPUTDEVICE structure as a parameter:

    [StructLayout(LayoutKind.Sequential)]
    internal struct RAWINPUTHEADER {
      [MarshalAs(UnmanagedType.U4)] public int dwType;
      [MarshalAs(UnmanagedType.U4)] public int dwSize;
      public IntPtr hDevice;
      [MarshalAs(UnmanagedType.U4)] public int wParam;
    }

My code was working fine, and then suddenly stopped working.  I lost at least an hour tracking back what I'd changed recently, and then finally realized that I'd run Resharper's Reformat Code tool:

image

Notice that last item?  This is what it did to the structure:

    [StructLayout(LayoutKind.Sequential)]
    internal struct RAWINPUTHEADER {
      [MarshalAs(UnmanagedType.U4)] public int dwSize;
      [MarshalAs(UnmanagedType.U4)] public int dwType;
      public IntPtr hDevice;
      [MarshalAs(UnmanagedType.U4)] public int wParam;
    }

The RegisterRawInputDevices call was falling over because the structure was totally out of whack.  I'm still a big fan of Resharper -- and this is marked as fixed in the next release.

Filed under: Media Center No Comments