Diagnosing MissingMethodExceptions and TypeLoadExceptions using the Loader Log

Have you ever encountered a MissingMethodException or TypeLoadException when starting a .NET Compact Framework application?  If you are running version 2 of the .NET Compact Framework, the Loader Log can help identify the source of the exception.

For detailed information regarding the Loader Log, please read Steven Pratschner's excellent Better Diagnostics in Whidbey: Loader Logging post.

Enabling the Loader Log
The Loader Log is enabled via the device's registry.  In my steps, below, I will be using the Remote Registry Editor that is included with Visual Studio 2005.

WARNING: Using Remote Registry Editor incorrectly can cause serious problems that may require you to hard reset your device. Microsoft cannot guarantee that problems resulting from the incorrect use of Remote Registry Editor can be solved. Use Remote Registry Editor at your own risk.

  1. Start the Remote Registry Editor
    • Open the Start Menu
    • Select All Programs
    • Select Microsoft Visual Studio 2005
    • Select Visual Studio Remote Tools
    • Select Remote Registry Editor
  2. Connect to your device
    • On the Target menu, select Connect
    • Select your device and click OK
  3. Enable diagnostic logging
    • In the left hand pane, expand the device
    • Expand HKEY_LOCAL_MACHINE
    • Expand SOFTWARE
    • Expand Microsoft
    • Expand .NETCompactFramework
    • Expand Diagnostics
      If this key does not exist, you will need to create it
      • Right click on .NETCompactFramework
      • Select New > Key
      • Type "Diagnostics" (without quotes)
      • Click OK
    • Expand Logging
      If this key does not exist, you will need to create it
      • Right click on Diagnostics
      • Select New > Key
      • Type "Logging" (without quotes)
      • Click OK
    • Set the value of Enabled to 1
      If this value does not exist, you will need to create it
      • Right click on Logging
      • Select New > DWORD Value
      • Set the Name to "Enabled" (without quotes)
      • Set the value to 1
      • Click OK
  4. Enable loader logging
    • In the Logging key (from step 3) expand Loader
      If this key does not exist, you will need to create it
      • Right click on Logging
      • Select New > Key
      • Type "Loader" (without quotes)
      • Click OK
    • Set the value of Enabled to 1
      If this value does not exist, you will need to create it
      • Right click on Loader
      • Select New > DWORD Value
      • Set the Name to "Enabled" (without quotes)
      • Set the value to 1
      • Click OK

To disable the Loader Log, follow the above steps and set the value of Enabled to 0.
To disable all logging, follow only steps 1-3, and set the value of Enabled to 0.

There are a few optional settings that can be set to configure how the Loader Log is created.  For details, please refer to Steven's post

One optional setting I highly recommend is to create application specific log files.  This causes the .NET Compact Framework to name the log file based on your application name.  For example, if I enable logging with the UseApp option, the log file created for an application called DkTest.exe will be netcf_DkTest_loader.log.

To enable application specific log files please make the following addition to the above steps.

  • Enable application specific log files
    • In the Logging key et the value of UseApp to 1
      If this value does not exist, you will need to create it
      • Right click on Logging
      • Select New > DWORD Value
      • Set the Name to "UseApp" (without quotes)
      • Set the value to 1
      • Click OK

Diagnosing the exception
To illustrate how the Loader Log can help identify the cause of these exceptions, I created a custom control that was built to incorrectly reference the full .NET Framework version of the System.Windows.Forms assembly.  I then built a simple application that used this control.  After running the application, the Loader Log contained the following data.

MissingType. Class [myControl.CustomButton], Assembly [myControl, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null].
Scrolling back up the log file, we find this entry.

Failed to load [System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=B77A5C561934E089]
In examining this entry, we see that the myControl.CustomButton assembly failed to load the System.Windows.Forms assembly.  The reason was that the strong name of the System.Windows.Forms assembly (Name, Version, Culture, PublicKeyToken) was not present on my device.  Take note of the value of PublicKeyToken.  By comparing the PublicKeyToken value of successfully loaded assemblies (ex: System.Xml), we find that, in this instance, they do not match.

The PublicKeyToken specified in the strong name for the System.Windows.Forms assembly is that of the full .NET Framework. 

To date (versions 1 and 2), the .NET Compact Framework uses the 969DB8053D3322AC as it's PublicKeyToken in system assembly strong names.

Enjoy!
-- DK

Edit: Fix UseApp steps

Disclaimer(s):
This posting is provided "AS IS" with no warranties, and confers no rights.