Using Visual Studio 2010 to Collect Usage, Performance and Stability Information to Improve Software

Gabriel Torok
Preemptive Solutions

Contents

Dotfuscator Considered as a Post-Build Code Injection Platform
A Concrete Example
Take Away

In Visual Studio 2010, Dotfuscator CE’s new official name is “Dotfuscator Software Services - Community Edition”. It has been renamed to emphasize its broader focus as a post-build tool in this release. A whole new class of features and services based on code injection has been added, and it has a new look, reorganizing and simplifying the user interface to improve usability and discoverability. Finally, there are improvements on the traditional obfuscation functions you may already be using. In this article, I’d like to introduce you to the new code injection features. Using these features might just help you build better software, faster.

Dotfuscator Considered as a Post-Build Code Injection Platform

As a tool that already performs significant program analysis and applies binary code transformations, Dotfuscator is in the unique position where it can add value to an application in the post-build phase, without necessarily having to write or modify source code. For a while now, Dotfuscator PRO has had these capabilities. So I’m happy that starting with Visual Studio 2010, Dotfuscator CE is also joining the club. Dotfuscator CE can now inject the following behaviors:

  • Session tracking to determine what applications have been executed, what versions of those applications, and for how long.
  • Feature usage tracking to determine what features are being used, in what sequence, and for how long.
  • Application expiry to encode an end-of-life date, transmit alerts when applications are executed after their expiry date, and terminate expired application sessions. We call this “Shelf Life.”
  • Tamper defense to detect the execution of tampered applications, transmit incident alerts, and terminate tampered sessions.

On the server side, there is a free version of the Runtime Intelligence Services Portal at free.runtimeintelligence.com. To send session tracking, feature usage, and other notifications to the free service, just select the free endpoint as the destination for your messages when configuring Dotfuscator for injection. (I’ll show you where to do this below.) When you log in to the portal using the company ID you created, you can view the data your application is sending.

A Concrete Example

Let’s use Dotfuscator CE’s new capabilities to add feature analytics to the “hello world” sample application that comes with Dotfuscator CE. The sample application is installed by default into your %Program Files%\Microsoft Visual Studio 10.0\PreEmptive Solutions\Dotfuscator Community Edition\samples folder. Since this folder is often not writeable by normal users, I recommend creating a work area under your “Documents” folder and copying HelloWorld.exe and hello_config.xml to it. These are the input application and the associated Dotfuscator configuration file, respectively.

Once you’ve done that, launch “Dotfuscator Software Services” from the Visual Studio Tools menu and open the hello_config.xml file via Dotfuscator File->Open Project menu.

Configuring Feature Analytics

Navigate to the Instrumentation editor by clicking on the Instrumentation node on the left side navigator as shown in Figure 1.

Click on the Options tab, and then check “Enable Instrumentation” and “Send application analytics messages”. This tells Dotfuscator to inject code to gather feature usage data as your application runs.

image: Figure 1

Figure 1. Configuring Dotfuscator Feature Analytics in Visual Studio 2010

You configure the actual code injection via attributes. Attributes can be embedded in the source code using .NET custom attributes (defined in PreEmptive.Attributes.dll, located in the Dotfuscator installation folder). Alternatively, if you don’t want to modify the source code, you can use “extended attributes”, which are maintained through the Dotfuscator UI and stored in your Dotfuscator configuration file. That’s the approach we will use here.

First, we will add two attributes at the assembly level that are used to identify and aggregate messages originating from your application. Select the Attributes tab and highlight the Helloworld.exe assembly. Right-click it and select “Add Attribute” from the context menu. In the Add Attribute dialog, select both an ApplicationAttribute and a BusinessAttribute, then click OK (as shown in Figure 2).

image: Figure 2

Figure 2. Adding Application and Business Attributes at the assembly level

The BusinessAttribute has a CompanyKey, which is a unique value used to identify the creator of the application. Later, you will use this key to log in to the free Runtime Intelligence Services Portal to view your data. You can generate a new unique identifier by clicking the “…” button associated with the CompanyKey entry area. You should also set the CompanyName property to the name of the organization associated with the CompanyKey. While not required, the name is used to personalize the portal. See Figure 3 for an example.

image: Figure 3

Figure 3. The auto-generated CompanyKey is the unique identifier assigned to the application. The CompanyName, while not required, helps personalize and identify the application.

Similarly, the ApplicationAttribute has a GUID property that identifies the instrumented application. Again, click the “…” button associated with the GUID property to generate an application identifier. You can leave the other ApplicationAttributes properties blank.

Now it is time to add two attributes to the Main method, located in the HelloWorld.Hello class. Navigate to that class in the instrumentation editor’s class browser, right-click the Main method, and select Add Attribute from the context menu. Select Setup and Teardown attributes, and then click OK (as shown in Figure 4).

image: Figure 4

Figure 4. Adding Setup and Teardown attributes to the main method.

The SetupAttribute should be placed on a method called when the application starts up. When Dotfuscator runs, it injects initialization code into the tagged method. The Main method is usually a good candidate, but that isn’t required—it just needs to be a method that is executed before any messages need to be sent. To configure the SetupAttribute, the only property you need to set is the Custom Endpoint, the remote destination of all messages sent from the application. Click the “…” button to bring up the Custom Endpoint dialog, and then select “PreEmptive’s Free Runtime Intelligence Services” as the endpoint (as shown in Figure 5).

image: Figure 5

Figure 5. Selecting PreEmptive’s Free Runtime Intelligence Services as the endpoint for Runtime Intelligence messages.

The TeardownAttribute can also be placed on the Main method. In general, it should be placed on a method that is called near the end of the application’s lifecycle, after all messages have been sent. Dotfuscator injects cleanup code at the end of the tagged method. Since HelloWorld.exe is a single-threaded console application, adding the Teardown attribute to the Main method works, as code at the end of Main is executed last.

Now that we have identified the application and specified the endpoint, we can now add the usage analytics. HelloWorld is a simple application that says Hello and Goodbye—we are interested in how often those two “features” are used (stay with me here; remember, this is “hello world”!).

The “Hello” feature is implemented in the HelloWorld.Friendly.SayHello class. Navigate to the method in the instrumentation editor’s class browser. As before, right-click to bring up the Add Attribute dialog, but this time select a FeatureAttribute. FeatureAttributes tell Dotfuscator where to inject analytics-collecting code. Set the attribute’s Name property to "SayHello" (See Figure 6). The name you set here shows up in the analytics reports, so choosing a human-readable name is important. Leave the FeatureEventType property set to "Tick". This tells Dotfuscator that the feature is an “instantaneous” event as opposed to an event with a stop and start time.

image: Figure 6

Figure 6. Setting the name of the feature and the feature event type to make it easily identifiable in the portal.

Now add the same attribute to the HelloWorld.Friendly.SayGoodbye class and name this feature "SayGoodbye".

Configuration is now complete and you are ready to run Dotfuscator. Click the play button or press Ctrl-B to build the project.

Now, when you run the application, it will send messages when it starts and stops, and whenever the SayHello and SayGoodbye methods execute.

Viewing your Data

You can see your data by going to the Free Runtime Intelligence Portal at free.runtimeintelligence.com and logging in with your company key.

Once logged in, you can view your application and feature dashboards to answer questions like:

  • Which of your applications are being used the most? (Figure 7)
  • What operating systems are they running on? (Figure 8)
  • What CLR versions are they running on? (Figure 9)
  • How often are your features used? (Figure 10)

There are also tabular views of the same data for application use (Figure 11):

image: Figure 11

Figure 11. Application use can also be viewed in a tabular format.

And for feature use (Figure 12):

image: Figure 12

Figure 12. Feature usage and frequency of usage can also be viewed in a tabular format.

Take Away

You’ve seen in the example how you can use Dotfuscator Software Services CE in Visual Studio 2010 to implement what amounts to your own “Customer Experience Improvement Program” in your .NET application with just a few clicks and without writing any additional code. But I’ve just scratched the surface here: you can do lots of other things with this technology, and we will be creating a series of “how do I” videos to show some of them off. Here are some of the planned upcoming videos:

In addition, more information can be found here: