Viewing Disassembled IL with ILDASM

For those of you who are simply computer geeks I present to you an easy way to view the generated intermediate language code that is generated when you’re using the .NET Framework. So if you’ve ever wanted to see what is generated from your compiler, so you can see what code gets executed at run-time you just need to take a few simple steps.

Open up the Visual Studio Command Prompt. You can find this command prompt in the Start Menu inside of the tools folder for Visual Studio.

VS-Command-Prompt

From here you will be able to open up ILDASM’s graphical user interface. Open it by typing “ILDASM”. It’s a very simple program.

ILDASM-Start

From here you will want to open up the assembled file you want to view. This could be a class library or an executable. In this example I will use a “Hello World” console application.

ILDASM-Project-Open

The console application really only has one class. ILDASM_World.Program, which can be seen in the image. You can see the ILDASM_World namespace is where the class is located. Inside of the class we have a constructor (this is the default one I did not write the code for it). See this is neat, because we can see that a default constructor was created for us and we can see exactly what it does.

The Main method listed there is a standard one with a Console.Writeline(“Hello World!”); line written in it.

When we open up the method to view it we see the following IL is generated when we compile.

ILDASM-Main

Now what is really cool here is that I bet pretty much every person reading this can figure out exactly what that code is doing. I think that people could have figured it out without my having to explain it. It is really cool to see. There are a lot of awesome tricks you can see here. Also if you’re ever wondering what is going to happen when you compile something I recommend looking here. You’ll be able to see exactly what actually happens.

This will assist you when you’re writing your code since you’ll be able to make a more educated decision on which approach to take with your code if you see what will be generated behind the scenes.

Your homework is to try this with loops and with a goto.

Overloading Implicit Conversions with Generics in C#

Overloading operators in a language is an excellent tool in every developer’s tool belt. It allows us to design our code in ways feeling far more natural. For example if we didn’t implement operator overloading for addition of numbers we would have some strange code. Could you imagine if we still wrote this kind of stuff?

int x = 5;
int y = 4;
int z = x.Add(y);

When we teach addition the non-computer way we learn it as “5 + 4 = 9”. The language reverses things and we switch the expression into “9 = 5 + 4”, but this is no big deal since we’re still using our operators. Some things happen behind the scenes so often we really don’t even think about them. Implicit conversions of numbers happens all the time. If we have a method that returns an integer we can certainly assign that value to a double. Why? Since we don’t lose any information doing that conversion it is just able to happen. We know that it is easy to store an integer value in a double so it is allowed.

One thing that I’ve always loved about the Nullable objects in C# is their ability to trick many of their newer users. A lot of people really don’t know about Nullable objects. I think they are fooled by the type? syntax into thinking it is something special. When the only thing special is the syntax. Beneath the surface we are actually just using Nullable<type>. My favorite part about the object is that they were nice enough to overload the implicit conversion from your type T into the Nullable<T>. The nullable object is just a cleverly hidden use of C# generics.

If you use .NET Reflector to examine the code for their implementation you will see this method.

public static implicit operator T?(T value)
{
    return new T?(value);
}

 

Sure that seems kind of boring. This is basically like a constructor in that it creates a new instance of the Nullable type and accepts an object of type T. The power comes from the fact that the user doesn’t need to realize he is changing types. It lets us do this.

int regularInteger = 3
int? nullableInteger = regularInteger;

 

Now to make things a little bit clearer I will change how their operator works so we don’t use their “?” shorthand. We will qualify things in the code so it is clear how the generic is working for us.

public static implicit operator Nullable<T>(T value)
{
    return new Nullable<T>(value);
}

 

So now if you want to use this for your generic object you can do the same thing as above. All you need is a constructor for your object that takes in a value of T, and then you write this method with your class name instead of Nullable. There is one thing to keep in mind though. There is one thing that could catch you off guard if your generic object contains state. That is that using this operator will create a new object.

If your generic is being exposed using a property, Value, like with Nullable then you could just set Value equal to the object. That approach is not as elegant, so if you can avoid having to set the value of the Value property I recommend it.

You can also perform an implicit conversion the other way, but that can potentially lose information if your object has state. If it does not then it is safe to perform that one. To achieve it just switch things around so you have this instead.

public static implicit operator T(Nullable<T> value)
{
    return value.Value;
}

So have fun assigning objects to the implicitly-converting, generic objects.

If you have questions or concerns or you just plain think I am wrong. Tell me about it! :-)

Build OpenAccess Project Using MSBuild on a Machine Without OpenAccess Installed

OpenAccess ORM is a powerful ORM tool that integrates very well into Visual Studio. It uses wizards and is tightly integrated, which makes it easy to pick up and start using. However, this same asset also provides a challenge when using this tool along with MSBuild on a machine without OpenAccess installed. There are some adjustments that needs to be made, since it is designed to be used with Visual Studio, so we have to add a couple of extra bits to get MSBuild to be able to build a project correctly.

So if you’re using the OpenAccess ORM tool and you want to use a build server you’ll need to make a couple of configuration changes to allow you to achieve this. Since I use a continuous integration server on pretty much every project I work on, I ran into this issue. There are a few things you need to do to get this working.

The first step to getting this working is to get the required dlls copied to a local directory. This is important because the build server will need to have these references for the project. To get these files all you need to do is look to see where the reference is coming from in your projects. In my case the location is.

C:\Program Files (x86)\Telerik\OpenAccess ORM\bin

So I copied the files being referenced by my project from here and put them into a lib folder in a relative directory for my project. I then removed all of the references to the libraries in their install directories and added the references back in this time pointing to the local directory.

AddLocalReferences

Once you have everything local you’ll want to make sure you got all of the required libraries by building your solution. The build should succeed.

When working with OpenAccess, it is important to know that the assembly used for persistence is going to be Enhanced by OpenAccess ORM. After Visual Studio builds that project it kicks off VEnhance.exe to inject IL into the library with added functionality.

This is the step that we next need to add in to our build so that we can achieve the desired result.

Find the VEnhance.exe file on your development machine. It should be located in a directory similar to this one.

C:\Program Files (x86)\Telerik\OpenAccess ORM\sdk

Copy that directory somewhere local to your project. We will need it in a minute. You also need to copy your Telerik.OpenAccess.dll into the local directory you created with the VEnhance.exe file. The executable will need that dll to be there in order for it to do the enhancement.

We will need to create a targets file which we will import into our project file. You can copy the one I have listed here and customize it to your needs. It is basically just the instructions to tell your project how to call the VEnhance executable. You will need to change the relative directory to your OpenAccessToolsDirectory in this targets file to reflect where you put the VEnhance.exe file.

enahnce.targets

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <PropertyGroup>
   <OpenAccessToolsDirectory>$(SolutionDir)..\util\Telerik</OpenAccessToolsDirectory>
</PropertyGroup>
 
 <Target Name="EnhanceAssembly" Condition="'$(_AssemblyTimestampBeforeCompile)'!='$(_AssemblyTimestampAfterCompile)'">
   <Copy SourceFiles="$(TargetPath)" DestinationFiles ="$(TargetPath).notenhanced"/>
   <Copy SourceFiles="$(PdbFile)" DestinationFiles ="$(PdbFile).notenhanced"/>
   <Exec IgnoreExitCode="false"
         WorkingDirectory="$(TargetDir)"
         Command="&quot;$(OpenAccessToolsDirectory)\venhance.exe&quot; -verboseMode:1 -signAssembly &quot;-keyFile:$(ProjectDir)$(AssemblyOriginatorKeyFile)&quot; &quot;-assembly:$(TargetPath)&quot;"
         Condition="'$(AssemblyOriginatorKeyFile)'!=''" />
   <Exec IgnoreExitCode="false"
         WorkingDirectory="$(TargetDir)"
         Command="&quot;$(OpenAccessToolsDirectory)\venhance.exe&quot; -verboseMode:1 &quot;-assembly:$(TargetPath)&quot;"
         Condition="'$(AssemblyOriginatorKeyFile)'==''" />
   <Copy SourceFiles="$(TargetPath)" DestinationFolder ="$(IntermediateOutputPath)"/>
   <Copy SourceFiles="$(PdbFile)" DestinationFolder ="$(IntermediateOutputPath)"/>
 </Target>
 <Target Name="PeVerify" Condition="'$(_AssemblyTimestampBeforeCompile)'!='$(_AssemblyTimestampAfterCompile)'">
   <GetFrameworkSdkPath>
     <Output TaskParameter="Path" PropertyName="SdkPath" />
   </GetFrameworkSdkPath>
   <Exec WorkingDirectory="$(SdkPath)bin" Command="peverify.exe /nologo &quot;$(TargetPath)&quot;" />
 </Target>
 <PropertyGroup>
   <PdbFile>$(OutputPath)\$(AssemblyName).pdb</PdbFile>
   <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
   <PrepareForRunDependsOn>
     $(PrepareForRunDependsOn);
     EnhanceAssembly;
     PeVerify
   </PrepareForRunDependsOn>
 </PropertyGroup>
</Project>

This file needs to be imported at the end of your project file. So you’ll want to open your project file using a text editor not Visual Studio. Remember that project files are really just XML so we can go in and made changes to their source code. We need to do this if we want to get our targets file included.

At the bottom of the file you should see XML that looks roughly like this.

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" 
  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Pretend this is all of the rest of the project file -->
  <ProjectExtensions>
    <VisualStudio>
      <UserProperties OpenAccess_ConfigFile="App.config" 
          OpenAccess_ConnectionId="SilverlightAnalyticsExpressConnection" 
          OpenAccess_Enhancing="true" 
          OpenAccess_UpdateDatabase="false" 
          OpenAccess_EnhancementOutputLevel="1" 
          OpenAccess_UseMSBuild="True" />
    </VisualStudio>
  </ProjectExtensions>
</Project>

 

All we have to do is add in one line and change it to this using a relative path to where we placed the targets file. I admit I didn’t really know the best place to put it so I put it with the Telerik class libraries for my project.

<Import Project="..\..\lib\Telerik\enhance.targets" />
<ProjectExtensions>
  <VisualStudio>
    <UserProperties OpenAccess_ConfigFile="App.config" 
        OpenAccess_ConnectionId="SilverlightAnalyticsExpressConnection" 
        OpenAccess_Enhancing="true" 
        OpenAccess_UpdateDatabase="false" 
        OpenAccess_EnhancementOutputLevel="1" 
        OpenAccess_UseMSBuild="True" />
  </VisualStudio>
</ProjectExtensions>

And now we should be able to commit our changes and everything should work correctly on the build server. Cross your fingers. Make sure that all of your relative paths are correct. If you have any questions just post a comment below, on the Telerik forums, or both.

Silverlight 3 Out of the Browser

Running a Silverlight application out of the browser is very powerful. This lets users install a Silverlight application locally with a quick right click on the app in the browser. In earlier versions of Silverlight this was still pretty easy, but now you don’t even have to open up an xml file to do it.

So here is my simple Silverlight application running in the browser.

InitialMessageInBrowser

After I click that Button the app makes a web service call to change the text, which isn’t that important to this demo. I figured it was better than having it do nothing.

AfterClickInBrowser

Hooray we have a working Silverlight application. Now in order to get it running out of the browser we have only a couple of steps to take. None of which involve going into the AppManifest.xml file like was required in previous versions. Now we simply right-click on the Silverlight project in Visual Studio and select Properties.

SilverlightProperties

After enabling the ability to run out of the browser you just need to change the Out-of-Browser Settings. Doing this will create a file in the properties folder of the Silverlight application which has XML defining all of the settings configured here. This GUI just makes it easy to set up.

OutOfBrowserSettings

I like how simple this is. Not overloaded with tons of options. Just easy to use.

Now when we run the app we can right-click on the application and we are able to install the app locally.

RightClickInstall

When we click on the Install option we get a nice installation wizard with no complexity.

InstallApp

All the user has to do is decide where to put a shortcut. Once they click this the app will be installed and running. The application will look a little bit like this.

InitialMessageOutOfBrowser

And when we click out button we get another web service call and this time we pass a different parameter to the service call and get a different message. Take a look.

AfterClickOutOfBrowser

So how easy was that? Say that the user wants to uninstall the application now. That is also easy. All they have to do is right-click on it and select the option to remove the app and it is gone. They can do this in or out of browser.

RemoveApp

So now you know how easy it is to set up an out of browser Silverlight application.

How to Change or Remove the No Data Series Message in a RadChart for Silverlight

I’ve been working with the charts from Telerik’s RadControls for Silverlight. I am of course not blocking the UI when I make my requests to get my data for the charts. Since I am doing this late-loading of the data into the charts it causes them to initially show a message, “No Data Series.” This message is not a bad default message since it provides adequate information about why the chart is not displaying data.

NoDataSeries

However, since my charts will always start with no data, that message is quite silly. Luckily, changing or removing that message is easy. There is a convenient property on the ChartArea object called NoDataString, and in my case I set that as an empty string and I receive this nice blank chart now. I could potentially change the message to something else.

BlankChart

Snippet of Relevant Code

<UserControl x:Class="MyProject.UI.Charts.MyChart"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:telerikChart=
"clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Charting" 
    xmlns:telerikCharting=
"clr-namespace:Telerik.Windows.Controls.Charting;assembly=Telerik.Windows.Controls.Charting" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot">
        <telerikChart:RadChart x:Name="Chart1" 
           UseDefaultLayout="False">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
 
                <telerikCharting:ChartTitle Content="My Chart" 
                  HorizontalAlignment="Center"/>
                <telerikCharting:ChartArea x:Name="ChartArea1" 
                  Grid.Row="1" NoDataString="" />
            </Grid>
        </telerikChart:RadChart>
    </Grid>
</UserControl>