Customising Your Build Process

TL;DR

This article got much longer than I had originally intended, so here’s a summary for those with short attention spans, wondering whether they should bother reading further:

  • You should automate manual pre and post build tasks by customising your MSBuild script.
  • Customising your builds with MSBuild can actually be quite easy, and changes can be made rapidly using a technique I demonstrate.
  • The best way I’ve discovered to structure build script customisations is to store your custom tasks in a .targets file, and import the .targets file into your project file.
  • This technique means you don’t need to modify your project file each time you want to make a change to your custom tasks.
  • You can also write code directly in your build scripts using inline tasks!

Introduction

I’ve known for years that you could customise how your .NET applications are compiled by MSBuild, but for a number of reasons (which I’ll mention shortly) I’ve avoided doing so up until now, tending to specify commands as pre or post build events instead.  However, I’ve recently discovered what I think is a much better way to customise MSBuild scripts, which I’ll share with you in this article.  Before we do so, I’ll provide a bit of background info for those of you who are new to MSBuild.

What is MSBuild?

For those that don’t know, MSBuild is the short name for the Microsoft Build Engine.  When you compile your .NET applications in Visual Studio, TFS Build, or on the command-line, it’s MSBuild that’s doing all the work.

MSBuild follows a build script, which specifies what it should build and how.  If you’ve ever taken the time to look at the source of your project file (.csproj, .vbproj, etc), you’ll notice that it’s all XML.  You may or may not have realised it, but it’s actually a MSBuild script!  MSBuild parses the XML in your project file (along with any other files that it imports), and compiles your project accordingly.

The great thing is that you can customise this build script and add your own tasks to it to suit your project’s specific needs.  The possibilities this provides are almost limitless!

It’s beyond the scope of this article to detail the structure and features of MSBuild scripts in any sort of depth.  MSDN is the place to go for that sort of information.  In summary though, a build script may consist of:

Properties – key/value pairs used to configure builds.
Items – items (usually file references) that are to be compiled or used as inputs to tasks.
Item Groups – all items must be contained within one or more item group elements
Tasks – actually perform work within the build process
Targets – used to sequence tasks within the build process

More information on the can be found on MSDN here: MSBuild Concepts

Manual Processes are Bad!

So when should you customise your builds, and why?  If you find that you need to manually perform any task before or after your application has built, regardless of whether it needs to be done every time you press F5 in Visual Studio or only when your build server is doing a release build, then you should automate this task.  Being a developer, you should naturally always be on the lookout for repetitive tasks that can be eliminated with automation.  MSBuild is the tool you should be using for this job.  Or Nant, or custom build templates in TFS Build, etc, but you get the drift.  This article is about MSBuild though, so let’s stay focused.

For example, if you’re doing any of these things manually before or after a build (a few examples off the top of my head), then you should be automating the process immediately!

  • Incrementing a version number
  • Zipping up outputs
  • Transforming XML files
  • Installing an assembly into the GAC
  • Generating a NuGet package
  • Deploying the outputs
  • Modifying outputs in any way (such as renaming them, etc)
  • Copying outputs between projects
  • Generating documentation files
  • Obfuscating assemblies
  • Executing SQL statements
  • Excluding files or folders from being published

The vast majority of build script customisations will typically only run when performing a release build (which is hopefully being done by a build server!).  We’ll look at how your custom build script can check for this later in the article.  A nice thing about custom MSBuild scripts though is that they’ll also run when building the project in Visual Studio, which can make developing, testing, and debugging your customisations a lot easier.

Misconceptions

As I mentioned at the start of the article, I’ve known that you can modify project files in order to customise the build process, but I’ve avoided doing so due to a few misconceptions I had:

  • I thought each time I wanted to change something in the build process I’d have to edit the project file.  Modifying a project file in Visual Studio involves unloading the project, opening the project file, finding the right spot for the change, making the change, and then reloading the project it again.  This can be a frustrating and time consuming process, especially when the changes you make don’t work and you need to repeat the process.
  • I thought that if you wanted to write custom code in C# as part of the build process, you’d have to write it as a task, compile it as an assembly, and make it available somehow such that MSBuild could find it.  This seemed a bit too much effort for what was generally a minor task.
  • I was worried that modifications to project files are not easily visible to future maintainers of the application, and can lead to confusion and frustration due to “unexpected behaviour” (good programmers should always consider the impact that their customisations will have on the maintainability of the applications they’re working on).

None of these points are true when you use the technique I’m about to describe for customising the build process.

Why not Simply use the Build Events Tab in the Project Properties?

Previously, my alternative to customising the MSBuild script was to specify pre and post build event commands in the Build Events tab in the Project Properties window.  For cases which involve simply executing a command on the command-line, this does the job fine.  It’s certainly worked for me in the past.  However, a lot more flexibility can be gained by customising the MSBuild script, and it opens many further possibilities.

I also personally hate the Build Events tab with a vengeance.  I’m pretty sure that no-one has touched it since VS2002.  Commands are usually quite long, yet it insists on having a fixed width of about 390px for the text boxes used to configure the commands, regardless of the width of the document pane.

CustomBuild1

A Better Way

I was using the AjaxMin to bundle and minimise JavaScript files recently (more on that in a future blog post), and noticed how the documentation for its build task demonstrated using a separate targets file to define its custom build actions, which could then be imported into the main build script (i.e. the project file).  It suddenly struck me that this was the perfect mechanism to use when customising the build process of my projects.  Rather than having to add custom build tasks directly to a project file, I could simply maintain them in a separate targets file, which the project file could then import.  The benefits of this would be:

  • Modifying my project’s build configuration becomes very easy and rapid, and
  • The presence of the .targets makes it much more obvious to future maintainers that the build process has been customised, and it’s easy to see exactly what those customisations are.

Sure, I still needed to modify the project file to get it to import the targets file, but then no further changes would be required.  As you’ll see shortly, when I discuss inline tasks, it can be a huge benefit not having to modify your project file each time you want to make a change to your build script.

Configuring a Targets File

So let’s look at how you go about customising your build script using this technique.  The first step in the process is to create a targets file, and import it into your project file:

  1. Add a new XML file to the root of your project named CustomBuildProcess.targets.
  2. Add the following XML to it:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

</Project>

  1. Right-click on your project file in the Solution Explorer window, and select Unload Project from the context menu.
  2. Right-click on your project file again in the Solution Explorer, and select Edit [Project File Name] from the context menu.
  3. Find a line that imports a targets file.  For example:

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

  1. Add a new line after this, and add the following XML element:

<Import Project="$(MSBuildProjectDirectory)\CustomBuildProcess.targets" />

  1. Save the changes you’ve made to the project file, then reload the project by right-clicking on the project in the Solution Explorer window, and selecting Reload Project from the context menu.
  2. Try to build your project – it should build successfully.

Customising Your Build Process

You’ve now got a targets file, in which you can specify the customisations to your project’s build process.  How you write MSBuild scripts is really beyond the scope of this article, as that’s a whole topic in itself.  There’s plenty of information available on doing so on MSDN and the wider web though – I’d probably recommend this MSDN article as a good first port of call: Walkthrough: Using MSBuild

That said, I don’t think this article would be complete without a simple example of customising the build script.  So for this example, we’re just going to log a message to the output console.  The key concern here is when will your custom tasks execute?  There’s actually a number of ways that you could use to specify when your custom tasks should run, such as overriding the default targets defined in Microsoft.Common.CurrentVersion.targets (not recommended – see the comment from Chris Walters at the end of the post), or adding your custom targets to the existing default target definitions (which is not ideal, as you have to modify the .csproj file). For this example we’ll actually use the simplest way, which is by specifying which target our target should run before or after.  There’s a number of targets you can “target”, including Compile, Build, Rebuild, Clean, Publish, ResolveReferences, and ResGen, amongst the many others defined in the Microsoft.Common.CurrentVersion.targets file.  As you can see, there’s no shortage of extensibility points.  In this example, we’ll create a target that runs after the Compile target, and get MSBuild to write Hello World! to the Output window.  All you need to do is add the Target element below to your CustomBuildProcess.targets file:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="SayHello" AfterTargets="Compile">
    <Message Text="Hello World!" Importance="High" />
  </Target>
</Project>

Note that it’s important that you set the Importance attribute to High.  Otherwise the message won’t display in the Output window unless you increase the output verbosity of MSBuild, a topic we’ll discuss further when it comes to debugging your customisations.

Now when you compile your project, the message is displayed in the Output window after the project has successfully built.

CustomBuild2

This was an extremely simple example, but it should help you at least get started customising your build.  There’s numerous tasks that are built into MSBuild which you can use, such as Copy, Delete, MakeDir, Exec, to name a few.  A full list of these with descriptions and examples can be found here: MSBuild Task Reference.  However, they are all very basic tasks, which is where the MSBuild Extension Pack and MSBuild Community Tasks projects come in.  These provide much more sophisticated build tasks that you can use, enabling you to work with FTP, the GAC, the registry, Active Directory, IIS, source control, XML, and much more.

Debugging Your Customisations

I thought I’d just touch on two tips to debug your build script customisations, and help you solve any issues you might have.

The first tip is to write messages to the Output Window, as demonstrated in the previous section.  The second is to increase the output verbosity of MSBuild in order to give you more of an insight into what’s going on.  You can change this in Visual Studio’s option dialog, under Projects and Solutions > Build and Run.

CustomBuild3

Using Inline Tasks

The build tasks provided out of the box with MSBuild, along with the community build tasks, will usually cover most of your requirements when customising your build process.  However, sometimes what you need done warrants writing your own custom build task, and even if it doesn’t it can often be easier to write just a bit of code to do what you need rather than mucking around with modifying the MSBuild script itself.

Traditionally, you had to create an assembly, write your custom build tasks in that, and then ensure it’s available to MSBuild when it runs.  But this incurred quite an overhead in configuration and management, so to solve this issue MSBuild 4.0 introduced inline tasks.  Essentially, inline tasks enable you to write code directly in the build script using your favourite .NET language (or even other languages if someone has developed a custom task factory, such as those for Powershell and the DLR provided by the MSBuild Extension Pack), and have it execute as part of your build process.  This is an awesome feature, and makes it so much easier to develop and maintain build customisations.  You can easily write code in a language that’s familiar to you, you’ve got the full .NET Framework at your disposal, and you’ve basically got almost limitless possibilities.

It’s when developing inline tasks that you’ll find locating your custom build tasks separately from your project file makes a huge difference.  You can iterate rapidly during the development of these inline tasks, and it’s very easy for future maintainers of the project to see exactly what’s going on.

I don’t want to get too deeply into how to write inline tasks as there’s pretty good documentation on MSDN already on this topic, however given that the targets file structure I’ve demonstrated is perfect for use when writing inline tasks, I think a simple example is in order.  Again, we’re just going to keep things simple and write a message to the Output window.

  1. The first step is to create a UsingTask element in your targets file.  You need to give the task a name, and specify the task factory and assembly file.  Since we’re writing .NET code for our inline task, the task factory will be CodeTaskFactory, and the assembly will be the MSBuild tasks assembly:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <UsingTask TaskName="MyCustomInlineTask" TaskFactory="CodeTaskFactory"
             AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
  </UsingTask>
</Project>

Note that these values will always be the same, assuming you’re just writing .NET code in your inline task.  Task factories essentially interpret and execute the code you write in your build script, so we’re pointing to the task factory class that manages this, and the assembly that it can be found in.  If you’d prefer to execute PowerShell script in your inline task, then you can use the PowerShellTaskFactory available in the MSBuild Extension Pack instead.

  1. The next step is to define your task (within a Task element), and write the code for it within a Code element, remembering to specify the language you’re using with the Language element:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <UsingTask TaskName="MyCustomInlineTask" TaskFactory="CodeTaskFactory"
             AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll
    <Task>
      <Code Type="Fragment" Language="cs">
        <![CDATA[
	  Log.LogMessage("Hello from an inline build task!", MessageImportance.High);
	]]>
      </Code>
    </Task>
  </UsingTask>
</Project>

Note that the CData elements are not required if your code doesn’t use XML characters such as (i.e. XML reserved characters), but it’s strongly recommended.

You can specify assembly references, using statements, and input parameters as required, which is documented on MSDN.

  1. The final step is to reference your task (using the name you gave it on the UsingTask element) in a target such that it will be executed:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <UsingTask TaskName="MyCustomInlineTask" TaskFactory="CodeTaskFactory"
             AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll>
    <Task>
      <Code Type="Fragment" Language="cs">
        <![CDATA[
	  Log.LogMessage("Hello from an inline build task!", MessageImportance.High);
	]]>
      </Code>
    </Task>
  </UsingTask>

  <Target Name="RunMyInlineTask" AfterTargets="Compile">
    <MyCustomInlineTask />
  </Target>
</Project>

Now when you build your project you should see the message appear in the Output window.

CustomBuild4

If the message doesn’t appear, try changing your MSBuild output verbosity option to Normal in Visual Studio’s options window, as described in the Debugging Your Customisations section of this article.  For some reason the Log.LogMessage method doesn’t seem to work exactly like the Message build task used earlier.  Even though the importance is set to High when using them both, the Message build task shows the message when the build output verbosity is set to Minimal, but the Log.Message method only shows the message if the build output verbosity is ramped up to Normal or higher.

This was a very simple example, but I have an upcoming blog post in which I’ll demonstrate implementing an inline task which is much more sophisticated.

Running Build Customisations on a Build Server

To be honest, I think most customisations to your build script will only need to be run when it’s being built on a build server.  From my experience, it’s rare to need to perform custom actions when doing a “desktop” build.  Many of the possible customisations I listed earlier in the article are things you’d only want done when creating a release build, and it’s not out of place to say that most teams should have a build server that does this for them.

Common build servers include TeamCity, CruiseControl.NET, and TFS Build. The technique outlined in this blog post works with all of these.

If this is the case and you’re using TFS Build, it may be worth investigating whether it would be better to customise your build definition’s template instead (build templates use Windows Workflow to define a sequence of activities to execute during the build, and can easily be reused across build definitions).  That said, I’ve done a lot of build template customisation work, and it’s a right royal PITA.  It’s not fun at all.  Testing and debugging customisations is a seriously slow and painful process, requiring checking in of the template to source control each time you make a change that you want to test.  It’s also hard to see what customisations have been made, making build templates a nightmare to maintain.  Anyway, that’s just my experience.

I did lots of work around customising TFS Build templates last year, and I might try and share some tips and recipes in future blog posts. Custom TFS Build templates very much have their place, particularly when implementing customisations that apply to multiple projects being built by your build server.  It may be a painful process, but is often the most appropriate choice over developing custom MSBuild scripts when implementing custom processes that only ever run on the build server.

If you do go down the path of developing custom MSBuild scripts but your custom build processes are to run only on the server, you can create a condition on your targets that check the value of the $(BuildingInsideVisualStudio) property.  It’s true when the project is being built from Visual Studio , and empty when hosted elsewhere (i.e. from the command line or a build server).  For example, the following target will only run when the project is built outside of Visual Studio:

  <Target Name="DoStuff" AfterTargets="Compile" Condition="'$(BuildingInsideVisualStudio)' == ''">
    <!-- My tasks -->
  </Target>

Conclusion

So we’re done!  In this article you’ve seen how you can implement MSBuild script customisations with reasonable ease.  I use this technique in many of my projects – hopefully you’ll agree that this is a pretty nice technique for customising your build scripts, and you’ll use it in your own projects too!

The best place to get more information on customising your build process is MSDN.  The section on MSBuild can be found here: MSBuild.

Advertisements

Relaunching My Blog, and a Silverlight Retrospective

After 2.5 years of radio silence, I’ve decided it’s finally time to relaunch this blog.  My last post was about the release of my Pro Business Applications with Silverlight 5 book, which just so happened to coincide with the “death” of Silverlight.  At the time, I had become burnt out from writing on top of maintaining a job, so between this and also finding the carpet swept out from underneath me given the fate of Silverlight, I no longer felt the need or desire to write any more.  I stand by my announcement that I will never ever write another book again, but I’d still like to take the opportunity via this blog to give back some of the hard won knowledge that I’ve gained to the developer community.  So I’m happy to announce that you’ll now start seeing renewed activity here, but with a new focus towards building professional business applications using HTML5 technologies (HTML, JavaScript, and CSS).

Before moving onto the next phase of this blog, however, I thought it might be worthwhile closing off the previous chapter, given that I had focused heavily on Silverlight, with a bit of a wrap up and a retrospective of Silverlight – a post-mortem if you may.  I think people tend to forget what a challenge it was to develop applications for the web just a few short years ago, and now unfairly (in my opinion) malign Silverlight and those who used it.  I’d like to set a few things straight, or at the very least detail my perspective on it, if I may.

Why Silverlight Received Traction

Silverlight had its roots in WPF, which automatically made it appealing to WPF developers.  Rather than just being bound to Windows, WPF developers could transfer their existing skillset to developing applications with Silverlight that easily deployed via the web, and could also run on Apple OS X!

I was not a WPF developer at the time – instead I had been developing various web-based business applications using ASP.NET WebForms and the Microsoft AJAX Toolkit.  These applications worked, and impressed clients and users, but it was certainly primitive and flawed.

Remember, the ASP.NET MVC CTP only appeared at the end of 2007, and didn’t hit V1.0 until March 2009!

My interest in Silverlight started in the Silverlight 2 Beta days (mid-2008), before Silverlight had a clear business application focus.  However, I immediately saw its potential in this area, and started writing articles on the SilverlightShow.net website in 2008, specifically targeting building business applications with Silverlight – one of the first, if not the first to do so.  Silverlight enabled me to write well-structured applications using C# on both the server and the client, and create rich user experiences with ease, without worrying about cross browser concerns.  Remember, this was a time when:

  1. Chrome didn’t exist (its first release only came in September 2008), and JavaScript on all other browsers ran incredibly slowly.
  2. IE6 was still an extremely popular browser.
  3. HTML5 support in browsers was still a long way off.
  4. CSS rendered inconsistently between browsers, and was limited in features.
  5. Libraries like knockout.js, backbone.js, require.js, breeze.js,  etc didn’t exist yet.
  6. Single Page Applications (SPAs) didn’t really exist (beyond GMail, which had the support of Google behind it).
  7. Frameworks like angular.js, durandal.js, and Ember.js didn’t exist yet.
  8. All the browsers behaved differently, and testing was a nightmare. (It still is, but less so)
  9. Mobile devices were not widespread.  It’s hard to believe, but there was a time when most mobile phones weren’t able to browse the web, and tablets were big clunky things running full Windows.  The iPhone only came out in 2007, and the iPad only in 2010.
  10. Browser plug-ins were used widely – particularly Flash.
  11. Installing the .NET Framework needed a 100+mb download, when Silverlight was only a 5-7mb download.

The above factors contributed to making web application development a nightmare.  This made Silverlight a very attractive platform for us as developers.  Silverlight started getting much more love from Microsoft than WPF had ever seen, and was rapidly gaining traction with developers accordingly.  Microsoft’s message was essentially “if you’re building business applications for the web, you should be using Silverlight”.  WPF was getting little to no attention, and Silverlight was getting lots, so given the choice it made sense to focus on that instead of WPF.  Especially given that from version 3, Silverlight was obviously much more focused towards business application development than WPF was.  It had a DataGrid (for better or worse) long before WPF, validation summary and validation styles on input controls, a DatePicker control, PivotViewer control (from version 4), the Visual State Manager, RIA Services, text in WPF was fuzzy and gave users headaches (until .NET V4.0 fixed this issue), and it could run on Apple OS X.  They are just some of the benefits off the top of my head.  Interestingly, Silverlight has many features that even “Modern UI” applications (i.e. Windows 8 applications) still don’t support.

Why Silverlight Started to Lose its Shine

Silverlight was inevitably misused at times.  I personally never saw Silverlight as being suitable for use on public facing websites (with the exception of sites that could take advantage of its awesome streaming video support), but I strongly believed in its ability as a solid technology for building web applications upon.  As in, data centric applications which typically (but not always) ran within a corporate network.  And it suited this scenario very well.  But it would obviously provide a barrier to entry when it comes to the “drive by” nature of web surfers on the open web.

Silverlight also had a perception issue.  People were expecting it to be something it was never realistically going to be.  In particular, there was a desire for Silverlight to run on mobile devices.  Unfortunately, that was just never going to happen, and some saw that as being an indicator that Silverlight had failed.  That said, given the rapidly rising use of Apple Macs and the fact that it ran on these machines meant that it still had a major advantage over WPF.

Over the following years, Silverlight was advancing rapidly, version to version.  Silverlight really matured when it hit version 4, however, during this time, the “native” web was also maturing rapidly.  We started to see JavaScript libraries appear (Backbone.js, Knockout.js, etc) which made developing native web applications much easier and more robust.   HTML5-supporting browsers started gaining widespread adoption, reducing the need for plug-ins.  The rise of iPad use within businesses, and Apple’s steadfast refusal to support Silverlight on it, started working against Silverlight.  Silverlight was starting to lose its competitive advantage, and it started to become much more viable to build business applications using native web technologies.

And Then Everything Fell Apart…

Silverlight was still getting a strong focus, marketing, and love from Microsoft, until suddenly it just stopped.  Just like that, it disappeared overnight, and no-one from Microsoft could be drawn in to talk about Silverlight and its future.  We’d heard some rumours that Silverlight may not have a future, care of ex-Silverlight program manager Scott Barnes (aka @MossyBlog), and this appeared confirmed when Bob Muglia, president of the Server and Tools division let it slip that Microsoft’s “strategy has shifted” toward HTML5.

Mr. Praline: I’ll tell you what’s wrong with it, my lad. ‘E’s dead, that’s what’s wrong with it!
Owner: No, no, ‘e’s uh,…he’s resting.
Mr. Praline: Look, matey, I know a dead parrot when I see one, and I’m looking at one right now.
– Dead Parrot Sketch, Monty Python’s Flying Circus

The silence on Silverlight’s future spoke more than words, and was the worst thing Microsoft could have ever done.  The resulting unease and uncertainty inevitably led to the ecosystem collapsing, with tens of thousands of developers suddenly left out in the cold.  Not only were developers cheated, but the effects extended to:

  • Contractors and development shops who had projects cancelled
  • Authors whose book sales fell through the floor
  • Component vendors who had invested heavily in developing components that nobody wanted any more
  • Businesses who had invested in a technology that had no future

Having personally invested greatly into Silverlight, and falling into multiple of the above categories, I was one of the thousands that felt the repercussions.

It’s interesting to now see companies that promoted Silverlight to their clients and had developed many Silverlight applications now marketing themselves as specialising in migrating Silverlight applications away from the platform.

My Position on Silverlight’s death

I am still, to this day, monumentally pissed off with Microsoft and their handling of Silverlight’s demise.  It just never needed to be as bad as it was.  I personally felt that Silverlight had reached a reasonable maturity by version 5, and didn’t really need to go too much further.  Actually, I think Silverlight went too far in a number of aspects.  In particular, adding 3D support to Silverlight 5 was completely unnecessary.  It added to the runtime size, I suspect it was the reason for Silverlight 5 being released so long after Silverlight 4 (18 months), and I’m still yet to see any application that ever used it.

That said, Silverlight was never perfect.  These points from Paul Stovell about WPF all apply to Silverlight too, and are quite valid criticisms.

“Native” web technologies have really matured, and for many business applications there now is really little need to build them on a technology like Silverlight.  There was a very steep learning curve, but I have quite happily been building applications with HTML, JavaScript, and CSS for almost 2 years now.  It has its ups and downs sometimes, but then again so did working with Silverlight!  JavaScript application frameworks have now come of age, though they are still very much in flux (Angular and Durandal are now in the process of merging, for example).  It really is possible to create well-structured rich business applications these days for the native web.  It’s funny, I was recently flicking through my Silverlight 5 book, and I realised how many of the topics can be handled easily in JavaScript now.  Sure, there’s a few things that only Silverlight can do, but for the most part, the native web has well and truly caught up.

I do miss the Silverlight PivotViewer control though.

Microsoft obviously had the foresight to see this, however, there was no reason why Silverlight needed to die.  All it needed was an inclusion in the product line roadmap (a minor and drawn out release schedule would have sufficed), some acknowledgement as still being an important part of the Microsoft family of products, and some continuing promotion of its value as a business application platform.  The silence from Microsoft just reinforced the consensus that Silverlight was dead.  I can’t think of a worse way to handle this scenario that could have caused any more damage than it did.

The damage that’s been caused extends far beyond just the Silverlight ecosystem.  The damage also extends to a major loss of developer faith in Microsoft as a platform provider, which can’t be understated.  This is especially important in an era when their flagship operating system (Windows 8) is struggling to gain traction, while its key competitor (Apple OS X) is surging in popularity.  Simultaneously, mobile devices and open technologies like the web are becoming more and more capable, and tying people less to Microsoft platforms.  I’ve discussed with numerous fellow developers how we’ve each lost the faith required in Microsoft to invest our personal time in their newer technologies – ultimately this will only hurt Microsoft.

My Experience in the Aftermath of Silverlight’s Demise

I lost a few things when Silverlight died.  Firstly, I lost my hard won standing in the developer community – suddenly nobody was really interested in what I had to say any more.  I had been running the Silverlight Designer and Developer Network, but numbers fell away rapidly, until it was no longer viable.  I refocused on building WPF applications, and eventually onto HTML5 applications.  WPF wasn’t being advanced, so there wasn’t a lot to talk about there, and I was far too new to the web development community in order to stand up as an expert (because I wasn’t).

Boxes Of Books

Boxes Of Books

The one thing, however, that saddened me the most was what happened with my Silverlight 5 book.  My Silverlight 4 book had been well received, but I felt that I could do much better.  So I practically rewrote it (adding 200 pages in the process) for Silverlight 5.  I was (and am) so proud of what I had accomplished with that book – it is so much better than the Silverlight 4 version.  I carefully crafted something that was really well structured, well written, and would guide developers through building business applications with Silverlight without getting lost.  The few reviews I got backed that up.  If you haven’t written a book (and I typically recommend against it), it requires a massive amount of effort.  I worked 7 days a week, for 6 months on it (fitting a job in-between).  Unfortunately, it was all for nothing, as few people ended up buying the Silverlight 5 version, given that it came out after the doom and gloom hit the Silverlight ecosystem.  Sales fell flat (as happened for all Silverlight related books), and all the effort I put in was not rewarded.  As it is, most of the copies sent to me by the publisher are still sitting in the cupboard (pictured), and I don’t really know what to do with them all, as nobody wants them.  If you’re interested and are in the Sydney area, let me know – I’d be happy to give them away to anyone who will use them.

The Future of this Blog

I now plan to start posting a lot more on this blog.  I’m still focusing on business applications for the web, just the technologies used will be different.  I will throw in some posts about WPF and other topics at times, but the key focus will be on building applications using native web technologies.  One thing I’d like to do is some video tutorials, and I hope to include them as a part of many posts where appropriate.  I’ve got a lot of things to blog about (my last project alone generated 111 ideas that I noted down to blog about) – let’s see how I go getting through them!