<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>The League of Paul</title>
	
	<link>http://www.theleagueofpaul.com/blog</link>
	<description>Blog of Paul ("Aeoth") Jenkins, forging the way into awesomeness through Android and WPF/.NET dev</description>
	<lastBuildDate>Thu, 02 Sep 2010 00:00:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/TheLeagueOfPaul" /><feedburner:info uri="theleagueofpaul" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>MahApps.Twitter library for Windows Phone 7 (WIP)</title>
		<link>http://feedproxy.google.com/~r/TheLeagueOfPaul/~3/hjqza6NpIF4/</link>
		<comments>http://www.theleagueofpaul.com/blog/2010/09/02/mahapps-twitter-library-for-windows-phone-7-wip/#comments</comments>
		<pubDate>Thu, 02 Sep 2010 00:00:22 +0000</pubDate>
		<dc:creator>Paul</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[MahApps]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[WP7]]></category>

		<guid isPermaLink="false">http://www.theleagueofpaul.com/blog/2010/09/02/mahapps-twitter-library-for-windows-phone-7-wip/</guid>
		<description><![CDATA[Eventually there will be MahTweets for Windows Phone 7 (WP7), but for now I’m concentrating on getting the base library done. One of the advantages is with anything .NET is that you can reuse code from platform to platform – ie, the same C# that works on desktop can work on the web via ASP.NET [...]]]></description>
			<content:encoded><![CDATA[<p><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="mahapps.twitter" border="0" alt="mahapps.twitter" src="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/09/mahapps.twitter.png" width="368" height="281" /> </p>
<p>Eventually there will be MahTweets for Windows Phone 7 (WP7), but for now I’m concentrating on getting the base library done. One of the advantages is with anything .NET is that you can reuse code from platform to platform – ie, the same C# that works on desktop can work on the web via ASP.NET or in games on the Xbox 360. Kinda. The problem is the compact/minimal variants such as Silverlight or WP7’s Silverlight don’t cover 100% of the “desktop” .NET or don’t work with third party libraries, or the Client Profile which lacks certain core libraries (such as System.Web). In this case, being Silverlight, everything has to be asynchronous, and is <em>Silverlight 3</em> based, rather than the current release of Silverlight 4.</p>
<p>Currently there is no real error checking/handling, nor any tests, but the basics work. MahApps.Twitter makes use of JSON.NET (for deserialisation) and Hammock (for OAuth and REST requesting)</p>
<p>Eventually this library will also come in a desktop flavour, it’s just a matter of time.</p>
<p>&#160;</p>
<p><a href="http://mahappstwitter.codeplex.com/">You can grab the full code on Codeplex</a>, released under the MS-PL. At this stage there is no binary release.</p>
<p>&#160;</p>
<h3>Example Usage</h3>
<p>Obviously, make sure YOURKEY, YOURSECRET and YOURREDIRECTURL are changed. This is example code for SetupView.xaml.cs – an PhoneApplicationPage. You will need a webbrowser to do the initial OAuth authorisation dance. I don’t have XAuth to test against, and I also believe it defeats the purpose of OAuth in the first place, so it isn’t currently covered by the library. If you wish to contribute something XAuthey, comment below or contact me via Codeplex :)</p>
</p>
<pre class="brush: csharp;">private const string ConsumerKey = &quot;YOURKEY&quot;;
private const string ConsumerSecret = &quot;YOURSECRET&quot;;
private TwitterClient t;
public SetupView()
{
    InitializeComponent();

    t = new TwitterClient(ConsumerKey, ConsumerSecret);
    t.BeginGetRequestUrl(RequestUrlCallback);
}

public void RequestUrlCallback(RestRequest request, RestResponse response, String Url)
{
    wbBrowser.Navigate(new Uri(Url));
}

private void wbBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
    //If it contains mahtweets.com, it is redirecting.
    if (e.Uri.AbsoluteUri.Contains(&quot;YOURREDIRECTURL&quot;))
    {
        t.BeginGetAccessToken(e.Uri,AccessTokensCallback);
    }
}

public void AccessTokensCallback(RestRequest request, RestResponse response, Credentials Tokens)
{
    //STORE THESE TOKENS!
    t.SetOAuthToken(Tokens);

    //Get information about the authorised user
    //t.Account.BeginVerifyCredentials(VerifyCredentialsCallback);
}

public void VerifyCredentialsCallback(RestRequest request, RestResponse response, ITwitterResponse Response)
{
    User u = ((User) Response);

    //Do cross thread GUI shit for WP7/SL/WPF and you could do Application.Name = u.Name
}</pre>
<p>&#8216;</p>
<img src="http://feeds.feedburner.com/~r/TheLeagueOfPaul/~4/hjqza6NpIF4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.theleagueofpaul.com/blog/2010/09/02/mahapps-twitter-library-for-windows-phone-7-wip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.theleagueofpaul.com/blog/2010/09/02/mahapps-twitter-library-for-windows-phone-7-wip/</feedburner:origLink></item>
		<item>
		<title>MediaScout: Now sans Paul</title>
		<link>http://feedproxy.google.com/~r/TheLeagueOfPaul/~3/MVKbHzVMM5U/</link>
		<comments>http://www.theleagueofpaul.com/blog/2010/08/16/mediascout-now-sans-paul/#comments</comments>
		<pubDate>Mon, 16 Aug 2010 04:33:39 +0000</pubDate>
		<dc:creator>Paul</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[MediaScout]]></category>

		<guid isPermaLink="false">http://www.theleagueofpaul.com/blog/2010/08/16/mediascout-now-sans-paul/</guid>
		<description><![CDATA[One of my first C#/OSS projects was TVScout, which eventually was renamed to MediaScout. Once it had a sufficient level of functionality, I grew disinterested with the project and ended up abandoning it. Krishmav has taken over as the project lead – I’ve stepped down. There is no bad blood here, just somebody interested in [...]]]></description>
			<content:encoded><![CDATA[<p>One of my first C#/OSS projects was TVScout, which eventually was renamed to MediaScout. Once it had a sufficient level of functionality, I grew disinterested with the project and ended up abandoning it. <a href="http://www.codeplex.com/site/users/view/krishmav">Krishmav</a> has taken over as the project lead – I’ve stepped down. There is no bad blood here, just somebody interested in picking up where I left off. I am a little sad that none of my icons or artwork are in use anymore, but c’est la vie.</p>
<p>The last version I was involved with was v0.9c, while the new version is now errr version <em>3 Preview 2.</em> Since I was running it all on my Windows Home Server, I’m unable to use the newer versions (requires Windows 7), so I’ll be sticking with my old versions for now.</p>
<p><a href="http://tvscout.codeplex.com/">MediaScout is available from Codeplex</a>, in both source and binary form.</p>
<img src="http://feeds.feedburner.com/~r/TheLeagueOfPaul/~4/MVKbHzVMM5U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.theleagueofpaul.com/blog/2010/08/16/mediascout-now-sans-paul/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.theleagueofpaul.com/blog/2010/08/16/mediascout-now-sans-paul/</feedburner:origLink></item>
		<item>
		<title>Twitter User Streams</title>
		<link>http://feedproxy.google.com/~r/TheLeagueOfPaul/~3/6YE2EfiAk4U/</link>
		<comments>http://www.theleagueofpaul.com/blog/2010/08/03/twitter-user-streams/#comments</comments>
		<pubDate>Tue, 03 Aug 2010 01:02:00 +0000</pubDate>
		<dc:creator>Paul</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[MahTweets]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://www.theleagueofpaul.com/blog/2010/08/03/twitter-user-streams/</guid>
		<description><![CDATA[Twitter has for awhile had streaming support for larger volume of Tweets, usually processed by companies offering analytics or searching or other &#8216;services&#8217; that need a high volume to make stuff work. Streaming maintains a very long HTTP session (infinitely long?), where Twitter pushes the data to you. In the case of &#34;firehose&#34; or &#34;gardenhose&#34;, [...]]]></description>
			<content:encoded><![CDATA[<p>Twitter has for awhile had streaming support for larger volume of Tweets, usually processed by companies offering analytics or searching or other &#8216;services&#8217; that need a high volume to make stuff work. Streaming maintains a very long HTTP session (infinitely long?), where Twitter pushes the data to you. In the case of &quot;firehose&quot; or &quot;gardenhose&quot;, they&#8217;re all public Tweets, sometimes filtered to keywords, etc.</p>
<p><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Untitled-1" border="0" alt="Untitled-1" src="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/08/Untitled1.png" width="573" height="589" /></p>
<p>&#160;</p>
<p>Another analogy is the long car trip with kids in the back. The standard RESTful API is the children asking <em>&quot;Are we there yet? Are we there yet? Are we there yet?&quot;, </em>whereas Streaming is the parents in the front saying <em>&quot;I&#8217;ll tell you when we are there…. we&#8217;re there&quot;</em></p>
<p>From Twitter&#8217;s point of view, at least in theory, this will result in less requests so their servers will be hammered less and in turn could result in a faster, more reliable service. From the user point of view it gives you real time Tweets using less traffic. Its win-win.</p>
<h3>What are user streams?</h3>
<p>When they had their first conference earlier in the year (Chirp), they talked about something called <em>user streams</em>. Are they a stream of a single user? No, user streams are what all desktop clients will eventually move to. They&#8217;re a stream of the logged in users friends tweets, mentions and direct messages as well as what I presume will be called &quot;stream events&quot; which include interactions between two people and optionally a Tweet.</p>
<p>You&#8217;ll notice the Streaming API is <strong><em>read</em></strong>&#160; only, so the REST API will be hanging around for writing (Tweeting). Infact, REST API will be hanging around so that you can do the initial &quot;fill up&quot; of the client, since the stream only gives you Tweets since you <em>connected</em> to the service.</p>
<p>Sadly, it is in limited beta at the moment, so while we&#8217;ve now got the code to do it in MahTweets, we can&#8217;t freely give it out to everybody yet.</p>
<p>&#160;</p>
<p><strong>Stream Events     <br /></strong>A stream event has a target, a source, a target object and a name for the event. So far I&#8217;ve only been able to observe the target object being a Tweet.</p>
<table border="0" cellspacing="0" cellpadding="2" width="549">
<tbody>
<tr>
<td valign="top" width="200">Target</td>
<td valign="top" width="347">User</td>
</tr>
<tr>
<td valign="top" width="200">Source</td>
<td valign="top" width="347">User</td>
</tr>
<tr>
<td valign="top" width="200">Target Object</td>
<td valign="top" width="347">Tweet (Optional)</td>
</tr>
<tr>
<td valign="top" width="200">Event</td>
<td valign="top" width="347">Favourite, Unfavourite, Follow, List_Add_Member, List_Remove_Member</td>
</tr>
</tbody>
</table>
<p>&#160;</p>
<p>This will lead to interesting things where you can see people following you in your client, perhaps as a notification (depending on client, etc). </p>
<p>&#160;</p>
<p>This is the <strong><em>real time web</em></strong>.</p>
<img src="http://feeds.feedburner.com/~r/TheLeagueOfPaul/~4/6YE2EfiAk4U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.theleagueofpaul.com/blog/2010/08/03/twitter-user-streams/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.theleagueofpaul.com/blog/2010/08/03/twitter-user-streams/</feedburner:origLink></item>
		<item>
		<title>Building Android APK’s with TeamCity</title>
		<link>http://feedproxy.google.com/~r/TheLeagueOfPaul/~3/UzNfCW10GrQ/</link>
		<comments>http://www.theleagueofpaul.com/blog/2010/07/24/building-android-apks-with-teamcity/#comments</comments>
		<pubDate>Sat, 24 Jul 2010 10:50:19 +0000</pubDate>
		<dc:creator>Paul</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[ant]]></category>
		<category><![CDATA[CI]]></category>
		<category><![CDATA[TeamCity]]></category>

		<guid isPermaLink="false">http://www.theleagueofpaul.com/blog/2010/07/24/building-android-apks-with-teamcity/</guid>
		<description><![CDATA[I&#8217;m slowly getting my various Android projects up to bitbucket, codeplex or another open/public DVCS and I&#8217;m slowly making sure that all of them can have auto-magic continuous integration. As my Windows Home Server is running TeamCity for MahTweets, its natural I want to keep it all contained in that. Originally I was trying to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m slowly getting my various Android projects up to bitbucket, codeplex or another open/public DVCS and I&#8217;m slowly making sure that all of them can have auto-magic continuous integration. As my Windows Home Server is running TeamCity for MahTweets, its natural I want to keep it all contained in that.</p>
<p>Originally I was trying to use the <em>Ipr</em> build runner, as I&#8217;m currently using IntelliJ IDEA, which is picked up by TeamCity rather well except it only generates a bunch of .classes (so it <em>is </em>compiling) but none of the dex/APK&#8217;s required for Android. </p>
<p><strong>The only solution I could find is to use Ant!</strong></p>
<h3>Generating the Build.Xml</h3>
<p>When I created projects in NetBeans, Eclipse or IntelliJ, none of them created the Build.xml file for your project. Luckily the Android SDK does.</p>
<p>You&#8217;ll find &quot;android&quot; under the tools subfolder in the SDK. From a command line:</p>
<blockquote><p>android create project –n <strong><em>&lt;ProjectName&gt; –</em></strong>t <strong><em>&lt;Target&gt;</em></strong> –p <em><strong>&lt;PathOnDesk&gt;</strong></em> –k <em><strong>&lt;Package&gt;</strong></em> –a <em><strong>&lt;Activity&gt;</strong></em></p>
</blockquote>
<p>All values are required. As I&#8217;d already created my project, I stuck in some dummy values and just grabbed the build.xml out of that folder, and placed it into my project folder. I used:</p>
<blockquote><p>android create project –n OhHai –t 1 –p D:\OhHai\ –k MahApps.OhHai –a OhHaiActivity</p>
</blockquote>
<p><strong>Make sure you commit the build.xml to your VCS!</strong></p>
<h3>BuildAgents</h3>
<p>Your BuildAgents are going to have to have a few extra requirements – primarily the <a href="http://developer.android.com/sdk/index.html">Android SDK</a> as well as the SDK for the particular version you are building against (run the SDKSetup inside the SDK download).</p>
<p>Once you&#8217;ve done that, you need to add a property to your BuildAgent to point to the location of the SDK you&#8217;ve just downloaded. Edit your BuildAgent configuration (by default on Windows, its C:\BuildAgent\conf\buildAgent.properties) by adding</p>
<blockquote><p>android.platform.base=<strong><em>pathToSDK</em></strong></p>
</blockquote>
<p>To the end of the file. <strong><em>This will disconnect and then reconnect your BuildAgent from your BuildServer. </em></strong>For me, it was</p>
<blockquote><p>android.platform.base=D\:\\SDKs\\android-sdk-windows</p>
</blockquote>
<p>You&#8217;ll notice this <em>isn&#8217;t</em> the path to the individual SDKs, and that&#8217;s because the ant tools build.xml calls are under <em>&lt;SDKRoot&gt;/tools/lib</em></p>
<h3>New Configuration</h3>
<p>Most of the values can be configured as normal, ie, give it a name, select your VCS, trigger, dependencies etc There are only a few extra values you&#8217;ll need to throw in</p>
<ol>
<li><strong>General Settings        <br /></strong>Artifact path: /bin/<strong><em>YourProjectName</em></strong>-debug.apk       <br /><strong></strong></li>
<li><strong>Runner</strong>
<ol>
<li>Select Ant as the <em><strong>build runner</strong></em> </li>
<li>put build.xml as the <strong><em>path</em></strong> to your build file (unless you&#8217;ve changed the name of it) </li>
<li>put &#8216;debug&#8217; as your <em><strong>targets</strong></em> (unless you want another build target) </li>
<li>Add an <strong>Additional Ant command line parameters, </strong>put in <em>-Dsdk.dir=&quot;%android.platform.base%&quot;            <br /></em>Ant properties are passed in via the command line as –D<em>paramName</em>=<em>ParamValue.</em> </li>
</ol>
</li>
</ol>
<p>Personally, I&#8217;ve added an additional Configuration Parameter Requirement, of android.platform.base to make sure only the BuildAgents with it configured attempt to build it.</p>
<p>Voila, build the project (and providing it doesn&#8217;t have compile issues), your APK should be the only file in your artifacts!</p>
<img src="http://feeds.feedburner.com/~r/TheLeagueOfPaul/~4/UzNfCW10GrQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.theleagueofpaul.com/blog/2010/07/24/building-android-apks-with-teamcity/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.theleagueofpaul.com/blog/2010/07/24/building-android-apks-with-teamcity/</feedburner:origLink></item>
		<item>
		<title>WP7 v Android: Dev ‘fluff’ stuff</title>
		<link>http://feedproxy.google.com/~r/TheLeagueOfPaul/~3/nFMWkJo6fpg/</link>
		<comments>http://www.theleagueofpaul.com/blog/2010/07/23/wp7-v-android-dev-fluff-stuff/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 06:42:05 +0000</pubDate>
		<dc:creator>Paul</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.theleagueofpaul.com/blog/2010/07/23/wp7-v-android-dev-fluff-stuff/</guid>
		<description><![CDATA[While I&#8217;ve outlined some of the programmatic differences between WP7 and Android, there is often a lot more to it than that – how easy is it to get the environment up and running? How easy is it to learn? Getting the SDK/Tools up and going WP7&#8242;s SDK can be found through developer.windowsphone.com portal (download [...]]]></description>
			<content:encoded><![CDATA[<p>While I&#8217;ve outlined some of the programmatic differences between WP7 and Android, there is often a lot more to it than that – how easy is it to get the environment up and running? How easy is it to learn?</p>
<h3>Getting the SDK/Tools up and going</h3>
<p>WP7&#8242;s SDK can be found through <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c8496c2a-54d9-4b11-9491-a1bfaf32f2e3&amp;displaylang=en">developer.windowsphone.com</a> portal (download is on the standard Microsoft downloads, but developer portal is the easiest way to grab it), you grab the 69kb web bootstrapper, which then downloads <em>up to</em> 339.8MB, installs the various tools and you&#8217;re right to go – from Visual Studio or Blend, you can go File –&gt; New Project –&gt; Select Windows Phone.</p>
<p>Android&#8217;s SDK is found on the <a href="http://developer.android.com/sdk/index.html">developer.android.com</a> portal, grab the appropriate version for your operation system, make sure Java 5 or 6 is installed, then once you&#8217;ve unzipped the SDK, you&#8217;ll need to run SDK Setup, which lets you choose and download which version of the SDK you&#8217;d like. Android is relatively fragmented, so you need to download the SDK for the lowest version of the API you&#8217;d like to target – that is, if you want to run on Android 1.6 and above, download 1.6 (version 4 of the API) and then you can target that/make virtual machine with 1.6 on it.</p>
<p>By default, the SDK Setup tool will query <strong><em><a href="https://dl-ssl.google.com/android/repository/repository.xml">https</a></em>://dl-ssl.google.com/android/repository/repository.xml</strong> for the latest information, but that has <strong><em>never</em> </strong>worked for me on a variety of machines. You&#8217;ll need to go into the Settings for SDK Setup and tick <em>&#8216;force https://… sources to be fetched using </em><a href="http://&hellip;'"><em>http://…&#8217;</em></a></p>
<p>Once you&#8217;ve got the SDK up and running, you may as well create a Virtual Device, unless you plan to do all your debugging on a device. </p>
<p>Finally, you&#8217;ll need to setup your IDE of choice – <a href="http://developer.android.com/sdk/eclipse-adt.html">Eclipse has a plugin from Google</a> with its own set of hopes to jump through, IntelliJ IDEA Ultimate ships with Android support, and NetBeans has an unofficial/unsupported plugin. And finally, now you can start a new Android project.</p>
<p><strong>Winner: WP7 – set and forget, done. Android you have to earn it.</strong></p>
<h3>Included SDK/Tools</h3>
<p>I should stress this is about the <strong><em>free</em></strong> SDK/Tools included, not any third party purchased tools.</p>
<p>WP7 includes</p>
<ul>
<li>Visual Studio 2010 Express for Windows Phone </li>
<li>Expression Blend 4 Express for Windows Phone </li>
<li>XNA </li>
<li>WP7 Emulator </li>
</ul>
<p>You cannot, however, select what components you want although thankfully its smart enough to figure out that if you&#8217;ve got VS2010 Standard or above to not install another copy of VS.</p>
<p>Android includes</p>
<ul>
<li>SDK Tools
<ul>
<li>Dalvik Debug Monitor </li>
<li>Draw 9 Patch </li>
<li>Android Emulator </li>
<li>Android Emulator manager which lets you create different VM configurations (storage/screen res/etc) </li>
<li>SDK version downloader/manager (download more versions </li>
</ul>
</li>
<li>Eclipse Plugin </li>
</ul>
<p>While at first glance you would be forgiven for thinking WP7 is superior as it includes a full IDE and a UI designer, there are a few caveats. The Android Dalvik Debug monitor can attach to either a VM/Emulator <em>or</em> a real device – meaning you get full file access/exploration, full debugger output, device querying, radio querying, ability to take screenshots <em>from</em> the device and more. While these tools don&#8217;t trump Visual Studio in most, having no way to query a physical (or emulated) device for WP7 or to take a screenshot is going to be very frustrating.</p>
<p>Not this is based on Windows <em>Mobile/CE </em>experience rather than WP7 experience – why? I have a Windows Mobile device, but I do not/cannot get a WP7 device just yet, unless a <a href="http://www.pcworld.com/article/201660/microsoft_giving_away_windows_phone_7_to_employees.html">Microsoftie wants to donate one of the 90,000 or so Microsoft are giving away to employees</a>.</p>
<p><strong>Winner: Not clear (leans towards WP7)</strong></p>
<h3>Emulator/Virtual Machine</h3>
<p><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" class="wlDisabledImage" title="image" border="0" alt="image" src="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/07/image6.png" width="242" height="387" /></p>
<p>Hands down, WP7 emulator is faster. I timed my first WP7 app from cold boot to being in my application…. 7.5 <em>seconds</em>. That&#8217;s insanely fast. It is, however, showing it&#8217;s beta-ness. I&#8217;ve managed to crash it – which just meant it closed, no restarting, it doesn&#8217;t respond to keyboard input &#8211; which means you have to use the onscreen keyboard using your mouse.</p>
<p>There doesn&#8217;t <em>seem</em> to be a way to start up the WP7 emulator without using Visual Studio or Blend, but I may just be missing something (why would you want to do this? Well, you might want to test the horrible browser on WP7 to make sure it works with your site). This <em>is</em> a downside but it is fairly easy to work around considering how fast VS2010 and the emulator boot.</p>
<p><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" class="wlDisabledImage" title="image" border="0" alt="image" src="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/07/image7.png" width="662" height="612" /></p>
<p>The Android VM is <em>sloooow.</em> Even on my quad core system, it 32 seconds for the OS to boot, let alone deploy and start up my app. And it&#8217;s relatively buggy too – icon&#8217;s are supposed to scale with the resolution of the VM but more often than not on my WVGA VM it doesn&#8217;t scale leaving the UI stretched or overly spaced.     <br />On the plus side, crashing the Android VM results in the virtual device rebooting itself inside the VM instead of just closing, it also responds to full (physical) keyboard input, and has a wider variety of installed apps to interact/test with.</p>
<p><strong>Winner: Not clear (leans towards Android, seriously, lack of keyboard input on WP7 bites)</strong></p>
<h3>Documentation</h3>
<p>&quot;Back in the day&quot; JavaDocs were all the rage, but that was a long time ago. Android&#8217;s documentation is barely more than JavaDocs for Java and Android API&#8217;s available. While there are <em>some</em> examples, they&#8217;re not entirely useful or beyond basic &quot;Hello World&quot; given the complexity that Android has.</p>
<blockquote><p>Google has Android Docs?!?!?!?!&#160; I thought those were templates for future use </p>
<p>Ive been working with the SDK since it has been out and the one thing i have learned is reading those docs is about as useful as trying to light a fire with a squirt gun.&#160; Its easier to go onto the github and rip apart their source to see the truth</p>
</blockquote>
<p>Those are two tweets in response to when I said the Android docs weren&#8217;t that good.</p>
<p>On the flip side, MSDN has come a long way in terms of visual and cross browser appeal in the last few years. In general, the MSDN docs are detailed enough and <em>generally </em>contain a sample in C#/VB/XAML.</p>
<p><strong>Winner: WP7, and by a big margin. MSDN rocks my socks.</strong></p>
<p> <br />
<h3>Winner?</h3>
<p>Again, there are no winners here – both have their positive and negative elements. I&#8217;d compare debugging but that&#8217;s a little unfair until I&#8217;ve got a WP7 device to compare against.   <br />WP7 is easiest to get going, and has better documents, but some of the tools are lacking and the VM is a little frustrating.    <br />Android is daunting to get going and you&#8217;re better off reading other people&#8217;s code/Android&#8217;s source code than reading the Android docs</p>
<p><font size="1">(I&#8217;m happy to have devices donated to compare…Microsoft, same goes for you HP/Palm on WebOS, or Apple if they want to send me a Mac Mini+iPhone)</font></p>
<img src="http://feeds.feedburner.com/~r/TheLeagueOfPaul/~4/nFMWkJo6fpg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.theleagueofpaul.com/blog/2010/07/23/wp7-v-android-dev-fluff-stuff/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://www.theleagueofpaul.com/blog/2010/07/23/wp7-v-android-dev-fluff-stuff/</feedburner:origLink></item>
		<item>
		<title>MahTweets has moved to Codeplex!</title>
		<link>http://feedproxy.google.com/~r/TheLeagueOfPaul/~3/UW0f9v3LtNI/</link>
		<comments>http://www.theleagueofpaul.com/blog/2010/07/22/mahtweets-has-moved-to-codeplex/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 02:16:14 +0000</pubDate>
		<dc:creator>Paul</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Hg]]></category>
		<category><![CDATA[MahTweets]]></category>
		<category><![CDATA[SVN]]></category>

		<guid isPermaLink="false">http://www.theleagueofpaul.com/blog/2010/07/22/mahtweets-has-moved-to-codeplex/</guid>
		<description><![CDATA[At the start of the year, Codeplex announced support for Mercurial (Hg), possibly the best tooled DVCS for Windows. We&#8217;ve now come full circle – originally MahTweets code was on Codeplex via TFS/SVNBridge, but after one too many stuff ups with SVNBridge refusing to let one or more of the team commit, we switched to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/07/logo.png"><img class="wlDisabledImage" style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="logo" src="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/07/logo_thumb.png" border="0" alt="logo" width="419" height="68" /></a></p>
<p>At the start of the year, <a href="http://blogs.msdn.com/b/codeplex/archive/2010/01/22/codeplex-now-supporting-native-mercurial.aspx">Codeplex announced support for Mercurial (Hg)</a>, possibly the best tooled DVCS for Windows. We&#8217;ve now come full circle – originally MahTweets code was on Codeplex via TFS/SVNBridge, but after one too many stuff ups with SVNBridge refusing to let one or more of the team commit, we switched to self hosted SVN.</p>
<p><strong><a href="http://mahtweets.codeplex.com/">MahTweets has now returned to Codeplex &#8217;cause DVCS is cool.</a></strong></p>
<p>From a tooling point of view, all we had to do for Fisheye was upgrade 2.3 to get support for Hg. Changing TeamCity over was pretty easy too, like Fisheye we just had to point it to the Hg binary location and it was good to go. JIRA hooks into Fisheye, so it doesn&#8217;t need explicit Hg support. From a dev client point of view, we&#8217;ve changed from TortoiseSVN to <a href="http://bitbucket.org/tortoisehg/stable/wiki/Home">TortoiseHg</a>, and VisualSVN to <a href="http://visualhg.codeplex.com/">VisualHg</a>.</p>
<p>However, the solution, project and MSBuild file that the build server uses more complex. <a href="http://www.theleagueofpaul.com/blog/2010/06/24/auto-clickonce-deploys-with-teamcity-msbuild/">All of our automagic builds append the revision number</a> from the source control. We were achieving this by using the <a href="http://msbuildtasks.tigris.org/">MSBuild Community Tasks</a> which includes tasks for Subversion in all our CSProjs&#8217; (so every assembly has the correct version) and in our msbuild file.</p>
<pre class="brush: xml;">&lt;SvnVersion LocalPath="$(ProjectDir)" ToolPath="$(MSBuildCommunityTasksPath)\Subversion\"&gt;
  &lt;Output TaskParameter="Revision" PropertyName="Revision" /&gt;
&lt;/SvnVersion&gt;</pre>
<p>The obvious issue with this is that no projects could build because SvnVersion had a bit of a panic attack being unable to find any Subversion bindings. While there is no Mercurial support in the MSBuild Community Tasks, there is (thankfully) a separate library available – <a href="http://msbuildhg.codeplex.com/">MSBuild Mercurial Tasks</a>.</p>
<pre class="brush: xml;">&lt;HgVersion  LocalPath="$(ProjectDir)" &gt;
  &lt;Output TaskParameter="Revision" PropertyName="Revision" /&gt;
&lt;/HgVersion&gt;</pre>
<p>Very similar syntax, with the only difference being no ToolPath. The SvnVersion task uses ToolPath to point to your svn.exe, whereas HgVersion just uses the &#8220;hg&#8221; command so a command line client must be installed/registered properly with Windows (TortoiseHg installs this, or they maintain a command line client without the GUI)</p>
<img src="http://feeds.feedburner.com/~r/TheLeagueOfPaul/~4/UW0f9v3LtNI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.theleagueofpaul.com/blog/2010/07/22/mahtweets-has-moved-to-codeplex/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.theleagueofpaul.com/blog/2010/07/22/mahtweets-has-moved-to-codeplex/</feedburner:origLink></item>
		<item>
		<title>WinMoPho vs Android from a dev point of view</title>
		<link>http://feedproxy.google.com/~r/TheLeagueOfPaul/~3/-IVxQeRJOrU/</link>
		<comments>http://www.theleagueofpaul.com/blog/2010/07/21/winmopho-vs-android-from-a-dev-point-of-view/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 10:00:33 +0000</pubDate>
		<dc:creator>Paul</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Windows Phone]]></category>

		<guid isPermaLink="false">http://www.theleagueofpaul.com/blog/?p=836</guid>
		<description><![CDATA[I&#8217;m a PC and I&#8217;m a big fan of WPF, so it could be assumed that I like Silverlight and therefore WinMoPhone 7. Well, the truth is I love WPF but think that Silverlight is more like WPF vPainful, and I use Android which has some fantastic hardware and is available now unlike the mythical [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a PC and I&#8217;m a big fan of WPF, so it could be assumed that I like Silverlight and therefore Win<span style="text-decoration: line-through;">Mo</span>Phone 7. Well, the truth is I love WPF but think that Silverlight is more like WPF vPainful, and I use Android which has some fantastic hardware and is available <strong><em>now </em></strong>unlike the mythical Windows Mobile 7.</p>
<p>It wasn&#8217;t until the recent spat of previews coming out from places like <a href="http://www.engadget.com/2010/07/19/windows-phone-7-in-depth-preview/">Engadget</a> that I was even vaguely interested in WinMoPho – seeing the simplified design of <em>Metro </em>on AMOLED screens looks fantastic. Some would say it lacks depth and is a bland design. In many ways I agree but as Microsoft have rather strict requirements for WinMoPho devices including OLED as a minimum (no LCD!) I&#8217;m beginning to see the beauty in it when compared to the reasonably complex (visually) Android <em>particularly</em> when out in the sun.</p>
<p>From a dev point of view, there are strengths and shortcomings for both systems, and I&#8217;m not entirely sure who is the clear winner, if there can be one.</p>
<h3>IDEs and tools</h3>
<p><strong>Dev tools<br />
</strong>Okay, so an IDE is never required, but I like to be productive and don&#8217;t memorise every namespace. Android is Java based, so naturally the top choice for IDEs are all Java based as well – the three I&#8217;ve tried are <a href="http://www.eclipse.org/">Eclipse</a>, <a href="http://netbeans.org/">Netbeans </a>and <a href="http://www.jetbrains.com/idea/">IntelliJ</a>. Personally I think IntelliJ is the best, although it&#8217;s not free if you want to do Android development.  These run on *Nix, OSX or Windows, giving you greater flexibility in your development. Eclipse is as close to the &#8216;official&#8217; IDE as it gets – Google provide the plugin for it – but there is no IDE directly from Google. This is good in that you can use whatever you are comfortable in, but bad because the general tooling is pretty below par.</p>
<p>WinMoPho has <a href="http://weblogs.asp.net/scottgu/archive/2010/07/12/windows-phone-7-developer-tools-beta-released.aspx">Visual Studio 2010 Express for Windows Phone</a>. It&#8217;s a mouthful, but <em>personally</em> I think its justified as its just that much better than the offerings for Android. VS10 Express is free (or you can use the professional versions of Visual Studio), but only runs on Windows which may hinder some. While it is an incredibly complex piece of software, it is also incredibly powerful.</p>
<p>The debugging is just.. well.. <em>better</em> on VS. And IntelliSense <em>works</em>. Eclipse&#8217;s auto-complete names all the arguments arg0, arg1 .. argN, I could never get NetBean&#8217;s debugging to actually debug and IntelliJ is case sensitive – it won&#8217;t pickup <em>Hello </em>for<em> helloWorld.</em></p>
<p><strong>Design/UI tools<br />
</strong>The WinMoPho Developer tools &#8220;ship&#8221; with an Express version of Expression Blend (Express Expression Blend… another nice name) which will only let you do WinMoPho development. This is free, and will remain free. Eventually it&#8217;ll install into regular (non-free) versions of Blend. Blend is, without a doubt, awesome.  I won&#8217;t bore you with lots of details, but it is a designery app for <em>designing</em> your applications UI. How designery? Blend 4 can directly import Photoshop (PSD) or Illustrator (AI) files – AI goes straight to XAML/Vectors, and PSD will <em>try</em> to map text layers up to Textboxes, rectangles, etc – your layer structure keeps intact!</p>
<p><a href="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/07/image2.png"><img class="wlDisabledImage" style="display: block; float: none; margin-left: auto; margin-right: auto; border: 0px;" title="image" src="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/07/image_thumb1.png" border="0" alt="image" width="701" height="423" /></a></p>
<p>In contrast, Android has no UI editing program, but there is an editor for Eclipse. Sadly, the editor is absolute balls – you can&#8217;t drag controls around, you can&#8217;t resize, etc. The closest to something useful is the unofficial <a href="http://www.droiddraw.org/">DroidDraw</a> java applet. I think DroidDraw is mostly limited by the poor layout system that Android has.</p>
<p><a href="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/07/image3.png"><img class="wlDisabledImage" style="display: block; float: none; margin-left: auto; margin-right: auto; border: 0px;" title="image" src="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/07/image_thumb2.png" border="0" alt="image" width="705" height="388" /></a></p>
<h3>Multitasking</h3>
<p>Android has it, WinMoPho doesn&#8217;t. I think it is rather stupid of Microsoft given the current mobile climate, but whatever. Android apps have multitasking built into them, even the default Google applications use the same API&#8217;s – no hidden secrets or limitations that other OS&#8217;s have/have had. There are just a few caveats to be aware of</p>
<ul>
<li>your application could be terminated at any time if its not in the foreground, if the device start running low on memory</li>
<li>every time the user switches back to your application (even after it is killed), the view is recreated as it was in the <strong><em>onCreate</em></strong> method of your <em>Activity</em> <em>unless</em> you override <strong><em>onResume</em></strong> as well.</li>
<li>Your application should always go back to the previous Activity it was on when they left – Android handles this automatically.</li>
<li>You can explicitly run in the background so that Android doesn&#8217;t kill off your application if you use <em>Services</em> or <em>BroadcastRecievers</em> – think music playing app, IM, etc.</li>
</ul>
<h3>Sharing, Intents and Navigation</h3>
<p>One thing thing that WinMoPho completely lacks is one of the greatest strong points of Android – the ability to share data between applications, but without having to specifically target an application. For example, if you take a photo then press <em>share</em>, any application that has registered the correct intent for sharing will appear in a list – email, a variety of Twitter clients, Flickr, Facebook, whatever, so long as its registered, it can handle it.</p>
<p>In Android, you register an Intent with the OS to replace pretty much anything that matches that – such as the Homescreen. That&#8217;s right, things as basic/essential as the <strong><em>homescreen</em></strong> can be replaced – how awesome is that?</p>
<pre class="brush: xml;">&lt;activity android:name=".AlbumListActivity"
          android:theme="@android:style/Theme.NoTitleBar"
          android:screenOrientation="portrait"
          android:label="@string/app_name"&gt;
    &lt;intent-filter&gt;
        &lt;action android:name="android.intent.action.MAIN" /&gt;
        &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
    &lt;/intent-filter&gt;
&lt;/activity&gt;</pre>
<p>In MahTunes I&#8217;ve registered the <em>AlbumListActivity</em> to hook up to the &#8220;Launcher&#8221; activity – this just means it&#8217;ll appear in the &#8220;app tray&#8221;, and that it should launch this activity first. Intents are registered via the AndroidManifest.xml that every Android app needs.</p>
<p><strong>Navigation</strong></p>
<p>Navigation in Android is through Intents whether it is between applications or inside a single application.</p>
<pre class="brush: java;">Intent playbackIntent = new Intent(getApplicationContext(), PlaybackActivity.class);
Track t = (Track)tadapter.getItem(arg2);
playbackIntent.putExtra("trackId", t.ID);
startActivityForResult(playbackIntent, 0);</pre>
<p>This example is also from MahTunes, inside the track selection dialog, it creates a new Intent to target the PlaybackActivity class and loads it up with some primitive data – you can only pass along primitive types, no objects.</p>
<p>If you&#8217;re querying another application, the Intent constructor parameters would look like</p>
<pre class="brush: java;">Intent intent = new Intent("com.google.zxing.client.android.SCAN");</pre>
<p>At the other end, inside PlaybackActivity&#8217;s onCreate, it can query the intent &#8220;bundle&#8221;</p>
<pre class="brush: java;">long trackId = getIntent().getLongExtra("trackId", -1);</pre>
<p>There is one downside – moving from screen to screen inside your own application in Android feels more like a collection of &#8220;activities&#8221; rather than a proper application, as you pass data around from one to another. There is the (optional) Application class to extend which acts as a global wrapper around them.</p>
<p>WinMoPho navigation around an application isn&#8217;t much different. It treats everything as a &#8220;page&#8221;, so you use <em>Uris </em>to navigate around. This has the same problem of not being able to send complex datatypes to the new page all that easily. That being said, the &#8220;application&#8221; class isn&#8217;t optional, so you&#8217;ll always have that container.</p>
<pre class="brush: csharp;">NavigationService.Navigate(new Uri("Details.xaml", UriKind.Relative));</pre>
<h3>Data binding</h3>
<p>Android doesn&#8217;t have data binding, it&#8217;s as simple as that. You can set X to Y, but you&#8217;re essentially just setting X to be an instance of Y – when Y updates, X doesn&#8217;t. <strong><em>Yes this is framework magic</em></strong>. Data binding and data templating are the two greatest things about WPF and Silverlight.</p>
<p>And this leads into the next point, Lists. Lists are hard, okay? Well, okay, I&#8217;m lying, lists aren&#8217;t hard at all on most UI frameworks but this is one of the greatest downfalls of Android programming. Unless you want a very basic list of just a string-per-line, Android requires you to create a custom ListAdapter <a href="http://www.theleagueofpaul.com/blog/2010/03/11/android-dev-custom-listadapter/">which I&#8217;ve written about before</a>. There are a whole stack of performance issues and enhancements you need to do to each and every one of your adapters – it&#8217;s just a messy and repetitive process.</p>
<p>Silverlight? myListBox.ItemSource = MyList; Done. That won&#8217;t automagically setup your UI to be bound the way you want it (in fact it&#8217;ll just give you a .ToString() of each object per line), but you don&#8217;t have to write any custom code to adapt a list to your ListBox.</p>
<p><strong>List example</strong></p>
<p><img class="wlDisabledImage" style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/07/image4.png" border="0" alt="image" width="356" height="213" /></p>
<p>This is a screenshot taken from the Android Dalvik Debug Monitor (part of the Android SDK) of MahTunes running on my Milestone. You&#8217;ll notice there are issues with text-wrapping and originally there were issues with some items stretching further than others. Ignoring the rounded corners on both the background item and on the album art and ignoring the custom font, how do you do this in Android and in WinMoPho?</p>
<p><strong>Android</strong></p>
<p><em>AlbumListActivity.java (snippet from where the Activity sets the current view)</em></p>
<pre class="brush: java;">AlbumAdapter albumadapter = new AlbumAdapter(this, Albums);
ListView lvMyListView = (ListView)findViewById(R.id.ListViewAlbums);
lvMyListView.setAdapter(albumadapter );</pre>
<p><em>AlbumAdapter.java</em></p>
<pre class="brush: java;">package mahapps.MahTunes;
import android.content.Context;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import java.util.*;

public class AlbumAdapter extends BaseAdapter
{
    private List&lt;Album&gt; elements;
    private Context c;
    public AlbumAdapter(Context c, List&lt;Album&gt; Albums) {
        this.elements = Albums;
        this.c = c;
    }
    public int getCount() {
        return elements.size();
    }
    public Object getItem(int position) {
        return elements.get(position);
    }
    public long getItemId(int id) {
        return id;
    }
    public void Remove(int id)
    {
        notifyDataSetChanged();
    }
    public View getView(int position, View convertView, ViewGroup parent)
    {
        LinearLayout rowLayout;
        Album t = elements.get(position);

        if (convertView == null)
        {
           rowLayout = (LinearLayout)LayoutInflater.from(c).inflate(R.layout.albumitemview, parent, false);
           TextView tv = (TextView)rowLayout.findViewById(R.id.txtName);
           tv.setText(t.getName());

           tv = (TextView)rowLayout.findViewById(R.id.txtArtist);
           tv.setText(t.getArtist());

           ImageView iv = (ImageView)rowLayout.findViewById(R.id.imgAlbumArt);
           iv.setImageBitmap(t.getAlbumArt());
        } else {
            rowLayout = (LinearLayout)convertView;

            TextView tv = (TextView)rowLayout.findViewById(R.id.txtName);
            tv.setText(t.getName());

            tv = (TextView)rowLayout.findViewById(R.id.txtArtist);
            tv.setText(t.getArtist());

            ImageView iv = (ImageView)rowLayout.findViewById(R.id.imgAlbumArt);
            iv.setImageBitmap(t.getAlbumArt());
        }
        return rowLayout;
    }
}</pre>
<p><em>AlbumListView.xml</em></p>
<pre class="brush: java;">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
       android:layout_height="fill_parent"
    android:orientation="vertical"&gt;
    &lt;ListView android:id="@+id/ListViewAlbums" android:layout_width="fill_parent" android:layout_height="wrap_content" /&gt;
&lt;/LinearLayout&gt;</pre>
<p><em>AlbumItemView.xml </em></p>
<pre class="brush: xml;">&lt;LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal"
    android:gravity="fill_horizontal"&gt;

    &lt;ImageView android:id="@+id/imgAlbumArt" /&gt;
    &lt;LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:orientation="vertical"&gt;

        &lt;TextView
            android:id="@+id/txtName"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:singleLine="false" /&gt;

        &lt;TextView
            android:id="@+id/txtArtist"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:singleLine="false" /&gt;
    &lt;/LinearLayout&gt;
&lt;/LinearLayout&gt;</pre>
<p><strong>WinMoPho</strong></p>
<p><em>C#/Codebehind (snippet where the list is bound to the list of Albums)</em></p>
<pre class="brush: csharp;">lstMyList.ItemsSource = myListOfAlbums;</pre>
<p><em>XAML/UI</em></p>
<pre class="brush: xml;">&lt;ListBox x:Name="lstMyList"&gt;
    &lt;ListBox.ItemTemplate&gt;
        &lt;DataTemplate&gt;
            &lt;StackPanel Orientation="Horizontal"&gt;
                &lt;Image/&gt;
                &lt;StackPanel&gt;
                    &lt;TextBlock TextWrapping="Wrap" Text="TextBlock"/&gt;
                    &lt;TextBlock TextWrapping="Wrap" Text="TextBlock"/&gt;
                &lt;/StackPanel&gt;
            &lt;/StackPanel&gt;
        &lt;/DataTemplate&gt;
    &lt;/ListBox.ItemTemplate&gt;
&lt;/ListBox&gt;</pre>
<p>There are better ways to write the XAML than this, but this is the easiest way to demonstrate it.</p>
<p>Android has a tonne more code, a tonne more markup (and trust me, its needed), and it still doesn&#8217;t function 100% of the way it should <em>and </em>you&#8217;d have to rewrite a lot of that code if you wanted to do another list of tracks instead of albums. On Android if you add to the list, you have to make sure you notify the adapter so it can update whereas its automatic on WinMoPho.</p>
<h3>Images</h3>
<p>If you&#8217;re getting images on Android from anywhere but local storage, you&#8217;re going to have some fun times there – by that I mean images from the internet.</p>
<p><strong>Android</strong></p>
<p><strong></strong>Part of the issue is when do you download the image? In this example I was setting it in the custom ListAdapter, but this of course creates a very slow loading of the list – you need to spin this off to a different thread.</p>
<pre class="brush: java;">ImageView imgAvatar = (ImageView) rowLayout.findViewById(R.id.imgAvatar);
URL aURL = null;
URLConnection con = null;

try {
    aURL = new URL(t.Avatar);
    con = aURL.openConnection();
    con.connect();
    InputStream is = null;
    is = con.getInputStream();
    BufferedInputStream bis = new BufferedInputStream(is);
    Bitmap bm = BitmapFactory.decodeStream(bis);
    imgAvatar.setImageBitmap(bm);
    is.close();
    bis.close();
} catch (MalformedURLException e) { }
catch (IOException e) { }
catch (IOException e) { }</pre>
<p><strong>Silverlight</strong></p>
<p>There are several ways to set images – you can set the Source on an Image in XAML to the Uri, you can databind the Image&#8217;s Source in XAML to a property on the object you&#8217;re binding (can be a BitmapSource, String or Uri) or you can set it in code like Android. However, most of the time the first two options are what you&#8217;ll do, and the framework automatically takes care of loading it asynchronously. It really is that simple &#8211; its hard to stress how easy it is compared to Android.</p>
<p>One clever thing Android does do around images, however, is the Nine-Patch image. A NinePatch is like the name suggests, an image that can be divided into 9 sections, where the &#8220;inner&#8221; (5 if you were looking at it from a numberpad) section can be stretched for content.  The editor for this is included in the Android SDK, although isn&#8217;t very friendly to use.</p>
<p><img class="wlDisabledImage" style="display: inline; border: 0px;" title="image" src="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/07/image5.png" border="0" alt="image" width="723" height="423" /></p>
<h3>Persistence and Storage</h3>
<p>WinMoPho will not give you direct access to the file system nor will it ship with (apparently its there, just not accessible) SQL CE. The only way you can store on the device is using <em>IsolatedStorage</em>, a concept brought over from the &#8220;desktop&#8221; version of Silverlight. That being said, <a href="http://blogs.msdn.com/b/priozersk/">Alex Yakhnin</a> has created a <a href="http://blogs.msdn.com/b/priozersk/archive/2010/04/14/creating-linq-data-provider-for-wp7-part-1.aspx">LINQ Data Provider for Isolated Storage</a> which works wonderfully by serialising objects to JSON, then storing in IsolatedStorage, which is incredibly easy to consume.</p>
<pre class="brush: csharp;">public static class Storage
{
    private static ObjectStore datastore = new ObjectStore("MahBlogMobile");
    public static ObjectContext Context = new ObjectContext("MahBlogMobile");
    public static void StoreAccounts(IEnumerable&lt;Account&gt; account)
    {
        datastore.Persist&lt;Account&gt;(account);
    }
}</pre>
<p>Android by contrasts lets you write to the file system and comes bundled with SQLite. While it (seems?) to lack ORM&#8217;s like LINQ, it&#8217;s flexible enough to let you decide how you want to do it.</p>
<pre class="brush: java;">public int InsertProduct(Product P)
{
    SQLiteDatabase db = mOpenHelper.getReadableDatabase();
    db.execSQL("INSERT INTO Products ('Barcode', 'Name') VALUES ('"+P.barcode+"','"+P.name+"');");

    int id = 0;
    Cursor c = db.rawQuery("SELECT ID FROM Products WHERE Barcode='"+P.barcode+"' AND Name='"+P.name+"'",  null);
    if (c.moveToFirst())
    {
        id = c.getInt(c.getColumnIndex("ID"));

    }
    db.close();

    return id;
}</pre>
<h3>Device Resolution/Size Handling</h3>
<p>WinMoPho will launch with WVGA (800&#215;480) support only with HVGA (480&#215;320) coming later on the track and only on phones (so no 10&#8243; tablets), while Android supports FWVGA, WVGA, HVGA, FWVGA, QVGA, FWQVGA, WQVGA and various phone screen sizes and formats as well as tablets and portable media players. As such, Android has a harder time supporting all those devices, but has some clever ways to support these.</p>
<p>When you create a new project in any of the Android-compatible IDE&#8217;s, you&#8217;ll have a /res folder with /drawable, /drawable-hdpi, /drawable-ldpi and /drawable-mdpi inside of it. The idea is that you put your special version of your images into each folder and Android will be smart enough to know when to use each resource – ie, for your icon.png, you make it 72&#215;72 for hdpi but mdpi is 48&#215;48. You <em><strong><span style="text-decoration: underline;">must</span></strong></em> declare in the manifest what screens you support, otherwise there is a good chance it&#8217;ll default to the wrong one.</p>
<p>While it&#8217;s great there is that level of support, the biggest issue is that the magic is based on density. According to Google, medium density is 320&#215;480 on 3&#8243; to 3.5&#8243; screen OR 480&#215;800/480&#215;854 on 4.8&#8243; to 5.8&#8243; screens. Does this mean that a 5&#8243; tablet is going to use a 48x48px icon instead of a 72x72px icon?</p>
<p>From a code point of view, getting the correct resource in said folders is performed in a similar magical way – <em>R.drawable.icon </em>refers to the correct density without having to figure that out yourself. That being said, you can do that</p>
<pre class="brush: java;">float scale = this.getResources().getDisplayMetrics().density;
Bitmap bdRounded = BitmapHelpers.getRoundedCornerBitmap(artwork, (int)(15 *scale), (int)(320 *scale), (int)(320 *scale));</pre>
<p>In this instance, <em>scale</em> would return 1.0 on a low density screen and 1.5 on a high density screen.</p>
<p>What will WinMoPho require? At this stage it&#8217;s unclear what Microsoft are planning, but because Silverlight is a <strong><em>vector</em></strong> based layout system, many applications may not require changes as vectors scale rather nicely.</p>
<h3>Winner?</h3>
<p>I don&#8217;t think there is a clear winner &#8211; for some people Java is going to be more natural but for others its going to grate against everything they know. I think I personally need to more Android dev before I chalk it up to &#8216;not for me&#8217;.</p>
<p>WP7 clearly has some great things going for it &#8211; the .NET stack goes from web, desktop, phone, Xbox360, and various mono implementations. Android on the other hand has the flexibility that no other mobile OS offers and a very passionate developer base, with a user base starting to challenge the almighty iPhone juggernaut.</p>
<img src="http://feeds.feedburner.com/~r/TheLeagueOfPaul/~4/-IVxQeRJOrU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.theleagueofpaul.com/blog/2010/07/21/winmopho-vs-android-from-a-dev-point-of-view/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.theleagueofpaul.com/blog/2010/07/21/winmopho-vs-android-from-a-dev-point-of-view/</feedburner:origLink></item>
		<item>
		<title>Review: Singularity (PC)</title>
		<link>http://feedproxy.google.com/~r/TheLeagueOfPaul/~3/BslRVBpdmK4/</link>
		<comments>http://www.theleagueofpaul.com/blog/2010/07/08/review-singularity-pc/#comments</comments>
		<pubDate>Thu, 08 Jul 2010 00:47:03 +0000</pubDate>
		<dc:creator>Paul</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Gaming]]></category>
		<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://www.theleagueofpaul.com/blog/2010/07/08/review-singularity-pc/</guid>
		<description><![CDATA[In Singularity, you play BJ Blazkowicz fighting the Nazi paranormal units, taking place in Isenstant. You gain super powers when you find the Thule medallion which lets you slow down time..wait wait wait wait – thats Wolfenstein, not Singularity, although you wouldn&#8217;t be blamed for confusing the two. Both games are from Raven Software (the [...]]]></description>
			<content:encoded><![CDATA[<p>In <em><a href="http://en.wikipedia.org/wiki/Singularity_%28video_game%29">Singularity</a></em>, you play BJ Blazkowicz fighting the Nazi paranormal units, taking place in Isenstant. You gain super powers when you find the Thule medallion which lets you slow down time..wait wait wait wait – thats <em><a href="http://en.wikipedia.org/wiki/Wolfenstein_%282009_video_game%29">Wolfenstein</a></em>, not <em>Singularity</em>, although you wouldn&#8217;t be blamed for confusing the two. Both games are from <em><a href="http://www.ravensoft.com/">Raven Software</a></em> (the studio who gave us wonders like <em>HeXen</em>, <em>Heretic</em>, <em>Soldier of Fortune</em> (1 &amp; 2), <em>Jedi Knight Outcast</em> and even <em>XMen Legends),</em> both feature historical weaponry/settings, both feature special powers, and both had a somewhat frustrating upgrade system to the devices that gave you the special powers. </p>
<p>In <em>Singularity, </em>you play Nate Renko who is thrown between modern day and 1955 on the elusive and fictional Russian island, Katorga-12. Kotorga-12 is the only known source of Element99, which in turn gives the scientists there the ability to manipulate time. The Time Manipulation Device (TMD) is the main draw card for <em>Singularity – </em>it acts as a gravity gun, shield and weapon. I will say this, while <em>Singularity</em> is better than <em>Wolfenstein</em>, neither are stand out games. While <em>Wolfenstein </em>just lacked punch and was overall too repetitive, <em>Singularity</em>&#8216;s main draw is the TMD – but in reality, that was its <em>only</em> draw, as the game overall feels like yet another generic shooter.</p>
<p>The game is short – only taking four or five hours to stomp through, the enemies are either mutated creatures which can teleport (but due to somewhat dumb AI never bother doing that to get the advantage on you) or Russian soldiers (either Cold War era or modern) who are happy enough to line up and die in an orderly fashion. The weapons the enemy have are no match for the arsenal you can get – such as a time manipulating sniper rifle, a rail gun, or a gun which slows time so much you can actually steer the bullet. While these sound fun at first, combined with the overpowered TMD, the game just becomes boring – a game isn&#8217;t fun if it doesn&#8217;t challenge you on some level. That isn&#8217;t to say there aren&#8217;t genuine moments of &quot;<em>zomg that was so cool</em>&quot; when you first get the weaponry, but those moments were spread so thin throughout the game.</p>
<p>Once interesting tidbit is that this <em>Raven</em> game <em>doesn&#8217;t</em> use any of <em>iD&#8217;s</em> <em>Tech</em> engines, but instead uses <em>Unreal Engine 3</em>. During the peak of the <em>id Tech 3</em> based games, Raven produced four hugely successful games, not to mention paved a lot of the way with a string of hits using the <em>id Tech 2</em> engine. Heck, <em>Raven</em> even created (the somewhat lacklustre) <em>Quake 4</em> – that&#8217;s saying something about how involved they&#8217;ve been with <em>iD</em> tech over the years. Now, this isn&#8217;t their first <em>Unreal Engine 3</em> based game (<em>X-Men Origins: Wolverine</em> was), but it still came as a bit of a surprise to me. Despite years of working with<em> iD Tech</em>, <em>Raven </em>are relatively new with UE, and it shows – it suffers a hilarious bug where textures just stop loading (or take 10-20mins to load). This <em>is</em> a feature of UE3, where textures stream in to create a smoother loading experience, rather than loading all at once and slowing down the system.</p>
<p><a href="http://ve3d.ign.com/images/fullsize/76682/PC/Singularity/Screenshots/July-26th-Texture-Streaming-Screenshot"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" class="wlDisabledImage" title="image" border="0" alt="image" src="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/07/image1.png" width="609" height="343" /></a></p>
<div style="text-align: center; font-size: 0.8em">(Image source: <a href="http://ve3d.ign.com/articles/news/55774/Singularity-PC-Plagued-By-Texture-Streaming-Problems-Fix-Found">IGN</a>)</div>
<p>As you can see from the above image the gun is fantastically detailed but the rest of the game looks terrible. More often than not, while playing Singularity, I was faced with this problem. Apparently there are now workarounds, and Raven are looking into it but it is somewhat of a big flaw.</p>
<p> <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="wlDisabledImage" title="review_card_singularity" border="0" alt="review_card_singularity" align="right" src="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/07/review_card_singularity.png" width="484" height="181" /></p>
<img src="http://feeds.feedburner.com/~r/TheLeagueOfPaul/~4/BslRVBpdmK4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.theleagueofpaul.com/blog/2010/07/08/review-singularity-pc/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.theleagueofpaul.com/blog/2010/07/08/review-singularity-pc/</feedburner:origLink></item>
		<item>
		<title>Review: Prince of Persia (2008, Xbox360)</title>
		<link>http://feedproxy.google.com/~r/TheLeagueOfPaul/~3/Eqs3DPmjk3Y/</link>
		<comments>http://www.theleagueofpaul.com/blog/2010/07/07/review-prince-of-persia-2008-xbox360/#comments</comments>
		<pubDate>Wed, 07 Jul 2010 02:29:28 +0000</pubDate>
		<dc:creator>Paul</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Gaming]]></category>
		<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://www.theleagueofpaul.com/blog/2010/07/07/review-prince-of-persia-2008-xbox360/</guid>
		<description><![CDATA[To distinguish this game from the previous Prince of Persias, Ubisoft decided to not give it a subtitle like the Sands series (Sands of Time, Warrior Within, Two Thrones, Forgotten Sands). The name also bares little resemblance to the game itself – the &#34;Prince&#34; isn&#8217;t actually a prince – it is hard not to dislike [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/07/image.png"><img style="border-bottom: 0px; border-left: 0px; margin: 0px 15px 15px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="image" border="0" alt="image" align="right" src="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/07/image_thumb.png" width="262" height="331" /></a></p>
<p>To distinguish this game from the previous Prince of Persias, Ubisoft decided to not give it a subtitle like the <em>Sands </em>series (<em>Sands of Time, Warrior Within, Two Thrones, Forgotten Sands). </em>The name also bares little resemblance to the game itself – the &quot;Prince&quot; isn&#8217;t actually a prince – it is hard not to dislike the game when it is setup to deceive you before you even begin! Ubisoft somewhat gave up after that and it is rather hard to list any distinguishing features that the game has. If I was pressed, the celshaded graphics are the only unique element in the series although not particularly unheard of these days. </p>
<p>Unlike the<em> Sands </em>series, <em>Prince of Persia </em>features a different protagonist, a different story, and fairly different gameplay. I think it is probably important to note the rating that this <em>Prince </em>gets – and I mean from classification boards – PG (Parental Guidance recommended) compared to previous games which generally got M (Mature Audiences). By targeting kids, most aspects of the game have been cut back to make it easier. </p>
<p>So how <em>is</em> the gameplay different and easier? Well, for a start there is no death – if you die, the other character will magically teleport and rescue you. Combat is also missing in action – or at least as good as gone, as the occasional combat comes down to Y, X, X, RT looping until the opponent is dead. Well, dead or decides to run off, as you seem to kill very few bad guys. And finally, a staple of the <em>Prince of Persia </em>series is missing (at least in the half of the game I&#8217;ve completed so far) – there are no traps. The game boils down to random/repetitive/unsatisfying combat, jumping with terrible lighting and camera angles so non-death is more often than not, collecting &#8216;light seeds&#8217; and not much else.</p>
<p>The story focuses on Elika the princess – your NPC companion &#8211; and Ahriman – the evil god of evilness. He&#8217;s been set loose, its your job to seal him back by making Elika heal the &#8216;fertile grounds&#8217;. As mentioned, whenever you are near death in combat or because you&#8217;re plummeting towards the ground, Elika will teleport and save you. Wait, hang on, the princess has magical powers that allow her to teleport (even when she&#8217;s caged up) to save you, she heals the lands, and is actually a princess, while you&#8217;re a nobody with no powers – why are you needed? While Elika can teleport, use magic in combat, heal the lands, and run circles around you there is one thing she needs you for – climbing on mossy walls. Yes, as soon as you hit a mossy wall, the character freezes as he waits for Elika to climb on his back.</p>
<p>Overall, I only have this game because a friend saw it going cheap ($10) at JB HiFi. If you don&#8217;t treat it like a <em>Prince of Persia</em> game or if you&#8217;ve never played <em>Sands of Time</em>, you might enjoy it but otherwise it&#8217;s a pretty hard sell.</p>
<p><a href="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/07/review_card_pop.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" class="wlDisabledImage" title="review_card_pop" border="0" alt="review_card_pop" align="right" src="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/07/review_card_pop_thumb.png" width="484" height="181" /></a></p>
<img src="http://feeds.feedburner.com/~r/TheLeagueOfPaul/~4/Eqs3DPmjk3Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.theleagueofpaul.com/blog/2010/07/07/review-prince-of-persia-2008-xbox360/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.theleagueofpaul.com/blog/2010/07/07/review-prince-of-persia-2008-xbox360/</feedburner:origLink></item>
		<item>
		<title>Auto ClickOnce Deploys with TeamCity + MSBuild</title>
		<link>http://feedproxy.google.com/~r/TheLeagueOfPaul/~3/CXyjWPbRPas/</link>
		<comments>http://www.theleagueofpaul.com/blog/2010/06/24/auto-clickonce-deploys-with-teamcity-msbuild/#comments</comments>
		<pubDate>Thu, 24 Jun 2010 06:42:51 +0000</pubDate>
		<dc:creator>Paul</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.theleagueofpaul.com/blog/2010/06/24/auto-clickonce-deploys-with-teamcity-msbuild/</guid>
		<description><![CDATA[Currently when you go to install MahTweets, you&#8217;re greeted with this less than reassuring dialog: Unknown publisher? Well, you should know it&#8217;s from the MahTweets team, but you can&#8217;t be certain &#8211; the next beta of MahTweets will be signed properly so a known publisher will appear (or you can be sneaky and install our [...]]]></description>
			<content:encoded><![CDATA[<p>Currently when you go to install MahTweets, you&#8217;re greeted with this less than reassuring dialog:</p>
<p><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="image" src="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/06/image1.png" border="0" alt="image" width="470" height="287" /></p>
<p><strong>Unknown publisher</strong>? Well, you should know it&#8217;s from the MahTweets team, but you can&#8217;t be certain &#8211; the next beta of MahTweets will be signed properly so a <em>known</em> publisher will appear (or you can be sneaky and install our <em><a href="http://mahtweets.com/downloads/nightlies/mahtweets.application">nightlies auto-generated by TeamCity+MSBuild</a></em>, which is what this article is all about!). Once done, you&#8217;ll see a dialog more like this:</p>
<p><img style="display: block; float: none; margin-left: auto; margin-right: auto; border-width: 0px;" title="Capture" src="http://www.theleagueofpaul.com/blog/wp-content/uploads/2010/06/Capture.png" border="0" alt="Capture" width="471" height="285" /></p>
<p>First step is getting the verified publisher parts working. For that, I highly recommend Jeff Wilcox&#8217;s guide to <a href="http://www.jeff.wilcox.name/2010/02/codesigning101/">Getting Started with code signing for under (USD)$100</a>. Jeff&#8217;s guide is great, until you come up to the issue of wanting to automate the whole build process.</p>
<h3>TeamCity</h3>
<p>Next is <a href="http://www.jetbrains.com/teamcity/">TeamCity</a> (TC) from JetBrains. If you&#8217;re new to the game, TC is one of many Continuous Integration (CI) servers, this one happens to have a free/limited version, which is perfect for small open source projects or for a personal CI. Being Java, TC runs on any platform.</p>
<h3>MSBuild</h3>
<p>This is the only &#8220;hard&#8221; part – partially because Mage is frustrating but mostly because MSBuild is frustrating. It was a matter of a lot of trial and error. To make things a little easier, all the build files are in a subdirectory of the root of the project creatively titled <em>BuildOutput</em>. Inside that there are the subfolders for the three main stages – Application (compiled output), Install (ClickOnce output) and Zip (the zipped ClickOnce output).</p>
<p><strong>You can download the latest version of the MahTweets msbuild script from <a href="https://svn.mahapps.com:8443/svn/MahTweets/trunk/MahTweets.msbuild">SVN</a> or <a href="http://fisheye.mahapps.com/browse/MahTweets/trunk/MahTweets.msbuild?r=HEAD">Fisheye</a></strong></p>
<p>Most build scripts have a few different stages to them, and ours is no different. For us, the flow is something like</p>
<ol>
<li><em>Cleanup</em> – make sure all the required build directories exist (and you could have it delete the contents first)</li>
<li><em>Version</em> – since it is automated builds, we make sure the AssemblyInfo contains the Subversion revision number associated with this build</li>
<li><em>Compile</em> – actually make the project to publish</li>
<li><em>Publish</em> – this is the difficult/frustrating section, and I&#8217;ll only really go in depth about <em>Publish.</em>
<ol>
<li>Our particular<em> Publish </em>process deletes all the duplicated files, cleans up any PDB&#8217;s and XMLs that were compiled, and removes the .manifest and .application generated.</li>
<li>Next is the first stage of the ClickOnce files – creating the MahTweets.exe.manifest from the files created in <em>Compile </em>using the devil known as Mage.</li>
<li>After creating the manifest, the rest of the files are copied over into the appropriate directory (<em>Install/Application Files/MahTweets_X_Y_Z_R/ </em>and then their subfolders, where X is MajorVersionNumber, Y is Minor, Z is Build and R is revision) – this could be performed before or after, makes no real difference.A key thing to note here is all files are appended with &#8220;.deploy&#8221; at the end – if you&#8217;re serving up your ClickOnce files from non-IIS servers, this isn&#8217;t needed, but IIS won&#8217;t serve up files ending with DLL or Config.</li>
<li>While mage could be used for the next stage, all reports are that <em>GenerateDeploymentManifest </em>(part of MSBuild) is far more suited to the job. This creates the MahTweets.application file – the file that launches the ClickOnce install process.</li>
<li>Mage is called once more &#8220;update&#8221; the MahTweets.application file, but in reality all it does is sign it</li>
</ol>
</li>
<li><em>Package – </em>to be honest, for us at the moment, the package section is unnecessary, but it is nice to have around. Packaging in this case just zips up the ClickOnce install to a single compressed file.<br />
Eventually, we could turn this into packaging up the files to do a portable build, but we&#8217;re not there just yet.</li>
</ol>
<h3>MSBuild: Publish</h3>
<p>As I mentioned, the meat of this post is is to do with the Publish section – see the links in the above section to get our full MSBuild file if its of interest.</p>
<p>Looking in more detail at the section below</p>
<ul>
<li>The <em>ItemGroup</em> then <em>Delete</em> cleans up the files generated in <em>Compile</em> that are duplicated – most projects shouldn&#8217;t need this, but we do some funny things around plugins</li>
<li>The next interesting command is the <em>Exec</em> calling <em>mage </em>– this creates the .exe.manifest file from the directory, and then signs the manifest.</li>
<li>Next we copy all the files (using that cryptic <em>Copy</em> command) and rename them to append .deploy – as mentioned above, this is related to IIS</li>
<li>Next <em>GenerateDeploymentManifest</em> creates the .application file – this is an XML file that ClickOnce gets all the details about the install from.</li>
<li>And finally <em>mage</em> signs the .application file</li>
</ul>
<p>This general process <em>should</em> work for all, but there are a few flags to be aware of</p>
<ul>
<li>As we needed MahTweets to be a 32bit app (because of some dependencies) <em>–Processor x86 </em>is required in the initial <em>mage </em>calls</li>
<li>In <em>GenerateDeploymentManifest&#8217;s </em>parameters
<ul>
<li>MapFileExtensions=&#8221;true&#8221; lines up with renaming files to .deploy</li>
<li>Platform=&#8221;x86&#8243; sets the processor correctly</li>
<li>TargetFrameworkMoniker=&#8221;.NETFramework,Version=v4.0,Profile=Client&#8221; is used because we&#8217;re targeting the .NET 4 Client Profile for increased compatibility.</li>
</ul>
</li>
</ul>
<pre class="brush: xml;"> &lt;Target Name="Publish" DependsOnTargets="Compile"&gt;

    &lt;!-- remove unnecessary plugins - dependencies which should be already loaded into appdomain --&gt;
    &lt;ItemGroup&gt;
      &lt;FilesToDelete Include="$(OutputFolderApplication)**\*.pdb" /&gt;
      &lt;FilesToDelete Include="$(OutputFolderApplication)**\*.xml" /&gt;
      &lt;FilesToDelete Include="$(OutputFolderPlugins)MahTweets.Core.*" /&gt;
      &lt;FilesToDelete Include="$(OutputFolderPlugins)MahTweets.Library.*" /&gt;
      &lt;FilesToDelete Include="$(OutputFolderPlugins)MahTweets.UI.*" /&gt;
      &lt;FilesToDelete Include="$(OutputFolderPlugins)Chrome.dll" /&gt;
      &lt;FilesToDelete Include="$(OutputFolderPlugins)GMap.*"/&gt;
      &lt;FilesToDelete Include="$(OutputFolderPlugins)IronPython*"/&gt;
      &lt;FilesToDelete Include="$(OutputFolderPlugins)Microsoft*"/&gt;
      &lt;FilesToDelete Include="$(OutputFolderPlugins)StructureMap.dll"/&gt;
      &lt;FilesToDelete Include="$(OutputFolderPlugins)Newtonsoft.Json.dll"/&gt;
      &lt;FilesToDelete Include="$(OutputFolderPlugins)System.Data.SQLite.dll"/&gt;
      &lt;FilesToDelete Include="$(OutputFolderPlugins)Windows7.SensorAndLocation.dll"/&gt;
      &lt;FilesToDelete Include="$(OutputFolderApplication)MahTweets.exe.manifest" /&gt;
      &lt;FilesToDelete Include="$(OutputFolderApplication)MahTweets.application" /&gt;
    &lt;/ItemGroup&gt;
    &lt;Delete Files="@(FilesToDelete)" /&gt;

    &lt;PropertyGroup&gt;
      &lt;CurrentVersion&gt;$(OutputInstallPath)Application Files\MahTweets_$(Major)_$(Minor)_$(Build)_$(Revision)\&lt;/CurrentVersion&gt;
    &lt;/PropertyGroup&gt;

    &lt;MakeDir Directories="$(OutputInstallPath)" Condition="!Exists('$(OutputInstallPath)')" /&gt;
    &lt;MakeDir Directories="$(OutputInstallPath)Application%20Files" Condition="!Exists('$(OutputInstallPath)Application Files')" /&gt;
    &lt;MakeDir Directories="$(CurrentVersion)" Condition="!Exists('$(CurrentVersion)')" /&gt;

    &lt;Copy SourceFiles="$(MSBuildCommunityTasksPath)setup.exe" DestinationFolder="$(OutputInstallPath)" OverwriteReadOnlyFiles="true" /&gt;
    &lt;Copy SourceFiles="$(MSBuildCommunityTasksPath)publish.htm" DestinationFolder="$(OutputInstallPath)" OverwriteReadOnlyFiles="true" /&gt;

    &lt;Message Text="Generating Application Manifest" /&gt;

    &lt;Exec Command='mage.exe -New Application -Processor x86 -ToFile "$(CurrentVersion)MahTweets.exe.manifest" -name MahTweets -Version $(Major).$(Minor).$(Build).$(Revision) -FromDirectory $(OutputFolderApplication) -ch $(CertHash) -IconFile mahtweetsicon.ico' /&gt;

    &lt;ItemGroup&gt;
      &lt;NewApplicationFiles Include="$(OutputFolderApplication)**\*.*" /&gt;
    &lt;/ItemGroup&gt;

    &lt;Copy  SourceFiles="@(NewApplicationFiles)" DestinationFiles="@(NewApplicationFiles-&gt;'$(CurrentVersion)\%(RecursiveDir)%(Filename)%(Extension).deploy')"/&gt;

    &lt;Message Text="Generating Deployment Manifest" /&gt;

    &lt;ItemGroup&gt;
      &lt;EntryPoint /&gt;
    &lt;/ItemGroup&gt;

    &lt;CreateItem Include='BuildOutput\Install\Application%20Files\MahTweets_$(Major)_$(Minor)_$(Build)_$(Revision)\MahTweets.exe.manifest' AdditionalMetadata='TargetPath=Application%20Files\MahTweets_$(Major)_$(Minor)_$(Build)_$(Revision)\MahTweets.exe.manifest'&gt;
      &lt;Output TaskParameter="Include" ItemName="EntryPoint"/&gt;
    &lt;/CreateItem&gt;

    &lt;Message Text="EntryPoint specified at '$(EntryPoint)'" /&gt;
    &lt;GenerateDeploymentManifest AssemblyName="MahTweets.exe"
                                AssemblyVersion="$(Major).$(Minor).$(Build).$(Revision)"
                                DeploymentUrl="$(DeployToUrl)"
                                Description="MahTweets - an open-source Twitter client"
                                EntryPoint="@(EntryPoint)"
                                Install="true"
                                OutputManifest="$(OutputInstallPath)\MahTweets.application"
                                Product="MahTweets"
                                Publisher="MahApps"
                                SupportUrl="$(SupportUrl)"
                                MapFileExtensions="true"
                                UpdateEnabled="true"
                                UpdateMode="Foreground"
                                Platform="x86"
                                TargetFrameworkMoniker=".NETFramework,Version=v4.0,Profile=Client"&gt;
      &lt;Output ItemName="DeployManifest" TaskParameter="OutputManifest"/&gt;
    &lt;/GenerateDeploymentManifest&gt;
    &lt;Message Text="Deployment Manifest stored to '@(DeploymentManifest)'" /&gt;

    &lt;Exec Command='mage.exe -Update $(OutputInstallPath)\MahTweets.application -Publisher MahApps -ch $(CertHash)'/&gt;
  &lt;/Target&gt;</pre>
<p><strong>Thumbprint vs file+password</p>
<p></strong>You may have noticed that I&#8217;m using &#8220;CertHash&#8221; instead of the usual CertFile (and pointing to a PFX) + CertPass. The advantage with this is that its easy to take this key and distribute it so it builds on any and all machines, so long as they can get a copy of the key file. The disadvantage is, your &#8220;secret&#8221; password is visible to anybody who has access to your build server.</p>
<p>However, if you install the certificate on your desired machines, you can use the &#8216;thumbprint&#8217; which is a hash/unique identifier to that key. Since the thumbprint is unique to that key – it&#8217;s the same value on all machines, so install the key onto the machines you want (and enter the password during installation) and nobody you don&#8217;t want having access to that password will ever be able to see it.</p>
<p>The downside to this is that it could still be abused – if somebody had access to TC with enough rights to create a new project or somebody committing to one of your source control repos, by just knowing that thumbprint, the could trick your machine into signing their own code under your key.</p>
<p><strong>Making sure your build agent has access to your key</p>
<p></strong>By default, TC Build Agents run under the LocalSystem account (on Windows) and when you install a certificate (by double clicking on it) it only installs under <em>that</em> account. Thankfully, <a href="http://www.laurentkempe.com/post/ClickOnce-certificate-and-TeamCity.aspx">Laurent Kempé figured out an easy way to install the certificate</a> under the LocalSystem account.</p>
<blockquote><p>You will need a tool from <a href="http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx">SysInternals called PsExec</a>, then using PsExec:</p>
<p>&gt; Psexec.exe -i -s cmd.exe</p>
<p>you will have ran a command prompt on your system in the Local System Account (LSA).</p>
<p>Using that new command prompt, cd to the folder containing your certificate and start it</p>
<p>&gt; my_TemporaryKey.pfx</p>
<p>Then you will face the Certificate Import Wizard in which you click Next &gt; Next &gt; Type the password &gt; Next.</p>
<p>Your certificate is installed now for Local System Account (LSA), and your build should work now.</p></blockquote>
<p><strong>Not using ClickOnce? No worries – sign the executable(s) instead </strong></p>
<blockquote><p>signtool.exe sign /f PathToKeysAndCert.Pfx /p “MySuperSecretPasswordToUseThePfxFile” /v “C:\MyFileToSign.exe”,</p></blockquote>
<img src="http://feeds.feedburner.com/~r/TheLeagueOfPaul/~4/CXyjWPbRPas" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.theleagueofpaul.com/blog/2010/06/24/auto-clickonce-deploys-with-teamcity-msbuild/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.theleagueofpaul.com/blog/2010/06/24/auto-clickonce-deploys-with-teamcity-msbuild/</feedburner:origLink></item>
	</channel>
</rss>
