Using HockeyApp to instrument a Visual Studio extension

Tuesday, 26 July 2016

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!

The changing state of installers

Sunday, 10 July 2016

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.

A tale of two cities

Sunday, 3 July 2016

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.

Jump on the @SSW_TV live stream and check what @DavidRGardiner has to share about #testing pic.twitter.com/P3toW2zu48

— Danijel Malik (@DanijelMalik) June 15, 2016

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!

Analysing .NET code dependencies–Visual Studio Code Maps

Thursday, 12 May 2016

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.

Dependencies

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.

Debugging

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.

Summary

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.

Analysing .NET code dependencies–NDepend

Friday, 29 April 2016

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:

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:

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.