Friday, 23 December 2016

Farewell Windows Phone, Hey iPhone

I’ve had my Nokia Lumia 920 phone for just over three and a half years, and it’s starting to age. It has served me pretty well, but the screen is showing a distinct yellowing and more annoyingly if someone calls me, I need to switch to hands free mode for them to hear me. (Not always convenient if I’m in a public place like sitting on a bus!)

So I’d started thinking about what’s next. I’d already decided that as much as I love the Windows Phone interface, there’s only a limited future for those phones so a change of platform was due.

Initially I was looking at Android phones, in particular the Nexus models (figuring that they would be better supported and updated seeing as they come from Google). I was a bit concerned about a number of security vulnerabilities discovered in Android recently, and while iOS isn’t necessarily any more secure, I had been impressed with the stance Apple had taken with the FBI earlier this year. The other consideration was that the kids will all have iPads for school, so maybe iOS could make sense.

I didn’t want a huge phone, so something similar in size to the 920 would be nice. A friend recently bought an iPhone 6 and I’d helped her set it up, and I thought it looked pretty good.

So weighing all that up (combined with getting $140 store credit when I bought two iPads on Black Friday) an iPhone it is. I ended up gong with an iPhone, opting for the latest iPhone 7 model.

I placed the order on Wednesday and went in to the Apple Store here in Adelaide first thing Thursday morning to pick it up. Turns out most of the people in the queue outside the shop were for service and repairs so I was in and out in about 5 minutes. A quick visit across the road to Vodafone to get a nano SIM and job done. Because of the new SIM card, it did mean I couldn’t wait until Christmas morning to open my new present!

iPhone Screen Shot

I already had an existing Apple ID, and it has a rather complex password. It’s quite a pain to have to enter into the phone repeatedly. I soon figured out that the fingerprint reader on the phone can be used instead of having to re-enter the password, but you need to enable that as it’s turned off by default.

Next stop was to install apps. A few favourites to match those I’d used on my Lumia and a few new ones to try out.

  • Twitter
  • Facebook
  • BOM Weather
  • Skype
  • Dropbox
  • My Vodafone Australia
  • Microsoft Word/Excel/PowerPoint/OneNote/Outlook
  • Office Lens
  • Microsoft Authenticator
  • Pluralsight
  • Stocard
  • metroMATE
  • KeePass Touch
  • Feedly
  • Endomondo
  • Australian Taxation Office
  • SwiftKey Keyboard
  • Google Maps
  • Fing Network Scanner
  • Pocket Casts

Paul Thurrott has written a couple of posts for people transitioning to iOS from Windows Phone. They are informative reading:

Some app-specific notes


I used this on the Lumia, but frustratingly the Windows Phone version doesn’t have a backup/export option, so I’ll need to re-enter all my store cards. Maybe I can scan the barcodes off of the Windows Phone app directly into the iOS one?

Microsoft Authenticator

A nice two-factor authentication app. Obviously I needed to manually transfer all my accounts over. One nice thing, I can now just ‘Approve’ when my Microsoft Account needs authentication. No idea why they couldn’t do that on Windows Phone.

Australian Taxation Office

I was able to export my data from this app on Windows Phone to OneDrive and import it into the iOS version. The only thing which doesn’t transfer is any photos of receipts.

Pocket Casts

It does cost $5.99, but a) it’s created by an Adelaide company and b) it has a lot of recommendations (including Thurrott), so I splashed out on this Smile. It can import OPML files. I had one lying around on OneDrive, though it wasn’t my current list as the default Windows Phone podcast app doesn’t support exporting OPML files. Not a big drama.

So that’s my new Christmas present! Any other app suggestions for me?

Sunday, 13 November 2016

MVP Summit 2016

My MVP Summit nametagI’ve just returned from my second Microsoft MVP Summit held in Bellevue and Redmond, Washington (just outside Seattle). I had an awesome time!

I flew over on Saturday going via Brisbane and Vancouver. It was drizzly in Seattle when I arrived (not uncommon I know), but not so wet that I couldn’t spend a bit of time walking around downtown, getting a few souvenirs for the family and generally trying to stay awake as long as I could with the plan to try and go to sleep at right time. That wasn’t easy!

I’d stayed in Seattle the first night, but the summit was over at Bellevue and at Microsoft’s Redmond campus, so I caught the bus up there on Sunday.

MVPs are from all over the worldI stayed at the Bellevue Hyatt, which was very nice (and convenient as that was also where registration and some of the off-campus events were being held).

Sunday afternoon there were some optional “pre-event” workshops that I attended.

Monday through Wednesday, I attended technical sessions hosted by the various Microsoft Product Teams at Redmond Campus. These started at 8am, so I was up bright and early to grab breakfast and jump on the shuttle buses to get from Bellevue to Redmond in time.

.NET Foundation medalOne unexpected surprise was to be one of a handful of MVPs to receive a special token of appreciation for contributing to open source projects connected to the .NET Foundation.

I believe some of the technical sessions were recorded with the intention that where they don’t cover NDA content they’ll be published to Channel 9. Also, you should watch out for the Microsoft Connect() event happening this week.

Thursday was a bit different. Still an 8am start, but for my area (Visual Studio and Development Technologies), Jeff Fritz (who had been coordinating the previous three days) organised a day-long hackathon.

I joined the Visual Studio Extensions group and worked on an extension code analyzer, which can check for common mistakes when creating an extension and offer code fixes. The idea for the analyzer came about after getting some advice on another of my extensions the previous night from Mads Kristensen (Microsoft Web Tooling and Visual Studio Extension author extraordinaire) and Justin Clareburt (expat Aussie and Senior Program Manager for Visual Studio Extensibility). You can see my progress on Github. After a little bit more polish, I hope to publish the analyzer to NuGet (and yes, I even spelled it with a ‘z’ Smile )

Jeff tweeted about one of the other extensions produced at the hackathon, which integrates with the new Surface Dial. Very cool!

David playing with a HTC Vive VR headsetAnother highlight was going down to visit the Microsoft Store in the Bellevue shops and trying out the Surface Studio and having snowball fight with their HTC Vive Virtual Reality headset (photo taken by fellow MVP Alan Burchill).

Thursday night I headed home, arriving back Saturday afternoon. There were some tight connections, but staff at both Vancouver and Brisbane were able to ensure I (and my baggage) made my flights. Phew.

Special thanks to RL Solutions for supporting me attending the summit and especially for my family for allowing me to be away for the week.

Sunday, 30 October 2016

Upgrading to new “new” (ADDriverStoreAccessNonLocalException)

A few weeks ago I received an email saying that I would be upgraded to the new Then last weekend I noticed I’d stopped receiving new emails and figured the migration had begun.

My email setup is a bit unusual. I have a custom domain “” and email for this domain is handled by Google Apps Free edition (legacy). This is the version of Google Apps (now called “G Suite”) that Google no longer offers for new customers, but maintain for existing ones.

A while back when Google and Microsoft were being less than friendly about GMail support with Windows Phones (combined with a weird problem on my phone where using GMail was using unusually high cellular data), I switched to using To make this work, I configured to regularly pull email from GMail, and to send all outbound emails back through GMail too (so that SPF and DKIM would continue to work).

That setup worked well for my phone, and also for family calendar sharing (seeing as my wife Narelle had been using Hotmail for ages).

The downsides were that there appeared to be a sporadic bug with the email import process. Just occasionally emails would get ever so slightly corrupted. Most times you could still read them, but sometimes just one character changing was enough to render it completely unreadable.

I lived in hope that the migration to the new O365 infrastructure would resolve the corruption problem.

So where was the new Every time I tried to log in, I kept getting a “Sorry, something went wrong” page, and if I looked at the details of the error, it mentioned this “ADDriverStoreAccessNonLocalException”. I sent a number of tweets to @Outlook, but got zero responses (disappointing).

I figured I’d give it a few days, but then it was still saying the same thing. Eventually I stumbled across a post to the Microsoft Support Forums which suggested switching my Microsoft Account to use a different default profile. It sounded crazy, but I was willing to give it a try. And it worked!

The new now loaded in my browser in all it’s O365-like glory. Great!

New banner

I suspect the reason I might have had this problem is that I’d previously set up a real O365 account (via a free trial through being an MVP) and I’d partially configured that to use “” (without ever changing my MX records to actually deliver there). My theory is that new, being O365-based, probably could see that other half-set up system and got confused. As part of resolving this I also modified the settings on the O365 service to remove the “” domain settings.

I could then switch my default profile back to my name and things continued to work.

The new More responsive, and so far not prone to those import corruption issues. That’s great.


I noticed that the integration with my custom domain hosted on GMail was also reduced. Sending emails continued to work correctly – they’d use the GMail SMTP gateway that I’d configured in the settings. However when I went create a meeting invite, the email wasn’t sent through GMail, but directly from, and it was sent using one of the profile aliases (not my address).

The migration also seemed to have messed up my email filter rules. Ok, I’ll go in and edit them then. Well looks like there’s some bugs there as this is all I get for editing the list of email addresses for a rule:


Yes, kind of hard to edit email addresses when the text box is empty. That’s just annoying.

The other downside to this whole “pulling email from GMail into” is that it uses polling – so there’s often a delay of a few minutes, up to maybe 30 minutes between polls from back to GMail checking for new emails.

So now I’m thinking that I might move back to using GMail directly (whilst keeping an eye on phone data usage).

Sometimes an “extra layer of abstraction” doesn’t help so much.

Sunday, 23 October 2016

Adelaide CodeRetreat

Earlier this year I’d been contacted by Rachelle (Community Manager at Reinteractive) asking if I could promote a CodeRetreat Event that she was organising in Adelaide to ADNUG members. Not only was I was more than happy to do this, but I decided to go along myself and find out what it was all about.

The day-long event was held in the _southstart (formerly Majoran) office space in Grenfell St. 20 had registered, but somewhat disappointingly only 6 of us showed up (I say “somewhat” as in some ways having a smaller group actually worked better, and not just because there was more food to go around!)

The day was also facilitated by Adam Davies (who also helps run the Adelaide Ruby Meetup group). The structure of the day was based on the one from After a welcome and introduction, we paired off with another attendee, worked on implementing Conway’s Game Of Life for around 40 minutes, then all came back together as a group for a ‘retrospective’ review and discussion of how we felt that session went. This was then repeated for most of the day, with a few challenges thrown in just to make it interesting, like “only commit code to version control when all tests pass, and use a 4 minute timer that you revert all uncommitted code when the timer expires” (that one was stressful!), “ping pong” (one person writes the test, and the other has to implement the code for the test) or “avoid using a mouse”.

Most of these sessions operated in pairs and promoted using test-driven development (writing the test first, confirm that the test fails, now write the smallest amount of code to make the test pass). I really do like the practises of pair programming and TDD, and it reminded me that it would be good to use these more in everyday work.

One rule of the day was “delete all your code at the end of each session”. It was curious how ‘wrong’ that felt. You are so used to saving and keeping stuff. It was probably a bit liberating too – after all while the code had gone, the experience and learning from the pairing session had not.

Even in such a small group there was a good mix of programming languages – Ruby, Java, JavaScript, C# (obviously) and even Elm. Sitting down with a fellow developer and working in an unfamiliar language was also both a challenge and a highlight.

Lunch was provided, and was a step up from the usual pizza fare. Very nice!

After lunch we did more of a ‘mob programming’ style session lead by another attendee Richie. Still using the Game of Life problem, it was a great illustration of how important communication skills are, as we worked through coming to consensus on not only how we could approach the problem, but what were good names for things and what did those names actually mean (not surprising, considering naming is one of the two hard things in computer science).

Richie taking us through The Game of Life in Ruby

Following that we did one more pairing session. This time each pair got to choose from a list of limitations. My partner had commented when we sat down together how much he appreciated his mouse and that was probably what prompted me to suggest we try the “only use your keyboard” challenge. We used Java in Eclipse and apart from an annoying splash screen that we had to resort to the mouse to make go away, we managed the rest of the session to stick to just typing. Not easy though.

The day ended with a final group review. I really enjoyed the day, appreciated learning some new skills and practising some old ones, and getting to know a great bunch of people.

Wednesday, 19 October 2016

Installing Mono in Bash on Windows 10

I was working on a pull request to add a feature to Cake, which includes bootstrapper scripts written in PowerShell and in Bash. Ideally my PR would include changes for both scripts to keep them in feature parity. I could create a VM and install a flavour of Linux
to test out the Bash shell script. But then I remembered that since the July 2016 update, Windows 10 now has an optional Linux Subsystem, which includes a 'native' Bash shell.

Enable Developer Mode and Bash

So first off, let's get the subsystem installed and up to date. You could do this manually through Windows Settings, but I love scripting things where possible. From an elevated PowerShell prompt:

$RegistryKeyPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock"
if (-not(Test-Path -Path $RegistryKeyPath)) {
    New-Item -Path $RegistryKeyPath -ItemType Directory -Force

# Add registry value to enable Developer Mode
New-ItemProperty -Path $RegistryKeyPath -Name AllowDevelopmentWithoutDevLicense -PropertyType DWORD -Value 1

Restart Windows, then open an elevated PowerShell prompt again:

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

Reboot again.

Now, type in 'Bash' and launch the Bash shell. The first time, you'll be prompted to enter a separate username/password. It's a good idea to make sure all the components are current.

Run the following to download and install any package updates:

sudo apt-get upgrade

Installing Mono

Cake currently uses Mono when run on Linux or MacOS (apparently .NET Core support is in the works). There's one trick regarding Mono running in Bash on Windows 10 - the build that works correctly is 4.2.4 (See the discussion on this Github issue

First up, add the key for the Mono project:

sudo apt-key adv --keyserver hkp:// --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF

And now download and install Mono 4.2.4 and related tools:

sudo sh -c 'echo "deb wheezy/snapshots/4.2.4 main">>/etc/apt/sources.list.d/mono-xamarin.list;apt-get -qq update;apt-get -qq install git gcc mono-complete'

I found after this, this easiest thing was to exit Bash and then open it again. Now I could use Cake's script which could successfully use Mono to run nuget.exe and cake.exe!

Saturday, 20 August 2016

DDD Melbourne 2016

Sign for Monash UniversityLast weekend I was privileged to be able to attend my second DDD Melbourne conference. I flew over Friday afternoon and had an uneventful transit from Melbourne airport to the motel, via the Skybus and a train connection. I stayed locally near Monash University’s Caufield campus, the venue for this year’s event.

Welcome and intro to DDD Melbourne

Around 350 people were there. Monash was a great venue, with all lecture theatres having excellent AV facilities, so no problems watching presentations or hearing speakers. It was also really nice to catch up with a few familiar faces.

Paul Fenwick with slide of 1970's sci fi robotsThe day started with a thought-provoking keynote from Paul Fenwick, making us stop and think about what kind of future we’re creating. That slide with the strange robots – I had that book as a child! Smile
Morning tea break

After that I caught the following sessions:

  • Thinking in React with Mohammad Helmy
  • Deploying Straight to Production: A Guide to the Holy Grail with Damian Brady
  • The Actor/Model pattern in .NET: Akka.Net vs Orleans for the curious with William Tulloch
  • Better APIs with GraphQL with Josh Price

Lunch break

After lunch I also got to present 10 tools and libraries to enhance .NET Unit Testing.

Audience before closing presentationThe final talk for the day was from Shawn Wildermuth. An inspiring and personal look into the life of a developer, and a great way to end the day.

Shawn talking about active listeningOne key point Shawn made was how critical it is if you want to be a good developer, is to really work in your listening skills – not just “hearing” but actual ‘active listening’, because as it turns out, good communication skills are more important that good technical skills.


And with that DDD Melbourne was over for another year. Off to the airport for the flight back home late Saturday night to be back at home with family and my own bed.

Tuesday, 9 August 2016

NDC Sydney 2016 Reflections

Now that I’m home again, it’s a good opportunity to think back over the last week. What were the highlights, lowlights of attending the first NDC conference held in the southern hemisphere?


WOW!. I had a great time, learned a lot, really enjoyed the sessions as well as meeting and chatting to lots of other developers. I’ll say it again.. WOW Smile

Depth of speakers

Scott Hanselman's opening keynoteThere were a lot of “big name” international speakers. I was going to name some, but that’s not really fair. Go have a look at the list.

That is definitely a plus. You don’t get many opportunities to see these people in Australia, let alone all in the one place. And not to mention the quality local talent.

A nice variety of presentations, and a chance to talk to all these people (and in my case asking “would you be interested in doing a Skype talk to our user group in Adelaide?”, to which the answer was almost always “yeah, sure I’d love to do that”.

The other nice thing is that even though you might regard some of them as having “celebrity” status in the software development (or even just the Microsoft software development) realm, the reality is that I didn’t find anyone who was so caught up in their own ‘fame’. They’re just regular people – they only have walk outside the conference to get a reality check if there was any doubt. No one walking past would have any clue who they were Smile


Sydney Hilton was excellent. Great rooms, helpful staff, yummy food. Full marks.


Rain on the windowIt was wet. I guess that’s the risk of holding a conference in early August – you’re going to catch a bit of Wintery weather sometimes. Not an issue for the conference itself, but maybe a little disappointing for foreign speakers who were hoping to do a bit of sight seeing during their visit.

Common trends and themes

There wasn’t a specific theme for the conference, but I did notice some topics that came up a few times in the presentations. In particular some that stood out to me were:

  • Micro services
  • F# and functional programming
  • Don’t get hung up on chasing new stuff all the time

Volunteer crew

Volunteers at the registration deskIt is quite an easy job –

  • Get rostered to look after a particular breakout room for half day blocks.
  • Pass around a cordless microphone for attendees to ask questions (so questions get picked up in the session recordings)
  • Count all the eval votes after each session and give the totals to Information Desk.

For doing this you get to attend the conference and participate in all the activities for free (and get a couple of bright green ‘CREW’ t-shirts).

Voting slipsThere weren’t enough volunteers (a few apparently failed to turn up), which meant extra shifts for the rest of us. Hopefully next time there are enough so that everyone gets a fair share of shifts and free sessions.

Session recordings

In the next few weeks, expect to see all of the sessions uploaded to Vimeo at

Next year

The dates have already been announced - 14-18th August, 2017. Mark your diary, talk to your boss, manager, colleagues, social secretary and/or spouse. This is THE developer event in Australia.

I hope to be there again next year, and I hope you will be too!

Saturday, 6 August 2016

NDC Sydney–Day 3

Friday, the final day of NDC Sydney. I was rostered in Room 2 all day, so got to see these speakers/presentations:

And then a late flight home to Adelaide Friday night.

Thursday, 4 August 2016

NDC Sydney–Day 2

Thursday sees me spending rostered the entire day in room 1. This was actually my preference, as the majority of the talks were already on my wish list. One slightly ‘down’ side of doing room 1 is that the bigger crowds mean counting much larger numbers of eval votes after each session.

The evening finished off with a hilarious talk from Assoc. Prof. James Mickens, followed by a social evening of food and drinks in the hotel bar – a good chance to meet and chat with other attendees.

One more day to go!

NDC Sydney–Day 1

The first full day started with Scott Hanselman’s keynote, then straight into sessions. I was rostered to look after room in the morning, with the afternoon free to attend other sessions.

Here’s my photo tweet stream from the day:

I had a quiet night back in the hotel room, though many attendees went on a harbour cruise. It had been quite wet and rainy, so I didn’t mind missing out on that.

Wednesday, 3 August 2016

NDC Sydney–Day 0

Cloud view of Sydney HarbourIt’s Tuesday, so off to NDC Sydney conference. I must say 11am is a very sensible time to fly from Adelaide to Sydney. Makes a nice change from 6am flights!

George St looking towards Hilton HotelI’m attending NDC as a volunteer crew member, but it turns out the organisers were extra-pleased to see me, as they’d forgotten that I was coming, and were actually short of helpers. Phew, glad that worked out well.

NDC is being held at the Sydney Hilton. I’ve actually been here many years ago attending a SharePoint conference. I wasn’t originally going to stay here on-site, but my employer (RL Solutions) encouraged me to do so and I’m really glad I did. It is super convenient to just be able to “pop upstairs” to my room.
Code Club registration badgeI started right away, helping out with the registration desk for the NDC Sydney Code Club, an evening of workshops for kids aged 7-16. It was great to see some of the conference speakers had brought their families over to Australia and so their kids got a chance to participate, as well as a bunch of Sydney school kids.
As a bonus, they had Scott Hanselman as their keynote speaker. I’m pleased to report the kids enjoyed Scott just as much as the adults will at the rest of the conference. Scott was entertaining and informative. I could hear lots of laughter coming from the room. After Scott’s welcome keynote, there were a number of workshops the kids participated in, including IoT, Minecraft and other fun stuff.

Here’s photo of Scott enjoying the perks of working for Microsoft (well I think that’s what he said!) from his welcome talk to the kids:

 Not really Scott Hanselman

Monday, 1 August 2016

Error AD0001: Compiler Analyzer … threw an exception of type 'System.InvalidOperationException' with message 'Feature 'IOperation' is disabled.'

If you upgrade to the latest beta release of one of the Roslyn compiler analyzer packages, you might notice they fail with an error like this:
Compiler Analyzer 'Microsoft.ApiDesignGuidelines.Analyzers.UsePropertiesWhereAppropriateAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'Feature 'IOperation' is disabled.'.
The solution wasn’t immediately obvious to me, but I eventually tracked down this comment on a Github issue. According to the comment, the analyzers are using an API that needs to be enabled through configuration. To do this, you need open up the .csproj file and add a new property as a child of the first PropertyGroup element like this:

  <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>  
  <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>  

Or if you have lots of projects, run this PowerShell script to update them all:

Get-ChildItem *.csproj -Recurse | ForEach-Object {   
    $content = [xml] (Get-Content $_) 
    $xmlNameSpace = new-object System.Xml.XmlNamespaceManager($content.NameTable)   
    $xmlNameSpace.AddNamespace("p", "")
    if (-not $content.Project.PropertyGroup[0].Features) {    
        Write-Host "Features missing in $_"
        $featureElt = $content.CreateElement("Features", "")    


    # Normalise line endings    
    (Get-Content $_ -Encoding UTF8) | Set-Content $_ -Encoding UTF8

Saturday, 30 July 2016

What HockeyApp told me about my Visual Studio extension

Last time I wrote about how I managed to incorporate HockeyApp into a new Visual Studio extension I’ve created. Well I published the updated extension a couple of days ago and HockeyApp is already paying dividends.

Here’s the info from HockeyApp at the time of writing:

Build Number



Last Updated



29 Jul 2016, 10:15



26 Jul 2016, 21:54

HockeyApp can provide a way to deploy applications, but that isn’t relevant to Visual Studio extensions, which is why the ‘Downloads’ column is zero. So you can see there’s a bunch of crashes (aka exceptions) that my extension is experiencing. Now I’m pretty sure that these wouldn’t be really crashing Visual Studio, but they would be affecting how well the extension works.

There’s now a number of issues created in the Github repo for me to review:

A bit of work for me to do now Smile Hopefully not too much - I suspect a few of can all be handled in a similar way. Interesting too to see all the different ways your own code can interact with other parts of both Visual Studio and other extensions!

Actually after a bit of investigation, I have a theory that most of these exceptions are nothing to do with me. When I configured HockeyApp, I used the RegisterDefaultUnobservedTaskExceptionHandler(). I suspect this was causing HockeyApp to capture any unobserved Task exception that happened in Visual Studio – not just relating to my extension. I guess if there was a way to get HockeyApp to include only those exceptions based on the extension's namespace that would be more useful.

Tuesday, 26 July 2016

Using HockeyApp to instrument a Visual Studio extension

I’m working on a new Visual Studio extension and I wanted to include some automatic analytics/crash reporting. Previously I would have looked at Visual Studio Application Insights, but over the last few months Microsoft have been transitioning developers of mobile and desktop apps to use their HockeyApp platform.

Assuming you’ve signed up for HockeyApp (or as in my case, had an existing Insights app on Azure that was migrated over to HockeyApp), you are ready to start using HockeyApp.

There is a choice of NuGet packages to choose from, depending on the kind of application you’re building. Nothing specifically for a Visual Studio extension, so the next best fit seemed to be HockeySDK.WPF. After all, Visual Studio has WPF in it, so that should work, right?

Not quite. The WPF package really assumes that you’ve got your own complete WPF application, not just an extension assembly being hosted in another application.

I encountered a couple of issues.

TrackException vs HandleException

The HockeyClient.Current property exposes an IHockeyClient interface. Browsing through the methods exposed on this interface I noticed TrackException. Perfect, I’ll use that in a few strategic try/catch blocks in the application. Just to test things, I added a throw new InvalidOperationException().

Running the extension under the debugger gave a surprise – I was getting a KeyNotFoundException being thrown from inside that TrackException method call!

A request for help from the HockeyApp forums pointed me in the right direction. There’s a WPF sample on Github. Reviewing the source code there revealed that they’re using a HandleException method which exists on HockeyClient, but not on IHockeyClient. Ok, let’s use that then, and we’re all good right?

NullReferenceException in HockeyPlatformHelperWPF.get_AppVersion

Not quite, again!

This time, I was getting another exception being thrown inside the HockeyPlatformHelperWPF.AppVersion property getter. The SDK itself is also on Github, I had a look at the property body. Curiously most of it was already in a try/catch, so I suspected the part not working was in the actual catch block:

catch (Exception) { }
    //Excecuting Assembly
    _appVersion = Assembly.GetCallingAssembly().GetName().Version.ToString();

Again, because we’re being hosted in another app, the code isn’t finding things as it was expecting. Fortunately it turns out that this code is only run if a field is null, otherwise it just uses the existing cached field value. Unfortunately there isn’t a public setter for that field, so reflection is the only option. Yes, it’s a bit dirty, but it gets the job done.

I added this code directly after I called HockeyClient.Current.Configure():

var hockeyClient = (HockeyClient)HockeyClient.Current;
var helper = new HockeyPlatformHelperWPF();

var crashLogInfo = new CrashLogInformation()
    PackageName = helper.AppPackageName,
    OperatingSystem = helper.OSPlatform,
    Windows = hockeyClient.OsVersion,
    Manufacturer = helper.Manufacturer,
    Model = helper.Model,
    ProductID = helper.ProductID,
    Version = Assembly.GetExecutingAssembly().GetName().Version.ToString()

var field = typeof(HockeyClient).GetField("_crashLogInfo", BindingFlags.NonPublic | BindingFlags.Instance);

field.SetValue(hockeyClient, crashLogInfo);

This code almost completely replicates the functionality found in the HockeyClient.PrefilledCrashLogInfo property, with the exception (ha ha) of the value assigned to Version. Because this code is now part of our extension assembly, I just use GetExecutingAssembly() instead of GetCallingAssembly().

With these changes made, I’m pleased to report that my InvalidOperationException was properly reported and now appears in HockeyApp. Even nicer, because I configured HockeyApp to talk to Github, it automatically created an issue in my extension’s Github repository.

Very nice!

Sunday, 10 July 2016

The changing state of installers

I’ve begun to notice that there’s somewhat of a gradual move away from MSI-style installers. This is an interesting change considering for a number of years now I’ve been a keen proponent of creating an MSI to package up your software and drive the installation process during deployment.

MSI (Windows Installer – previously Microsoft Installer) started life as the Office 2000 installer. Office was (and still is) quite a large and complex piece of software and I guess the development team realised they needed a slightly more reliable way to install all the bits in the right places.

This then evolved into a more general-purpose installer technology and was finally built right in to Windows itself as the preferred way to install applications and services.

So what’s changed?

MSI is great if you just need to install a single instance of an application. It is possible to handle multiple instances – for example SQL Server. If you’ve ever installed SQL you’ll know that you can use the setup program to install multiple instance of SQL Server. I recently learned through a question posed to a Reddit AMA that they use ‘Transforms’ for this. It is possible, but not super easy.

Then there’s Nano – Nano Server to be precise. This is the new super cut-down, minimalist edition of Windows Server, and one of the things that has been left out to keep it as lean as possible is MSI support. To build software for Nano, you’ll be packaging it up in an ‘appx’ file (essentially the same package used for Windows 8/10 UWP).

So who’s changed?

I noticed that JetBrains went to a non-MSI installer with their ReSharper 9.x release. They were already using NuGet packages for managing extensions. I think they’ve kind of gone the whole way with their installer now.

It also appears that Visual Studio “15” (not to be confused with the current 2015 release which is version 14) is moving to a non-MSI installer as part of reducing the install process.

ASP.NET for a while now has had the ‘msdeploy’ packaging. It’s what is used when you choose ‘Publish’ from the context menu in Visual Studio.

So what now?

MSI still has a role, especially for traditional server deployments, but if you want to support deployments to Nano then you’ll need to look at appx. If you have a desktop app that you’d like to feature in the Windows Store, then appx is also a requirement.

There’s currently a couple of options if you want to move towards appx deployments:

Project Centennial – aka the Desktop Converter for Win32 or .NET 4.6.1 apps. This is currently in preview (and requires that you run on a preview release of Windows 10).

WiX AppX Extension – a commercial product created by some of the main WiX developers that lets you leverage your existing WiX projects to produce an Appx package.

Sunday, 3 July 2016

A tale of two cities

Last month I was delighted to be able to speak at the Sydney .NET User Group on “Enhancing .NET Unit Tests”. Thanks to group leader Adam Cogan for hosting a great meeting. If you’re in Sydney or passing through then I’d definitely recommend dropping in. If you can’t get there in person, they also live-stream the user group meetings as well as publish the recordings to YouTube.

NDC Sydney had around 600 submissions for only 125 sessions, so I didn’t feel so bad when I heard my session proposal had missed out. I do think this is going to be one of the biggest developer conferences Australia has ever seen, so I was still really keen to get there somehow. When I was offered the chance to go as a volunteer crew member, I jumped at the opportunity. I’ll work half the time helping at the conference, and the remaining time I’ll be able to attend sessions.

Here’s the recording from my Sydney .NET talk..

But you may not need to watch if you’re going to DDD Melbourne! It’s on Saturday 13th August (a week after NDC Sydney), and I just heard that my session has been accepted! I’ll be presenting “10 tools and libraries to enhance .NET unit testing” – which is going to be quite similar to the talk above, so come along and see it live Smile Apparently DDD Melbourne is a sell-out again, so it should be a great day.

August is going to be a busy month!

Thursday, 12 May 2016

Analysing .NET code dependencies–Visual Studio Code Maps

This is the second in a series of posts on reviewing tools to help analyse code dependencies in .NET

Code Maps is a feature that was first included in Visual Studio 2012 Ultimate. It remains an Enterprise-only feature in 2015, though Professional and Community editions can view previously created diagrams.

Code Maps operate from the cross-project solution level right down to the method level.


To generate a map of project dependencies, go to the Architecture menu, and choose Generate Code Map for Solution.

A new window opens and gradually items appear on the diagram. Usually this will trigger a build of the solution, and then the analysis process will run, eventually displaying the dependencies between the projects.

Code Maps - Solution

If your solution uses solution folders to group similar projects, then you’ll see that represented in the diagram (the OLW solution doesn’t currently do this).

You can then expand this out by selecting all the nodes (Ctrl-A) and choosing Group, Expand from the context menu.

Code Maps - Solution expanded with externals highlighted

You can see two things – the OpenLiveWriter.PostEditor project seems to be the most significant project, and also there’s an ‘Externals’ block with all external assembly references. To just focus on strictly code from the solution, you can select this group and press Delete. This removes it from the diagram.

Editing a Code Map diagram doesn’t mess with your source code, as the diagrams are a bit like a snapshot of your code at the time they were created. In some ways this is a limitation, but one positive aspect is that you can use Code Map diagrams to model or prototype changes to the class hierarchy and dependencies without having to commit those changes in code.

Let’s focus in on the PostEditor project. If we select that node, we can choose New Graph from the context menu. A separate diagram is now displayed with just the contents of the previously selected node. You can use the Filters tool window to select which elements you want to display. I de-selected Assembly so that I can now focus on the namespaces.

Code Maps - HtmlEditor assembly classes

Let’s keep going further in. Select the OpenLiveWriter.PostEditor namespace, and open this in a new graph again. To drill down to the class level, select all nodes again (Ctrl-A) and choose Group, Expand again.

Code Maps - OpenLiveWriter.HtmlEditor namespace classes

Let’s click on that top node – BlogPostEditingManager. Repeating the same process again, and filtering down to just methods, we get the following:

Code Maps - BlogPostEditingManager Methods

We now have a call graph of the methods inside the class. I also changed the layout for this graph to be ‘left to right’. The two blue nodes represent classes defined inside this class.

Usually, you’d expect to see public methods on the left, and non-public methods going to the right. Unfortunately there’s no way distinguish between them apart from hovering over a node and reading the tooltip that appears, or by selecting a node and reviewing the details in the Properties window.


You can also display Code Maps while debugging. If you have stopped at a breakpoint, you can right-click and select Show Call Stack on Code Map.

Code Maps - Call stack

Basically just a different way see the same info that gets displayed in the Call Stack debugging window, and unless I’ve missed something obvious, I think I’ll stick with the latter.


That’s a quick overview of some of the things that Code Maps can show you. They are entirely visual, so unlike NDepend, there’s no way to do any custom querying out of the box. On the other hand, the fact that the diagrams use DGML (directed graph markup language), it would be possible to write code that queried the file directly.

Friday, 29 April 2016

Analysing .NET code dependencies–NDepend

This is the first in a series of posts on reviewing tools for analysing .NET code dependencies.

I last wrote about NDepend briefly four years ago, and with a bit more detail way back in 2010. Some of the features added since then include:

  • Support for Visual Studio 2013 and 2015
    • Now a proper VSIX extension (v6)
    • NDepend project can be included in VS solution.
  • New Dashboard Panel – state of your code base at a glance
  • Focus on recent rules violations – only show rule violations on added/modified code
  • UI enhancements – improved menus
  • Better path management – UNC paths and support for environment and MSBuild variables.
  • Windows Store and Windows Phone support – honours the TypeForwardedToAttribute
  • Trend monitoring – monitor trend metrics and view via trend charts
  • Share rules between projects
  • Rules
    • Rule descriptions and fix suggestions added
    • Reduction in false positive detection
  • TFS integration
    • 2013 (2015 is coming)
  • SonarQube integration
  • TeamCity integration
  • Report enhancements – report includes trend metric charts
  • More console options – additional parameters to support file and directory variables.
  • Coloured Code Metric view – treemap elements can be coloured to indicate second metric
  • Code coverage shown with red/green colouring
  • Improved handling of compiler-generated code
  • Async support
  • High DPI support
  • Visual Studio theme support

So let’s take NDepend v6 for a spin and see what it can do.

I’m going to use the Open Live Writer code base for these reviews. The writer.sln contains 28 projects and around 3,000 types.

The OLW solution is special in that most projects point to the same single output folder. As a result you might have to tell NDepend to look in this output directory rather than just relying on it to examine the solution’s projects. Once the assemblies are selected, the analysis begins.

Analysis might take a minute or two, but when it finishes you are prompted to view the results. I chose the Dashboard view:

NDepend Dashboard view

To dig into the dependencies, let’s look at some useful diagrams. First up, the Dependency Graph. Go to NDepend, Graph, View Application Assemblies Only.

Assembly dependency graph

By default, the size of each ‘node’ indicates the relative number of IL instructions in that assembly. From the graph above, it’s obvious that OpenLiveWriter.PostEditor is the largest assembly. That sounds reasonable given that OLW is all about editing posts.

Switching to the Matrix, here again is the ‘Application Assemblies Only’ view:

Matrix View of Dependencies

The intersections where there are 0 methods used from the assembly reference bear further investigation. Sometimes there might be a valid reason, but quite often this represents an unnecessary assembly reference that can be removed.

The query language is very powerful. I’d like to find assemblies that are only referenced by one other assembly. Matching assemblies could be candidates for merging with the parent assembly if there’s no good reason for keeping them separate.

I came up with this custom query:

from m in Assemblies.ExceptThirdParty()
where m.AssembliesUsingMe.Count() == 1
select new { Parent = m.AssembliesUsingMe.First() , Child = m}

Which returned the following results:

  • OpenLiveWriter.FileDestinations
  • OpenLiveWriter.HtmlEditor
  • OpenLiveWriter.InternalWriterPlugin

Are all referenced only by OpenLiveWriter.PostEditor. That’s useful to know.

Jumping back to the dashboard, let’s drill in to see some of those “Critical Rules Violated”. Clicking on this heading in the dashboard opens the Queries and Rules Explorer, with the “14 Critical Rules Violated” filter selected.

Selecting the top item in the list opens the Queries and Rules Edit window, with the top half showing the actual query that was used to search for the violations and the bottom half showing a tree of matches for this rule (in this case it’s the offending methods). So that Init() method takes 15 parameters. Maybe that’s ok, maybe not.

NDepend Queries and Rules Edit

I love digging around the results of these kinds of rule queries. Particularly the ones around potential dead code, where you end up identifying and removing code that isn’t being used anymore.

NDepend has really progressed over the years. It’s particularly nice to see the improved integration with Visual Studio. Ideally every developer would have NDepend in their toolbox to use themselves, but a first step is probably including it as part of your build pipeline. That way, at least everyone can view the reports it generates as part of the build results.

Analysing .NET code dependencies–Overview

How can you tell if modules/components in your application are loosely-coupled between each other, and tightly cohesive internally? You could read the code line-by-line, but that becomes difficult once the codebase becomes large.

It can be very valuable to be able to visualise the the dependencies between the various components that make up your application – both at the class and module/assembly level. These tools analyse code, either by parsing the source code, or by analysing the compiled assemblies to produce various summaries and reports about the state of the code.

I’m planning to spend a bit of time in future blog posts reviewing a number of these tools that can help with this analysis, including:

I’m also interested to hear what you use. Let me know in the comments of your experiences with these or other tools I haven’t mentioned.

Monday, 11 April 2016

My new Dell XPS 15 laptop

My birthday has come early this year. I've finally bought a new laptop! It wasn’t the cheapest either, so I think that will cover a couple more birthdays in the future too Smile

I'd been evaluating a number of different manufacturers and models, and eventually went with a Dell XPS 15 (9550). I'd had a pretty good run with my old XPS 1645 and that counted in the XPS 15's favour.

I bought the 1645 in 2010, so I was expecting to buy something that represented 6 years of technology improvements. So far I think the 15 delivers that.

  • 16GB DDR4
  • 512GB SSD (PCIe)
  • 4K Ultra HD (3840 x 2160) touch display


Out of the box, the top row of the keyboard defaults to the feature keys. I make use of the Function keys (F1, F2, etc) much more than I'd use the feature keys (Mute, Volume Up/Down, etc) so I went into the UEFI firmware settings and changed that to default to function keys.

Here’s a comparison of the keyboards of the 1645 and 15 (the shiny strip above the main keyboard on the 1645 has the feature keys). Obviously fashions change too – from glossy/shiny to matte.

XPS 1645 KeyboardXPS 15 keyboard

I HATE touchpads that simulate a mouse click with a single tap. Maybe it's my hands but I find I end up 'clicking' a lot more than I intended. So it's another thing I try to disable if possible. On the 1645 this was done through the Synaptics touchpad driver, but that isn't present on the 15. Instead it turns out that's a setting provided by Windows itself.

Windows 10 Touchpad settings

Old and new comparison

XPS 15 and 1645 closedXPS 15 and 1645 open

Here’s the 15 sitting on top of the 1645, to show it’s slightly smaller.

View from above of XPS 15 sitting on top of 1645

Side views show the 15 is a fair bit slimmer. The 1645 comes with VGA, HDMI and DisplayPort ports – the 15 just has a single HDMI, but you can get an external adapter with a second HDMI and VGA (as well as extra USB and Ethernet). No DVD drive in the 15 either!

XPS 15 and 1645 right side comparisonXPS 15 and 1645 - left side comparison

The rubber feet of the 1645 fell off a while ago – both the ones on the base of the laptop and the ones fixed to the battery bar. The 15 has two rubber strips. Time will tell if they last longer.

XPS 1645 underneath - worn feetXPS 15 - underneath showing rubber feet strips

My 1645 weighs 3.065kg. I’m pleased to see the 15 weighs only 2.040kg. (For those days when I need to carry it around, my back is also pleased!)

XPS 1645 Weight - 3.065KGXPS 15 2.040kg

It’s not easy to show the difference in displays, but this gives you a bit of an idea of the 4K display of the 15 next to the standard 1080 of the 1645. It doesn’t show up here, but the 1645 screen also got quite scratched over the years from rubbing against the keyboard. Probably made worse from the extra rubber pads falling off that should have prevented this. I’m looking into getting a protective cloth for the new laptop to try and reduce the chance of that happening again.
Comparing the displays of 15 and 1645

And check out the disk performance – almost 10x faster with the PCIe SSD – nice!

HDTune Benchmark Crucial CT512MX1 SSD - Average 111 MB/secHDTune Benchmark NVMe THNSN5512GPU7_NV - Average 897 MB/sec

Finally, I’d forgotten what it was like to have a battery that holds a decent amount of charge (the 1645 might say it has 1:45 left, but that’s pretty optimistic). I can sit on the sofa with the XPS 15 and it lasts the whole evening. Wow Smile

dell xps 1645 batteryDell XPS 15 Battery