3

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ghd
  • 258
  • 1
  • 3
  • 14

1 Answers1

1

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
josef
  • 5,951
  • 1
  • 13
  • 24
  • In fact, when starting out to build Mono.Cecil for the CompactFramework, I started a new C# "Smart Device Project" in Visual Studio 2008 IDE, added all the Mono.Cecil files that I had dowloaded as a zip file from GitHub. I have even cross verified that the build is happening against CompactFramework assemblies and not the Full Framework by having a look at the output window which shows the exact command used to build the project. The command includes the csc.exe, referenced assemblies, source code files and defined symbols. Hence I think, the reasoning that you are applying here is ruled out. – ghd Feb 23 '13 at 12:42
  • Also as I have stated in my original post, I am able to successfully use the Mono.Cecil library (DLL) in my CompactFramework projects (Smart Device Projects) to read an assembly, navigate through types, methods, method bodies, instructions, etc. without a hitch. It's only when it comes to writing out the assembly, that the library is failing me - the newly written out assembly is not recognized as a valid Pocket PC application. – ghd Feb 23 '13 at 12:43
  • +1 for suggesting the pitfall in trying to convert a project targeted to .NET full framework to one that's targeted to the Compact Framework, using the Visual Studio IDE. – ghd Feb 23 '13 at 12:56
  • Mono cecil is a library. Did you start your porting to CF by starting a smartdevice library project? Why are you trying to read/write an exe file? I am sorry, but use of the lib is not clear for me. Normally you would use cecil in an app to 'decompile' another mono or dotnet lib: "Today it is used by the Mono Debugger, the bug-finding and compliance checking tool Gendarme, MoMA, DB4O, as well as many other tools." I use .Net Reflector and other CIL tools to inspect DLLs and dotnet apps. – josef Feb 24 '13 at 07:35
  • Yes, I started porting to CF by starting a smartdevice library project. The exe file that I am reading / writing is a standard .NET assembly (PE format). So, it must still be inside the scope of Mono Cecil to read / write it. My goal is to use the original exe file to create a new exe with diagnostic / instrumentation code added at appropriate places. – ghd Feb 25 '13 at 03:50