Compartilhar via


Using MediaState.dll with GAC'd Add-Ins

Update (10/14/2005): MediaState.dll in the new SDK released today is signed. You can download it at https://www.microsoft.com/downloads/details.aspx?FamilyId=1D836C29-ABD5-4FDD-90C5-5C5ABAE97DB4&displaylang=en .

The Media State Aggregation Service (MSAS) in Windows XP Media Center 2005 provides media event information about the current state of the Media Center. This includes information such as track or channel number changes and time elapsed. The MSAS service is implemented as a local COM server and distributes information about property changes it experiences to one or more registered media status sinks. Note, however, that sinks are only notified when a property changes, and that notification only includes the current state of the changed property, not the current state of all properties.  This means that if you write a sink that needs to know the current state of all properties in the system, it must listen for all events and track the current state of all properties.  And in order to write a managed add-in for Media Center that can query for the current state, you need to not only create such an MSAS add-in, but you also need to implement some mechanism for communicating between the managed add-in running in Media Center and the sink running in the MSAS service process.

To make this easier, the Windows XP Media Center 2005 SDK provides the MediaState library, which is composed of three DLLs. The MSASState.dll contains the MSASState.MediaStatusSink class, a managed implementation of the unmanaged IMediaStatusSink COM interface.  When registered with MSAS, the MediaStatusSink creates an MSASState.MediaStatusSession object (MediaStatusSession implements the unmanaged IMediaStatusSession COM interface), which listens for all MediaStatusChange events and writes information about each to a memory-mapped file.  To do this, it utilizes classes from MemMapFile.dll, also included with the SDK.  The third DLL included with the MediaState library, MediaState.dll, provides a managed object model for then accessing that memory-mapped file from an add-in running in Media Center.  In theory, this makes it easy for an add-in to access a plethora of information about the current state of the Media Center.  For example, if an add-in wants to determine the current live TV channel being watched, it can use code something like:

    MediaState state = new MediaState();
    int currentChannel = state.TV.Channel;

Unfortunately, there's a bit of an inconsistency in the SDK (at least in the current release) that makes this slightly more challenging.  Typically, one registers a managed add-in in the global assembly cache (GAC), as outlined at https://msdn.microsoft.com/library/en-us/medctrsdk/htm/registeringanaddinwithmediacenter.asp.  In order to use MediaState.dll from your add-in, typically you'll add a reference from your add-in assembly to MediaState.dll.  But in order to install your assembly into the GAC, it must have a strong-name, and in order to for a strong-named assembly to reference another assembly, that referenced assembly must also have a strong-name (and should be installed into the GAC).  The problem is that MediaState.dll doesn't have one. While there are a few workarounds to this, the most convenient is to give MediaState.dll a strong-name, and with Visual Studio .NET and/or the .NET Framework SDK installed, this takes only a couple of commands at the command prompt.

Open the Visual Studio .NET command prompt (if you don't have Visual Studio .NET installed, you can still do this, but the commands used will need to use the full paths to the utilities, or you'll need to manually augment your path environment variable; the VS.NET command prompt simply makes sure the env vars are configured appropriately).  Change to the Media State directory (with my installation, this is C:\Program Files\Microsoft\Microsoft Windows XP Media Center SDK\MSAS Sample\MediaState). 

First, we need to create a new strong-name key.  To do so, use the sn.exe tool:

    sn -k MediaState.snk

This creates a new key named MediaState.snk in the current directory.  With that in place, we need to disassemble MediaState.dll, and for that, we use the very handy ildasm.exe:

    ildasm /out:MediaState.il MediaState.dll

This diassembles MediaState.dll to a new Microsoft Intermediate Language (MSIL) file MediaState.il (it also saves the resources for the assembly to a file named MediaState.res).  Now, move the original MediaState.dll out of this directory to some place safe, as a backup just in case something goes wrong.  Finally, reassemble the DLL with the ilasm.exe tool:

    ilasm /key:MediaState.snk /out:MediaState.dll /dll MediaState.il

This tells ilasm.exe to reassembly MediaState.il (and the associated .res file) into a DLL named MediaState.dll, using the strong-name key MediaState.snk to sign the compiled assembly.  You'll now have a signed MediaState.dll which can be referenced by a strong-named add-in assembly and installed into the GAC.

Comments

  • Anonymous
    September 20, 2005
    Stephen, were you at the PDC? i asked this exact question at the MCE session.

    ultimately hope that the next version of MCE has MediaState as a supported and signed assembly

  • Anonymous
    September 20, 2005
    Hi Casey-

    Yup. I was in the audience ready with the answer, but Charlie didn't notice my hand raised, so I figured I'd just blog it, and I didn't get around to doing so until this morning. Regardless, I agree with you... it'd be nice to see better support for MediaState in the next release of the SDK.

    -Steve

  • Anonymous
    September 21, 2005
    The comment has been removed

  • Anonymous
    September 21, 2005
    No problem; I hope it was helpful. And, yes, I'm sorry we didn't meet at the PDC; if I had known that was you, I would definitely have introduced myself.

    Anyway, let me know when you've updated your mceSapi utility... I'd like to check it out.

    -Steve

  • Anonymous
    October 12, 2005
    Should MSAS event get published to an add-in? I tried this process and signed mediastate.dll, I got my add-in to compile but it's not receiving any events notifications. A standard winforms app on the other hand is working fine with the signed dll. Is this expected behaviour?

  • Anonymous
    October 14, 2005
    Andy, it should be able to, yes. I'll try to play around with it when I get a some free time in order to see what might be causing you problems.

  • Anonymous
    October 14, 2005
    my guess is that Andy needs to call Application.DoEvents() in his loop so that the events will get pumped through

  • Anonymous
    October 14, 2005
    My add-in doesn't have a loop that runs all the time. I want it to handle MSAS events to know when a recorded tv show starts and stops playback so I can startup my add-in.

    I'll try out the rev in the new SDK, see if that changes anything.

    Also, I don't really need the complexity that the MediaState.dll exposes. Is there any reason that I couldn't just read what I need from the memory file?

  • Anonymous
    October 15, 2005
    Figured out what the problem is... MediaState uses a system.windows.forms.timer to poll the memory file to generate the MSAS events and I'm using a manualresetevent to stall the entry thread (same method used in your timetravel add-in) that the add-in starts with. Replacing the system.windows.forms.timer with a system.threading.timer gets everything moving again.

    Any chance the new MediaState.dll uses a system.threading.timer?

  • Anonymous
    May 13, 2006
    Stephen, I have been struggling with MediaState for over a week now trying to get a background addin display a messagebox with the ArtistName and TrackTitle. I tried everything in the SDK and your examples above, but I still cannot get it working. Do you think you can post sample code to do this? Or even better, take a look at my code?

    I have tried all kinds of forums and newsgroups and everyone says it "should" work, but it never actually does.

    Thanks a million

  • Anonymous
    May 13, 2006
    Nevermind my last post... Turns out I never set MediaExperience experience = mcHost.CurrentExperience;

    A week wasted... lol

  • Anonymous
    June 19, 2006
    Im pretty sure I have the dll compiled correctly, but for some reason my MediaState object fails on the connect() method.  Does anybody know why this might be, or feel like sharing a sample app that is working?

  • Anonymous
    June 19, 2006
    Josh,

    If you are trying to do this in an addin make sure the MediaState.dll, MemMapFile.dll, and MSASState.dll that comes with the MCE SDK are part of your Global Assembly Cache. (Check C:WindowsAssembly) If you don't see them there copy them to that folder. I'm running on Vista and had to add them by hand to get the connect method working.

    Also, make sure you have the latest copy of the sdk (see the link at the top of this page).

    Thanks,
    R. Sparrow

  • Anonymous
    June 20, 2006
    Thanks Sparrow.  Im pretty sure I have my .dll's registered correctly in the GAC, and MediaState is strong named.  My connect() method actually does work, but none of my events are being triggered.  I have one event catching the generic MSASEventHandler, and then quiet a few other specific eventhandlers.  Im trying to follow casey chesnut's sample and the way he "subscribed to state change events".  Do I need to poll for changes since this is an add in?

    Thanks for the help!

  • Anonymous
    June 20, 2006
    Is there a reason the mediastatedisplaysample doesnt work when an extender session is running?  Id rather use an app outside of media center like this example if its possible.

  • Anonymous
    August 01, 2006
    I've tried all of the suggestions here and I'm not getting any events from the MediaState.

    Any suggestions as to what might be wrong?

    I added all of the assemblies to the GAC with gacutil and still no luck.

  • Anonymous
    January 03, 2007
    Is there a workaround to the (windows.forms.)timer issue ? Thanks

  • Anonymous
    June 02, 2009
    PingBack from http://woodtvstand.info/story.php?id=45780

  • Anonymous
    June 18, 2009
    PingBack from http://cutebirdbaths.info/story.php?id=4241