Send mail to the author(s)

January 30, 2007

Using ILMerge on Compact Framework Applications

A couple of questions appeared in the newsgroup in the last few days about using ILMerge with CF applications. Both questioners where having problems after merging their assemblies and attempting to run them on the device. In both circumstances, the users were getting the same error:

".NET CF Initialization Error

The application failed to load required components. If the .NET CF is installed on a storage card, please ensure that this card is in place and launch the application again.

If this fails, a re-installation of the .NET CF is recommended."

At first glance, it looks like the .NET CF is not installed on the device, but in both cases, CF 2.0 was present on the device. My next thought was that the applications where bound to wrong framework since ILMerge will, by default, use the .NET Framework assemblies.

After running ILMerge on my own application and looking the BCL references in ILDasm, I confirmed that ILMerge was replacing the CF references with desktop framework references. Below is the dependency manifest from ILDasm. Take a look at the publickeytoken value. of mscorlib, System and System.Windows.Forms. It is the public key token for the .NET Framework, not the Compact Framework.

.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 2:0:0:0
}
.assembly extern System.Windows.Forms
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 2:0:0:0
}
.assembly extern System
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 2:0:0:0
}

I checked the ILMerge documentation and found that you can specify the directory where ILMerge will find mscorlib and the other BCL references. I ran the following command-line and then looked at the BCL references once again:

ilmerge /t:winexe /targetplatform:v2,"C:\Program Files\Microsoft.NET\SDK\CompactFramework\v2.0\Debugger\BCL" /out:MergedApplication.exe DeviceApplication1.exe OpenNETCF.Dummy.dll

In ILDasm, I found the following dependency manifest:

.assembly extern mscorlib
{
  .publickeytoken = (96 9D B8 05 3D 33 22 AC )                         // ....=3".
  .ver 2:0:0:0
}
.assembly extern retargetable System.Windows.Forms
{
  .publickeytoken = (96 9D B8 05 3D 33 22 AC )                         // ....=3".
  .ver 2:0:0:0
}
.assembly extern retargetable System
{
  .publickeytoken = (96 9D B8 05 3D 33 22 AC )                         // ....=3".
  .ver 2:0:0:0
}

This time around, the public key token matches that of the Compact Framework BCLs. Success!

The key to using ILMerge with Compact Framework applications is the targetplatform command-line argument. This takes the form of:

/targetplatform:[version,platformdirectory]

where version is either v1 or v2 (the "v" is not case-sensitive) and platformdirectory is the full path to the folder containing mscorlib.dll.


Update: You will need ILMerge v2.0.7.0213 or later to successfully merge Compact Framework assemblies. You can download it here.