Reputation: 368
I am trying to port Mono.Cecil to work with the .NET CompactFramework 3.5 on Windows Mobile 6 devices. Firstly, I had to make a couple of odd tweaks to the source code of Mono.Cecil (from its GitHub page, commit: ec2a54fb00). It's a bit surprising to me in trying to understand why the tweaks were required at all.
The first change: The source code of Mono.Cecil has expressions that call "IsNullOrEmpty()" method on objects of System.Array type. But, such a method doesn't exist at all in the .NET framework implemented by Microsoft. Due to this, the code wouldn't compile. Hence I added an extension method to System.Array class:
static class ArrayExtensions
{
public static bool IsNullOrEmpty(this System.Array a)
{
return a.Length == 0;
}
}
The second change: The source code of Mono.Cecil tries to call "ToLowerInvariant()" method on objects of System.String type. But, such a method doesn't exist in the CompactFramework. So here's the second tweak:
static class StringExtensions
{
#if PocketPC
public static string ToLowerInvariant(this String a)
{
return a.ToLower();
}
#endif
}
Here I am just forwarding the calls made to "ToLowerInvariant" method to the "ToLower" method of the String class.
I built the source code of Mono.Cecil with the above changes in Visual Studio 2008, with the following compilation symbols defined:
PocketPC
CF
Next, I needed to test the Mono.Cecil DLL file built using the above steps. My approach was to read an assembly and recreate it with a different name. To this end, I created a simple application that would run on a Windows Mobile device and called it SmartDeviceProject1.exe. I read the assembly corresponding to this application and wrote it out with a different name:
using System;
using System.Linq;
using System.Collections.Generic;
using System.Windows.Forms;
using Mono.Cecil;
namespace SmartDeviceProject3
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[MTAThread]
static void Main()
{
var assemblyDef = AssemblyDefinition.ReadAssembly(@"\Program Files\SmartDeviceProject1\SmartDeviceProject1.exe");
assemblyDef.Write(@"\Program Files\SmartDeviceProject1\SmartDeviceProject1New.exe");
}
}
}
The new assembly is called SmartDeviceProject1New.exe. When I try to run the new application SmartDeviceProject1New.exe on the Windows Mobile device, it fails to run. The error message reports that the file is not a valid PocketPC application.
Have I gone wrong somewhere?
P.S: However, using the Mono.Cecil DLL file that I built above, I am able to navigate through the CIL code and inspect different aspects of it.
Upvotes: 3
Views: 1178
Reputation: 5959
I assume the Mono Cecil you build is still referencing the full framework system assemblies and therefore does not load into a Compact Framework assembly.
As I ported iTextSharp to compact framework, I opened the iTextSharp source code in one Visual Studio session and started a new iTextSharpCF in another new Compact Framework (C# SmartDevice) project session.
Then I added all code files and subdirectories in the new Compact Framework project as they are loaded in the original full framework project.
When all files were copied over, I had to add the corresponding Compact Framework assemblies that are used in the Compact Framework project.
Then try to compile the Compact Framework version and rewrite or add code to get the Compact Framework project build successfully. Finally you get a Compact Framework assembly that only references Compact Framework assemblies and will run on smart devices.
The MS build system is not that flexible that you can switch a full framework project to a Compact Framework project just be setting a compiler directive.
Upvotes: 1