<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Damian&#039;s Blog &#187; Media Center</title>
	<atom:link href="http://damianblog.com/category/media-center/feed/" rel="self" type="application/rss+xml" />
	<link>http://damianblog.com</link>
	<description>.NET from Geneva, Switzerland</description>
	<lastBuildDate>Fri, 30 Sep 2011 23:25:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Closed down MceFM</title>
		<link>http://damianblog.com/2010/04/17/closed-down-mcefm/</link>
		<comments>http://damianblog.com/2010/04/17/closed-down-mcefm/#comments</comments>
		<pubDate>Sat, 17 Apr 2010 12:40:34 +0000</pubDate>
		<dc:creator>damian</dc:creator>
				<category><![CDATA[Media Center]]></category>

		<guid isPermaLink="false">http://damianblog.com/2010/04/17/closed-down-mcefm/</guid>
		<description><![CDATA[Click here to take survey to help me decide whether to create a new release of MceFM. A couple of years ago I created a Windows Media Center addin called MceFM which let you listen to Last.fm within Media Center. However Last.fm have changed their Application Programming Interface (API), and charge for access from Switzerland [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.surveymonkey.com/s/J7PV2VL"><font color="#008000" size="3"><strong>Click here to take survey</strong></font></a><font color="#00ff00"><strong><font color="#008000" size="3"> to help me decide whether to create a new release of MceFM.</font></strong> </font></p>
<p>A couple of years ago I <a href="/2008/06/06/mcefm-10-beta-6-released/" target="_blank">created a Windows Media Center addin called MceFM</a> which let you listen to Last.fm within Media Center.</p>
<p>However Last.fm have changed their Application Programming Interface (API), and charge for access from Switzerland – leaving it unviable for me to continue…</p>
<p>Mcefm.com now redirects to this page.</p>
<p>Do check out <a href="http://beebmc.com/">BeebMC</a> which lets you listen to BBC radio within Media Center.</p>
]]></content:encoded>
			<wfw:commentRss>http://damianblog.com/2010/04/17/closed-down-mcefm/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Small utility to generate summary of your Media Center recorded movies</title>
		<link>http://damianblog.com/2008/12/21/small-utility-to-generate-summary-of-your-media-center-recorded-movies/</link>
		<comments>http://damianblog.com/2008/12/21/small-utility-to-generate-summary-of-your-media-center-recorded-movies/#comments</comments>
		<pubDate>Sun, 21 Dec 2008 20:47:14 +0000</pubDate>
		<dc:creator>dmehers</dc:creator>
				<category><![CDATA[Media Center]]></category>

		<guid isPermaLink="false">http://damianblog.com/2008/12/21/small-utility-to-generate-summary-of-your-media-center-recorded-movies/</guid>
		<description><![CDATA[I've created a small simple utility to create an HTML summary document listing all the movies I've recorded using Vista Media Center. I did this to get a compact record which I can browse without firing up Media Center, and which I can print out to give to visitors that are not familiar with Media [...]]]></description>
			<content:encoded><![CDATA[<p>I've created a small simple utility to create an HTML summary document listing all the movies I've recorded using Vista Media Center.</p>
<p>I did this to get a compact record which I can browse without firing up Media Center, and which I can print out to give to visitors that are not familiar with Media Center.</p>
<p>This is what the output looks like:</p>
<p><a href="http://www.atadore.com/images/SmallutilitytogeneratesummaryofyourMedia_12CEF/image.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="366" alt="image" src="http://www.atadore.com/images/SmallutilitytogeneratesummaryofyourMedia_12CEF/image_thumb.png" width="464" border="0" /></a></p>
<p>The links you can see are links to IMDB.</p>
<p>When you run the utility you can choose the directories it should look in, and the name of the output file:</p>
<p><a href="http://www.atadore.com/images/SmallutilitytogeneratesummaryofyourMedia_12CEF/image_3.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="298" alt="image" src="http://www.atadore.com/images/SmallutilitytogeneratesummaryofyourMedia_12CEF/image_thumb_3.png" width="463" border="0" /></a></p>
<p>The first checkbox lets you tell the utility to only output films that it has found duplicated -- I added this so that I could easily find films that I'd recorded twice by accident.&#160; The second checkbox tells it to also output the locations of the media files so that you can see where they are.</p>
<p>This tool is free, unsupported, and is to be used <u>entirely at your own risk</u>.&#160; <strong>You can download it <a href="http://damianblog.com/download/GenerateVMCMoviesHtml.exe">here</a></strong>.</p>
<p>You might also want to <a href="http://damianblog.com/2008/04/28/bulk-fetching-images-for-dvr-ms-files/">check out this other utility</a> which you can use to download image files for your films so that the images appear in generated html and also in Windows Media Center.</p>
]]></content:encoded>
			<wfw:commentRss>http://damianblog.com/2008/12/21/small-utility-to-generate-summary-of-your-media-center-recorded-movies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My PDC 2008 &quot;Show Off&quot; entry: Using .NET code injection to do the seemingly impossible</title>
		<link>http://damianblog.com/2008/11/05/my-pdc-2008-show-off-entry-using-net-code-injection-to-do-the-seemingly-impossible/</link>
		<comments>http://damianblog.com/2008/11/05/my-pdc-2008-show-off-entry-using-net-code-injection-to-do-the-seemingly-impossible/#comments</comments>
		<pubDate>Wed, 05 Nov 2008 20:29:47 +0000</pubDate>
		<dc:creator>dmehers</dc:creator>
				<category><![CDATA[Media Center]]></category>
		<category><![CDATA[Screencast]]></category>

		<guid isPermaLink="false">http://damianblog.com/2008/11/05/my-pdc-2008-show-off-entry-using-net-code-injection-to-do-the-seemingly-impossible/</guid>
		<description><![CDATA[Having come third in the first event &#34;Show Off&#34; entry, for PDC 2005, I decided to submit an entry for the 2008 PDC. I decided to base my entry on a .NET code injection blog article I'd written a couple of months ago.&#160; I got a very positive response from the people running the contest, [...]]]></description>
			<content:encoded><![CDATA[<p>Having <a href="http://channel9.msdn.com/posts/PDC2005ShowOff/How-I-Got-SQL-Intellisense-Working-in-Microsoft-Query-Analyzer/">come third</a> in the first event &quot;Show Off&quot; entry, for PDC 2005, I decided to submit an entry for the 2008 PDC.</p>
<p>I decided to base my entry on a <a href="http://damianblog.com/2008/07/02/net-code-injection/">.NET code injection blog article</a> I'd written a couple of months ago.&#160; I got a very positive response from the people running the contest, although on the night I didn't actually win. </p>
<p>I missed the showing of my entry because I was attending a dinner thrown by Microsoft Switzerland for the people that attended the PDC from Switzerland.</p>
<p>In any event, here is my entry: <a title="http://damianblog.com/DamianMehersPDC2008ShowOff.wmv" href="http://damianblog.com/DamianMehersPDC2008ShowOff.wmv">http://damianblog.com/DamianMehersPDC2008ShowOff.wmv</a></p>
<p>&#160;</p>
<p> <!-- begin embedded WindowsMedia file... --></p>
]]></content:encoded>
			<wfw:commentRss>http://damianblog.com/2008/11/05/my-pdc-2008-show-off-entry-using-net-code-injection-to-do-the-seemingly-impossible/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
<enclosure url="http://damianblog.com/DamianMehersPDC2008ShowOff.wmv" length="3426853" type="video/x-ms-wmv" />
		</item>
		<item>
		<title>MCML Scroll Button PageUp jumps to first item in list</title>
		<link>http://damianblog.com/2008/08/29/mcml-scroll-button-pageup-jumps-to-first-item-in-list/</link>
		<comments>http://damianblog.com/2008/08/29/mcml-scroll-button-pageup-jumps-to-first-item-in-list/#comments</comments>
		<pubDate>Fri, 29 Aug 2008 07:27:54 +0000</pubDate>
		<dc:creator>dmehers</dc:creator>
				<category><![CDATA[Media Center]]></category>

		<guid isPermaLink="false">http://damianblog.com/2008/08/29/mcml-scroll-button-pageup-jumps-to-first-item-in-list/</guid>
		<description><![CDATA[In BeebMC when you select a channel, you are presented with the list of programs available to &#34;Listen Again&#34;.&#160; You can scroll up and down the list using a remote control, or by positioning your mouse just before the first item, or just after the last item. I've had a request from someone that has [...]]]></description>
			<content:encoded><![CDATA[<p>In BeebMC when you select a channel, you are presented with the list of programs available to &quot;Listen Again&quot;.&#160; You can scroll up and down the list using a remote control, or by positioning your mouse just before the first item, or just after the last item.</p>
<p>I've had a request from someone that has a touch panel.&#160; They have no easy way of scrolling through their list.&#160; I've decided to add a couple of arrow buttons to let you page up/down through the list.&#160; This was pretty easy.&#160; I first added a couple of buttons to my Content:</p>
<div>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">con:TouchButton</span> <span style="color: #ff0000">Name</span><span style="color: #0000ff">=&quot;ScrollUpButton&quot;</span> <span style="color: #ff0000">Command</span><span style="color: #0000ff">=&quot;[ScrollUpCommand]&quot;</span>
                 <span style="color: #ff0000">Picture</span><span style="color: #0000ff">=&quot;resx://BeebMC/BeebMC.Resources/arrow_up_blue&quot;</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">LayoutInput</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">FormLayoutInput</span> <span style="color: #ff0000">Top</span><span style="color: #0000ff">=&quot;Parent, 0.2&quot;</span> <span style="color: #ff0000">Left</span><span style="color: #0000ff">=&quot;Parent,0.05&quot;</span><span style="color: #0000ff">/&gt;</span>
  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">LayoutInput</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">con:TouchButton</span><span style="color: #0000ff">&gt;</span>

<span style="color: #0000ff">&lt;</span><span style="color: #800000">con:TouchButton</span> <span style="color: #ff0000">Name</span><span style="color: #0000ff">=&quot;ScrollDownButton&quot;</span> <span style="color: #ff0000">Command</span><span style="color: #0000ff">=&quot;[ScrollDownCommand]&quot;</span>
                 <span style="color: #ff0000">Picture</span><span style="color: #0000ff">=&quot;resx://BeebMC/BeebMC.Resources/arrow_down_blue&quot;</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">LayoutInput</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">FormLayoutInput</span> <span style="color: #ff0000">Bottom</span><span style="color: #0000ff">=&quot;Parent, 0.80&quot;</span> <span style="color: #ff0000">Left</span><span style="color: #0000ff">=&quot;Parent,0.05&quot;</span><span style="color: #0000ff">/&gt;</span>
  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">LayoutInput</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">con:TouchButton</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>When the user clicks the button, I page up or down the scroller:</p>
<div>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">Changed</span> <span style="color: #ff0000">Source</span><span style="color: #0000ff">=&quot;[ScrollUpCommand.Invoked]&quot;</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">Actions</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">Invoke</span> <span style="color: #ff0000">Target</span><span style="color: #0000ff">=&quot;[ScrollingData.PageUp]&quot;</span><span style="color: #0000ff">/&gt;</span>
  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Actions</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Changed</span><span style="color: #0000ff">&gt;</span>

<span style="color: #0000ff">&lt;</span><span style="color: #800000">Changed</span> <span style="color: #ff0000">Source</span><span style="color: #0000ff">=&quot;[ScrollDownCommand.Invoked]&quot;</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">Actions</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">Invoke</span> <span style="color: #ff0000">Target</span><span style="color: #0000ff">=&quot;[ScrollingData.PageDown]&quot;</span><span style="color: #0000ff">/&gt;</span>
  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Actions</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Changed</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>I tested and all seemed to work well, however then I noticed that although paging down through the list worked fine, paging up was jumping straight to the <strong>first</strong> item in the list <img src='http://damianblog.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' />  </p>
<p>Eventually I discovered the problem.&#160; When you click the Up button, the scroll area loses focus, and so it seems to lose track of where it was in the list.&#160; I'm not sure why it works for the Down button.&#160; </p>
<p>In any event, the solution was to add a rule to my TouchButton UI to essentially tell it not to grab focus:</p>
<div>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">Default</span> <span style="color: #ff0000">Target</span><span style="color: #0000ff">=&quot;[Input.KeyInteractive]&quot;</span> <span style="color: #ff0000">Value</span><span style="color: #0000ff">=&quot;false&quot;</span> <span style="color: #0000ff">/&gt;</span></pre>
</div>
<p>Now it works and I am close to releasing version 2.1 of BeebMC, which should work with the Media Center TV Pack too.</p>
]]></content:encoded>
			<wfw:commentRss>http://damianblog.com/2008/08/29/mcml-scroll-button-pageup-jumps-to-first-item-in-list/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BeebMC 2.0 released: Listen Again supported</title>
		<link>http://damianblog.com/2008/07/31/beebmc-20-released-listen-again-supported/</link>
		<comments>http://damianblog.com/2008/07/31/beebmc-20-released-listen-again-supported/#comments</comments>
		<pubDate>Thu, 31 Jul 2008 17:32:37 +0000</pubDate>
		<dc:creator>dmehers</dc:creator>
				<category><![CDATA[BeebMC]]></category>
		<category><![CDATA[Media Center]]></category>

		<guid isPermaLink="false">http://damianblog.wordpress.com/2008/07/31/beebmc-20-released-listen-again-supported/</guid>
		<description><![CDATA[I've just released a new version of BeebMC, adding support for &#34;Listen Again&#34;: If/when the BBC update their web site or RSS feeds then BeebMC will probably break -- leave a comment and I'll do what I can to fix it.&#160; Many thanks to the BBC for making all this content available. BeebMC is available [...]]]></description>
			<content:encoded><![CDATA[<p>I've just released a <a href="http://www.beebmc.com/">new version of BeebMC</a>, adding support for &quot;Listen Again&quot;:</p>
<p><a href="http://damianblog.com/wp-content/uploads/2008/07/image5.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="343" alt="image" src="http://damianblog.com/wp-content/uploads/2008/07/image-thumb5.png" width="431" border="0" /></a></p>
<p><a href="http://damianblog.com/wp-content/uploads/2008/07/image11.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="343" alt="image" src="http://damianblog.com/wp-content/uploads/2008/07/image-thumb11.png" width="431" border="0" /></a></p>
<p><a href="http://damianblog.com/wp-content/uploads/2008/07/image21.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="344" alt="image" src="http://damianblog.com/wp-content/uploads/2008/07/image-thumb21.png" width="431" border="0" /></a></p>
<p>If/when the BBC update their web site or RSS feeds then BeebMC will probably break -- leave a comment and I'll do what I can to fix it.&#160; Many thanks to the BBC for making all this content available.</p>
<p>BeebMC is available here: <a title="http://www.beebmc.com/" href="http://www.beebmc.com/">http://www.beebmc.com/</a></p>
<p>The Channels.xml file under <font face="Courier New">C:\ProgramData\Atadore\BeebMC</font> has been extended to include the URL for each channel's RSS feed.&#160; Feel free to edit it to add/remove/modify channels:</p>
<div>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">&lt;</span><span style="color: #800000">Channel</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">Description</span><span style="color: #0000ff">&gt;</span>BBC 1Xtra<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Description</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">PictureUrl</span><span style="color: #0000ff">&gt;</span>http://www.bbc.co.uk/iplayer/img/nav/radio/bbc_1xtra.gif<span style="color: #0000ff">&lt;/</span><span style="color: #800000">PictureUrl</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">ChannelUrl</span><span style="color: #0000ff">&gt;</span>http://www.bbc.co.uk/iplayer/console/1xtra<span style="color: #0000ff">&lt;/</span><span style="color: #800000">ChannelUrl</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">ProgramsRss</span><span style="color: #0000ff">&gt;</span>http://feeds.bbc.co.uk/iplayer/bbc_1xtra/list<span style="color: #0000ff">&lt;/</span><span style="color: #800000">ProgramsRss</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Channel</span><span style="color: #0000ff">&gt;</span></pre>
</div>
<p>I'm going to try to add extender support next.&#160; Subscribe to the &quot;BeebMC&quot; category in my blog to be notified of updates: <a title="http://damianblog.com/category/beebmc/" href="http://damianblog.com/category/beebmc/">http://damianblog.com/category/beebmc/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://damianblog.com/2008/07/31/beebmc-20-released-listen-again-supported/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Screencast: Creating a simple Media Center Application</title>
		<link>http://damianblog.com/2008/07/12/screencast-creating-a-simple-media-center-application/</link>
		<comments>http://damianblog.com/2008/07/12/screencast-creating-a-simple-media-center-application/#comments</comments>
		<pubDate>Sat, 12 Jul 2008 21:11:47 +0000</pubDate>
		<dc:creator>dmehers</dc:creator>
				<category><![CDATA[Media Center]]></category>

		<guid isPermaLink="false">http://damianblog.wordpress.com/2008/07/12/screencast-creating-a-simple-media-center-application/</guid>
		<description><![CDATA[I've had some demand for the source for my simple application that plays BBC Radio inside Media Center. I thought it might be more valuable if I put together a screencast introducing how I created the application from scratch, although the source is below too. I assume your are familiar with .NET and C#, and [...]]]></description>
			<content:encoded><![CDATA[<p>I've had some demand for the source for my simple application that plays <a href="http://damianblog.com/2008/07/08/beebmc/">BBC Radio inside Media Center</a>.</p>
<p>I thought it might be more valuable if I put together a screencast introducing how I created the application from scratch, although the source is below too.</p>
<p>I assume your are familiar with .NET and C#, and have perhaps browsed through the Media Center documentation a little.&nbsp; If you are an experienced Media Center developer then move along, move along, there is nothing here to see.</p>
<p>The first screencast walks through the simple application that gets created for you when you create a new Media Center Application.&nbsp; I show how it works, and how you can build, install, and run it.&nbsp; It is available to be streamed or downloaded here: <a title="http://www.atadore.com/videos/MCBeeb.wmv" href="http://www.atadore.com/videos/MCBeeb.wmv">http://www.atadore.com/videos/MCBeeb.wmv</a></p>
<p>The second screencast starts when the first one leaves off, and shows how I modified the initially created application to play BBC Radio.&nbsp; It is here: <a title="http://www.atadore.com/videos/MCBeeb.wmv" href="http://www.atadore.com/videos/MCBeeb2.wmv">http://www.atadore.com/videos/MCBeeb2.wmv</a></p>
<p>The final project is <a href="http://www.atadore.com/Downloads/MCBeeb.zip">here</a>.&nbsp; It isn't quite the same as the BeebMC application (it doesn't load the channels from an XML file, and has no error checking), but feel free to play around with it.</p>
<p>I recorded them in one go quite late on a Saturday night, and I stumbled a couple of times with the terminology - please forgive the occasional mistake.</p>
<p>Hope this is useful! Do let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://damianblog.com/2008/07/12/screencast-creating-a-simple-media-center-application/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
<enclosure url="http://www.atadore.com/videos/MCBeeb.wmv" length="27325829" type="video/x-ms-wmv" />
<enclosure url="http://www.atadore.com/videos/MCBeeb2.wmv" length="30359183" type="video/x-ms-wmv" />
		</item>
		<item>
		<title>BeebMC &#8211; BBC Radio addin for Windows Media Center</title>
		<link>http://damianblog.com/2008/07/08/beebmc/</link>
		<comments>http://damianblog.com/2008/07/08/beebmc/#comments</comments>
		<pubDate>Tue, 08 Jul 2008 21:56:42 +0000</pubDate>
		<dc:creator>dmehers</dc:creator>
				<category><![CDATA[BeebMC]]></category>
		<category><![CDATA[Media Center]]></category>

		<guid isPermaLink="false">http://damianblog.wordpress.com/2008/07/08/beebmc-bbc-radio-addin-for-windows-media-center/</guid>
		<description><![CDATA[I've developed a small&#160; BBC Radio Media Center addin mainly for my own use, which I'm making available here for free for anyone else that wants it. [I've since posted a new version of BeebMC here . It supports "Listen Again".&#160;&#160; I recommend going to this posting to read about it and download it.] There [...]]]></description>
			<content:encoded><![CDATA[<p>I've developed a small&nbsp; BBC Radio Media Center addin mainly for my own use, which I'm making available here for free for anyone else that wants it.</p>
<p><strong>[I've since posted a new version of BeebMC <a href="/2008/07/31/beebmc-20-released-listen-again-supported/">here</a> . It supports "Listen Again".&nbsp;&nbsp; I recommend going to <a href="/2008/07/31/beebmc-20-released-listen-again-supported/">this posting</a> to read about it and download it.]</strong></p>
<p>There are a couple of restrictions:</p>
<ul>
<li>Your need Real Player installed
<li>You need version 3.5 of the .NET framework installed.&nbsp; It is available <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=333325FD-AE52-4E35-B531-508D977D32A6&amp;displaylang=en" target="_blank">here</a> if you don't have it (or if you are not sure).
<li>It will <strong>not work with Extenders</strong>, since the BBC streams using Real Audio.</li>
</ul>
<p>I can't promise a lot of support, but reply here if you have problems using it and I'll help if I can.</p>
<p>Once installed you'll find it under the Music menu:</p>
<p><a href="http://damianblog.com/wp-content/uploads/2008/08/image5.png"><img style="border-width:0;" height="368" alt="image" src="http://damianblog.com/wp-content/uploads/2008/08/image5-thumb.png" width="456" border="0"></a></p>
<p>Click on a channel to play that channel:</p>
<p><a href="http://damianblog.com/wp-content/uploads/2008/07/image3.png"><img style="border-width:0;" height="362" alt="image" src="http://damianblog.com/wp-content/uploads/2008/07/image-thumb3.png" width="449" border="0"></a>&nbsp; </p>
<p>You can customize it by editing the <strong>Channels.xml</strong> file you will find under <font face="Courier New">C:\ProgramData\Atadore\BeebMC. </font><font face="ge">Add channels by adding a Channel element with the appropriate description, picture and URL for playing the channel.</font></p>
<p><a href="http://damianblog.com/wp-content/uploads/2008/07/image4.png"><img style="border-width:0;" height="219" alt="image" src="http://damianblog.com/wp-content/uploads/2008/07/image-thumb4.png" width="442" border="0"></a>&nbsp;</p>
<p><strong>[I've since posted a new version of BeebMC <a href="/2008/07/31/beebmc-20-released-listen-again-supported/">here</a> . It supports "Listen Again".&nbsp;&nbsp; I recommend going to <a href="/2008/07/31/beebmc-20-released-listen-again-supported/">this posting</a> to read about it and download it.]</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://damianblog.com/2008/07/08/beebmc/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>.NET Code Injection</title>
		<link>http://damianblog.com/2008/07/02/net-code-injection/</link>
		<comments>http://damianblog.com/2008/07/02/net-code-injection/#comments</comments>
		<pubDate>Wed, 02 Jul 2008 12:56:20 +0000</pubDate>
		<dc:creator>dmehers</dc:creator>
				<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Media Center]]></category>

		<guid isPermaLink="false">http://damianblog.wordpress.com/2008/07/02/net-code-injection/</guid>
		<description><![CDATA[In this post I'll show how you can inject your own .NET code into a process that is already running the .NET framework. I needed to do this when developing for Windows Media Center because there is no official documented way to determine what page is currently being displayed in Media Center. I wanted to [...]]]></description>
			<content:encoded><![CDATA[<p>In this post I'll show how you can inject your own .NET code into a process that is already running the .NET framework.</p>
<p>I needed to do this when developing for <a href="http://en.wikipedia.org/wiki/Windows_Media_Center" target="_blank">Windows Media Center</a> because there is no official documented way to determine what page is currently being displayed in Media Center.</p>
<p>I wanted to know when the user is showing the Media Center "now playing" page.</p>
<p>Media Center addins run in a completely separate process to the main Media Center process, which is ehshell.exe.&nbsp; Calls you make in your addin are remoted across to the Media Center ehshell.exe process.</p>
<p>The solution works using:</p>
<ul>
<li>an "Injecter" C# class&nbsp; which uses <a href="http://msdn.microsoft.com/en-us/library/ms682437.aspx" target="_blank">CreateRemoteThread</a> to load a Bootstrap DLL into the ehshell.exe process
<li>The "Bootstrap" C++ DLL which is injected into the ehshell.exe process uses the <a href="http://msdn.microsoft.com/en-us/magazine/cc163567.aspx" target="_blank">CLR Hosting API</a> to attach to the default .NET domain, and then load an instance of the "Injectee" C# class
<li>The "Injectee" C# class is loaded by the "Bootstrap" DLL and runs within the ehshell.exe process.&nbsp; It uses reflection to subscribe to an event within the ehshell.exe process and then sends an interprocess message when the event fires</li>
</ul>
<h3>The "Injecter"</h3>
<p>Using <a href="http://www.aisto.com/roeder/dotnet/" target="_blank">Reflector</a>, I looked around at the ehshell.exe assembly, and related assemblies, and eventually discovered that there is a PageChanged event fired by the ServiceBus.UIFramework.PageBasedUCPService class:</p>
<p><a href="http://damianblog.com/wp-content/uploads/2008/07/image5.png"><img style="border-width:0;" height="309" alt="image" src="http://damianblog.com/wp-content/uploads/2008/07/image-thumb5.png" width="465" border="0"></a>&nbsp;</p>
<p>What is more, there is a static PageBasedUCPService.DefaultUCP method to return a PageBasedUCPService instance.</p>
<p>There are of course a couple of problems.&nbsp; The first problem being that these classes are internal to the ehshell assembly,&nbsp; the second issue being that these are all running in a totally separate process to my addin.</p>
<p>I searched a little, and came across <a href="http://theoklibrary.org/showthread.php?p=605" target="_blank">this example</a> showing how you could use the <a href="http://msdn.microsoft.com/en-us/library/ms682437.aspx" target="_blank">CreateRemoteThread</a> from .NET to inject your own native code into a remote process.</p>
<p>Essentially it <a href="http://msdn.microsoft.com/en-us/library/ms684320(VS.85).aspx" target="_blank">opens a handle</a> to the remote process, finds the <a href="http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx" target="_blank">LoadLibrary</a> system call's address in the remote process, <a href="http://msdn.microsoft.com/en-us/library/aa366890(VS.85).aspx" target="_blank">allocates a chunk of memory</a> in the process, and fills the memory with a LoadLibrary call to load a DLL that you specify, and then creates the thread in the remote process, passing the address of the chunk of memory as the starting point for the thread.</p>
<p>I recommend taking a look at the CRT call in the <a href="http://theoklibrary.org/showthread.php?p=605" target="_blank">example</a>.&nbsp; I'll not be duplicating the code here.</p>
<p>To use the CRT call, I first find Media Center:</p>
<div>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> Process FindMediaCenterProcess() {
  <span style="color:#008000;">// Could be more than one if an extender is running too</span>
  <span style="color:#0000ff;">foreach</span> (Process process <span style="color:#0000ff;">in</span> Process.GetProcessesByName(<span style="color:#006080;">"ehshell"</span>)) {
    <span style="color:#0000ff;">if</span> (process.SessionId == Process.GetCurrentProcess().SessionId) {
      <span style="color:#0000ff;">return</span> process;
    }
  }
  <span style="color:#0000ff;">return</span> <span style="color:#0000ff;">null</span>;
}</pre>
</div>
<p>I can then call the CRT method:</p>
<div>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;">Process mediaCenterProcess = FindMediaCenterProcess();
IntPtr hwnd;
<span style="color:#0000ff;">string</span> error;
CRT(mediaCenterProcess, dllPath, <span style="color:#0000ff;">out</span> error, <span style="color:#0000ff;">out</span> hwnd);
</pre>
</div>
<p>The dllPath is the full path to my C++ DLL, in my case this was </p>
<div>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;">Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) +
                                  <span style="color:#006080;">@"\Atadore\MceFM\InjectBootstrap.dll"</span></pre>
</div>
<div>&nbsp;</div>
<h3>The "Boostrap DLL"</h3>
<p>The InjectBootstrap.dll is a pretty simple C++ library project.&nbsp; The DllMain calls a bootstrap function when the process is loaded:</p>
<div>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;">BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    <span style="color:#0000ff;">switch</span> (ul_reason_for_call)
    {
    <span style="color:#0000ff;">case</span> DLL_PROCESS_ATTACH:
        Bootstrap();
        <span style="color:#0000ff;">break</span>;
    <span style="color:#0000ff;">case</span> DLL_THREAD_ATTACH:
    <span style="color:#0000ff;">case</span> DLL_THREAD_DETACH:
    <span style="color:#0000ff;">case</span> DLL_PROCESS_DETACH:
        <span style="color:#0000ff;">break</span>;
    }
    <span style="color:#0000ff;">return</span> TRUE;
}
</pre>
</div>
<div>&nbsp;</div>
<div>My bootstrap function attaches to the default .NET domain and loads an instance of one of my own classes:</div>
<div>&nbsp;</div>
<div>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;">#include <span style="color:#006080;">"stdafx.h"</span>
#include &lt;stdio.h&gt;
#include <span style="color:#006080;">"objbase.h"</span>
#include <span style="color:#006080;">"MSCorEE.h"</span>
#import <span style="color:#006080;">"C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.tlb"</span> raw_interfaces_only
<span style="color:#0000ff;">using</span> <span style="color:#0000ff;">namespace</span> mscorlib;

<span style="color:#0000ff;">void</span> Bootstrap() {
    OutputDebugString(L<span style="color:#006080;">"MceFM Bootstrap Started"</span>);

    CoInitializeEx(0, COINIT_MULTITHREADED );
    ICorRuntimeHost* pICorRuntimeHost = 0;
    HRESULT st = CoCreateInstance(CLSID_CorRuntimeHost, 0, CLSCTX_ALL,
        IID_ICorRuntimeHost, (<span style="color:#0000ff;">void</span>**)&amp;pICorRuntimeHost);
    <span style="color:#0000ff;">if</span>(!pICorRuntimeHost) <span style="color:#0000ff;">return</span>; <span style="color:#008000;">// Clean up and log errror ...</span>

    HDOMAINENUM hEnum = NULL;
    pICorRuntimeHost-&gt;EnumDomains(&amp;hEnum);

    <span style="color:#0000ff;">if</span>(!hEnum) <span style="color:#0000ff;">return</span>; <span style="color:#008000;">// Clean up and log errror ...</span>

    IUnknown* pUunk = 0;
    st = pICorRuntimeHost-&gt;NextDomain(hEnum, &amp;pUunk);
    <span style="color:#0000ff;">if</span>(!pUunk) <span style="color:#0000ff;">return</span>; <span style="color:#008000;">// Clean up and log errror ...</span>

    _AppDomain * pCurDomain = NULL;
    st = pUunk-&gt;QueryInterface(__uuidof(_AppDomain), (VOID**)&amp;pCurDomain);
    <span style="color:#0000ff;">if</span>(!pCurDomain) <span style="color:#0000ff;">return</span>; <span style="color:#008000;">// Clean up and log errror ...</span>

    _bstr_t assemblyName =
        <span style="color:#006080;">"Last, Version=1.1.0.0, Culture=neutral, PublicKeyToken=792d614cdf38e9ce"</span>;
    _bstr_t typeName = <span style="color:#006080;">"MceFM.Last.Inject.Injectee"</span>;

    _ObjectHandle* pObjectHandle = 0;

    pCurDomain-&gt;CreateInstance(assemblyName, typeName, &amp;pObjectHandle);

}</pre>
</div>
<div>&nbsp;</div>
<h3>The "Injectee"</h3>
<p>Finally we come to the Injectee class, which is loaded by the DLL, and runs inside the remote (ehshell.exe) process.&nbsp; It is in a strongly named assembly which is stored in the GAC, so that the bootstrap call above can find it (note the strong name in the assembly name bstr).</p>
<p>I use a static constructor (which runs as soon as the class is loaded).&nbsp; In this static constructor I subscribe to the event:</p>
<div>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;"><span style="color:#0000ff;">using</span> System;
<span style="color:#0000ff;">using</span> System.Collections.Generic;
<span style="color:#0000ff;">using</span> System.Diagnostics;
<span style="color:#0000ff;">using</span> System.Net;
<span style="color:#0000ff;">using</span> System.Reflection;
<span style="color:#0000ff;">using</span> System.Reflection.Emit;
<span style="color:#0000ff;">using</span> System.Threading;

<span style="color:#0000ff;">namespace</span> MceFM.Last.Inject {
  <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> Injectee {

    <span style="color:#0000ff;">static</span> Injectee() {
      <span style="color:#0000ff;">try</span> {
        Assembly ehshell = Assembly.Load(<span style="color:#006080;">"ehshell"</span>);

        <span style="color:#008000;">// Get the PageBasedUCPService type</span>
        Type pageBasedUCPServiceType =
          ehshell.GetType(<span style="color:#006080;">"ServiceBus.UIFramework.PageBasedUCPService"</span>);

        <span style="color:#008000;">// Call static DefaultUCP method to get a PageBasedUCPService instance</span>
        <span style="color:#0000ff;">const</span> BindingFlags bindingFlags = BindingFlags.DeclaredOnly |
          BindingFlags.Static | BindingFlags.Public | BindingFlags.GetProperty;
        <span style="color:#0000ff;">object</span>[] args = <span style="color:#0000ff;">new</span> <span style="color:#0000ff;">object</span>[0];
        <span style="color:#0000ff;">object</span> defaultUCP = pageBasedUCPServiceType.InvokeMember(<span style="color:#006080;">"DefaultUCP"</span>,
          bindingFlags, <span style="color:#0000ff;">null</span>, <span style="color:#0000ff;">null</span>, args);

        <span style="color:#008000;">// Get a reference to the PageChanged event</span>
        EventInfo pageChangedEventInfo =
          pageBasedUCPServiceType.GetEvent(<span style="color:#006080;">"PageChanged"</span>);
        Type pageChangedDelegate = pageChangedEventInfo.EventHandlerType;

        <span style="color:#008000;">// Get the MethodInfo for the method to be called when the event fires</span>
        MethodInfo newPageHandlerMethodInfo =
          <span style="color:#0000ff;">typeof</span>(Injectee).GetMethod(<span style="color:#006080;">"NewPageHandler"</span>);

        <span style="color:#008000;">// Build an array of types used for new method we shall dynamically emit</span>
        Type pageType = ehshell.GetType(<span style="color:#006080;">"ServiceBus.UIFramework.Page"</span>);
        Type[] pageChangedDelegateParameters = <span style="color:#0000ff;">new</span>[] { pageType };

        <span style="color:#008000;">// Need a dynamic method because we can't create a method that has</span>
        <span style="color:#008000;">// the Page type as a parameter</span>
        DynamicMethod dynamicHandler = <span style="color:#0000ff;">new</span> DynamicMethod(<span style="color:#006080;">""</span>, <span style="color:#0000ff;">null</span>,
          pageChangedDelegateParameters, <span style="color:#0000ff;">typeof</span>(Injectee));
        ILGenerator ilgen = dynamicHandler.GetILGenerator();
        ilgen.Emit(OpCodes.Nop);
        ilgen.Emit(OpCodes.Ldarg_0);
        ilgen.Emit(OpCodes.Call, newPageHandlerMethodInfo);
        ilgen.Emit(OpCodes.Nop);
        ilgen.Emit(OpCodes.Ret);

        <span style="color:#0000ff;">if</span>(pageChangedDelegate != <span style="color:#0000ff;">null</span>) {
          <span style="color:#008000;">// Subscribe to the event</span>
          Delegate dEmitted = dynamicHandler.CreateDelegate(pageChangedDelegate);
          pageChangedEventInfo.GetAddMethod().Invoke(defaultUCP,
                                                     <span style="color:#0000ff;">new</span> <span style="color:#0000ff;">object</span>[] {dEmitted});
        }
      } <span style="color:#0000ff;">catch</span>(Exception ex) {
        Trace.TraceError(<span style="color:#006080;">"Unexpected error in Injectee initializer: {0}"</span>, ex);
        Trace.TraceError(ex.StackTrace);
      }
    }

    <span style="color:#008000;">// Queue of new pages that have been navigated to.  Decouples event handler</span>
    <span style="color:#008000;">// from re-despatching of the event to the addin process that is told</span>
    <span style="color:#008000;">// of the new event.</span>
    <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">readonly</span> Queue&lt;<span style="color:#0000ff;">string</span>&gt; newPages = <span style="color:#0000ff;">new</span> Queue&lt;<span style="color:#0000ff;">string</span>&gt;();

    <span style="color:#008000;">// Indicates whether background thread that despatches events is running</span>
    <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">bool</span> notifierActive;

    <span style="color:#008000;">// Called when Media Center navigates to a new page</span>
    <span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">void</span> NewPageHandler(<span style="color:#0000ff;">object</span> page) {
      Trace.TraceInformation(<span style="color:#006080;">"New Page: "</span> + page);
      <span style="color:#0000ff;">lock</span>(newPages) {
        <span style="color:#0000ff;">if</span>(!notifierActive) {
          Thread thread = <span style="color:#0000ff;">new</span> Thread(NewPageNotifier) {IsBackground = <span style="color:#0000ff;">true</span>};
          thread.Start();
          notifierActive = <span style="color:#0000ff;">true</span>;
        }
        newPages.Enqueue(page.GetType().FullName);
        Monitor.Pulse(newPages);
      }
    }

    <span style="color:#008000;">// Thread that despatches events to addin process telling it that</span>
    <span style="color:#008000;">// a new page has been navigated to</span>
    <span style="color:#0000ff;">private</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">void</span> NewPageNotifier() {
      <span style="color:#0000ff;">while</span>(<span style="color:#0000ff;">true</span>) {
        <span style="color:#0000ff;">string</span> page;

        <span style="color:#0000ff;">lock</span>(newPages) {
          <span style="color:#0000ff;">while</span>(newPages.Count == 0) {
            Monitor.Wait(newPages);
          }
          page = newPages.Dequeue();
        }

        <span style="color:#0000ff;">try</span> {
          <span style="color:#008000;">// Use whatever interprocess notification mechanism you wish.</span>
          <span style="color:#008000;">// WCF could be good.  Here I use a simple web call.  My</span>
          <span style="color:#008000;">// addin has a web server in it to receive these calls.</span>
          WebClient webClient = <span style="color:#0000ff;">new</span> WebClient();
          webClient.QueryString[Server.PAGE_QUERY_STRING] = page;
          webClient.DownloadString(Util.LocalBaseUrl
                                   + Server.MCE_PAGE_CHANGED_ACTION);
        } <span style="color:#0000ff;">catch</span> (Exception ex) {
          Trace.TraceError(<span style="color:#006080;">"Error while sending new page notification: {0}"</span>, ex);
        }
      }
<span style="color:#cc6633;">#pragma</span> warning disable FunctionNeverReturns
    }
<span style="color:#cc6633;">#pragma</span> warning restore FunctionNeverReturns
  }
}</pre>
</div>
<div>&nbsp;</div>
<h3>The Result</h3>
<p>In my web server running within my addin (which is notified by the "NewPageNotifier" method above), I keep track of which is the current page, and log information when the page changes:</p>
<div>&nbsp;</div>
<div>
<pre style="font-size:8pt;overflow:visible;width:100%;color:black;line-height:12pt;font-family:consolas, 'Courier New', courier, monospace;background-color:#f4f4f4;border-style:none;margin:0;padding:0;">Server notified of page change MediaCenter.Audio.AudioNowPlayingPage
Server notified of page change MediaCenter.Audio.AudioNowPlayingTracklistPage
</pre>
</div>
<p>All this means that if you are a Last.fm user and want to tell Last.fm that you love a track that is currently playing then you can press the right-button on your remote control on the "now playing" page using my <a href="http://www.mcefm.com/" target="_blank">MceFM addin</a>.</p>
<p>I use low level system hooks to know when you press the right button, and the above technique to know that you are on the "now playing" page:</p>
<p><a href="http://damianblog.com/wp-content/uploads/2008/07/image11.png"><img style="border-width:0;" height="380" alt="image" src="http://damianblog.com/wp-content/uploads/2008/07/image-thumb11.png" width="476" border="0"></a></p>
<p><strong>Word if warning</strong>.&nbsp; If/When Media Center changes its internal structure this technique will completely fall over.&nbsp; Use sparingly, entirely at your own risk,&nbsp; to do the seemingly impossible.</p>
]]></content:encoded>
			<wfw:commentRss>http://damianblog.com/2008/07/02/net-code-injection/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Using mdbg to debug at the MSIL level instead of assembly code.</title>
		<link>http://damianblog.com/2008/06/12/using-mdbg-to-debug-at-the-il-level-instead-of-assembly-code/</link>
		<comments>http://damianblog.com/2008/06/12/using-mdbg-to-debug-at-the-il-level-instead-of-assembly-code/#comments</comments>
		<pubDate>Thu, 12 Jun 2008 10:32:13 +0000</pubDate>
		<dc:creator>dmehers</dc:creator>
				<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Media Center]]></category>

		<guid isPermaLink="false">http://damianblog.wordpress.com/2008/06/12/using-mdbg-to-debug-at-the-il-level-instead-of-assembly-code/</guid>
		<description><![CDATA[Windows Media Center (MCE) lets you create addins to provide new functionality.&#160; There are two kinds of addins -- normal addins, and background addins.&#160; 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 [...]]]></description>
			<content:encoded><![CDATA[<p>Windows Media Center (MCE) lets you create addins to provide new functionality.&nbsp; There are two kinds of addins -- normal addins, and background addins.&nbsp; Background addins run continuously as soon as MCE starts up, and are limited in the user-interaction they provide.</p>
<p>One thing they <em>are</em> allowed to do is to pop up a dialog message to the user using the <em>AddInHost.Current.MediaCenterEnvironment.Dialog(...)</em> method call.</p>
<p>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.</p>
<p>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.</p>
<p>Using <a href="http://en.wikipedia.org/wiki/.NET_Reflector" target="_blank">Reflector</a> I could see that the call was eventually failing in <em>MediaCenter.Extensibility.ExtensibilityAutomation.EnforceApplicationPermission(...) </em>which was calling through to<em> Microsoft.MediaCenter.Hosting.Infrastructure.RegisteredApps.IsBackgroundEntryPoint</em> which looks like this:</p>
<p><font face="Courier New" size="2">public static bool IsBackgroundEntryPoint(ExtensibilityEntryPointInfo epi)<br />{<br />&nbsp;&nbsp;&nbsp; return (0 == string.Compare(epi.Category, "Background", true,<br />CultureInfo.InvariantCulture));<br />} </font></p>
<p>Somehow I needed a way to use the debugger to see what the <em>epi.Category</em> value was when the call was failing.</p>
<p>The standard Visual Studio debugger just drops you through to x86 assembly code if it has no debugging symbols.&nbsp; I needed a debugger which shows <a href="http://en.wikipedia.org/wiki/Common_Intermediate_Language" target="_blank">.NET IL</a> instead.</p>
<p>This is where <a href="http://msdn.microsoft.com/en-us/library/ms229861.aspx" target="_blank">mdbg</a> comes in. Mdbg is a command line debugger created by <a href="http://blogs.msdn.com/jmstall/" target="_blank">Mike Stall</a>.</p>
<p>Once you have <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=38449a42-6b7a-4e28-80ce-c55645ab1310&amp;displaylang=en" target="_blank">downloaded</a> it and started running it, then you can use the '<strong>a</strong>' command to list available processes, and then <strong>'a &lt;pid&gt;</strong>' to attach to a specific process.</p>
<p>Once attached, you can set a breakpoint using '<strong>br &lt;module name&gt;!&lt;type&gt;.&lt;method name&gt;</strong>", and then '<strong>go</strong>' to resume:</p>
<p><a href="http://damianblog.com/wp-content/uploads/2008/06/image7.png"><img style="border-width:0;" height="214" alt="image" src="http://damianblog.com/wp-content/uploads/2008/06/image-thumb7.png" width="477" border="0"></a> </p>
<p>Once the breakpoint is hit, you can use the '<strong>print</strong>' command to display a parameter value:</p>
<p><a href="http://damianblog.com/wp-content/uploads/2008/06/image8.png"><img style="border-width:0;" height="98" alt="image" src="http://damianblog.com/wp-content/uploads/2008/06/image-thumb8.png" width="472" border="0"></a></p>
<p>There is also a GUI which can be invoked using '<strong>load gui'</strong>:</p>
<p>&nbsp;<a href="http://damianblog.com/wp-content/uploads/2008/06/image9.png"><img style="border-width:0;" height="408" alt="image" src="http://damianblog.com/wp-content/uploads/2008/06/image-thumb9.png" width="470" border="0"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://damianblog.com/2008/06/12/using-mdbg-to-debug-at-the-il-level-instead-of-assembly-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MceFM 1.0 Beta 6 released</title>
		<link>http://damianblog.com/2008/06/06/mcefm-10-beta-6-released/</link>
		<comments>http://damianblog.com/2008/06/06/mcefm-10-beta-6-released/#comments</comments>
		<pubDate>Fri, 06 Jun 2008 08:30:48 +0000</pubDate>
		<dc:creator>dmehers</dc:creator>
				<category><![CDATA[Media Center]]></category>

		<guid isPermaLink="false">http://damianblog.wordpress.com/2008/06/06/mcefm-10-beta-6-released/</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>I'm finally feeling as though I am getting very close to the first non-beta release of <a href="http://www.mcefm.com/" target="_blank">MceFM</a>.</p>
<p>I decided to remove MceFM's Queue page (which was by all accounts rather ugly anyway) and just to use the standard <a href="http://en.wikipedia.org/wiki/Windows_Media_Center" target="_blank">Windows Media Center</a> music related pages (Now Playing, and View Queue).</p>
<h3>MSAS Fun</h3>
<p>I needed to detect Media Center events in order to know when a song changes, etc. </p>
<p>The standard way to do this is using the <a href="http://msdn.microsoft.com/en-us/library/ms816495.aspx" target="_blank">Media State Aggregation Service</a> (MSAS), and I got this working.&nbsp; However it is rather flaky, and in the end I threw away the MSAS code I'd written, and took a different approach.&nbsp; The code is <a href="http://damianblog.com/2008/05/20/creating-msas-sinks-in-c/" target="_blank">here</a> if anyone wants it.</p>
<p>I'm embedding an instance of the <a href="http://msdn.microsoft.com/en-us/library/bb249308(VS.85).aspx" target="_blank">Windows Media Player (WMP) ActiveX Control</a> in a hidden window attached to the MceFM background application.&nbsp; The WMP control runs in "<a href="http://msdn.microsoft.com/en-us/library/bb249234(VS.85).aspx" target="_blank">remote</a>" mode, so that it reflects what is happening with the WMP instance used by Media Center.&nbsp; Using this control I can detect when songs start playing.</p>
<h3>Detecting Remote Control button pushes</h3>
<p>I also went through a weird and wonderful journey with regards to allowing users mark songs as Loved or Banned in Last.fm.&nbsp; 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.&nbsp; Two things were needed -- how to detect when the key is pressed, and how to know when the Now Playing page is being displayed.</p>
<p>I initially decided to use the colored buttons that appear on my remote control (Red, Green, Yellow, Blue) which are used for <a href="http://en.wikipedia.org/wiki/Teletext" target="_blank">teletext</a>.&nbsp; These buttons can't be intercepted using the normal techniques (low level system hooks), but can be detected using <a href="http://msdn.microsoft.com/en-us/library/ms645600(VS.85).aspx" target="_blank">RegisterRawInputDevices</a> and looking for RAWINPUT Windows Messages.&nbsp; I got this working fine on my computer (RAWINPUT 91=Red, 92=Green, 93=Yellow, 94=Blue).</p>
<p>My idea was to let people press the Red button to Ban a song, and the Green button to Love a song.&nbsp; I got this all working great.&nbsp; Then I hit two issues.</p>
<p>The first issue is that the RegisterRawInputDevices mechanism didn't work at all for extenders.</p>
<p>The second issue is that only European Media Center remote controls appear to have the colored buttons.&nbsp; D'oh. </p>
<p>I had to throw the whole approach overboard and start again from scratch.</p>
<p>I ended up letting you press the Left or Right arrow buttons on the remote control, which <em>can</em> be detected using low level system hooks, and <em>do</em> work on Extenders.&nbsp; Whew.</p>
]]></content:encoded>
			<wfw:commentRss>http://damianblog.com/2008/06/06/mcefm-10-beta-6-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

