windows-phone-7code-generationmono.cecilcci

How can I create a new Windows Phone 7 assembly from scratch using CCI or Mono.Cecil


I am working on a tool to generate assemblies for WP7. I am doing this from the full framework. Since Reflection.Emit doesn't work with WP7 but either CCI or Mono.Cecil do I am wondering if there is a way to create new assemblies from scratch. I already know that I can modify existing assemblies, but being able to create one would be pretty useful. I guess a workaround would be to generate an empty assembly in visual studio and keep it as a template, but I think that there should be a better way.


Solution

  • It's pretty easy to do with Mono.Cecil:

    using Mono.Cecil;
    using Mono.Cecil.Cil;
    
    class Demo
    {
    
        static void Main()
        {
            var winphoneAssemblies = @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\Profile\WindowsPhone";
    
            var assemblyResolver = new DefaultAssemblyResolver();
            assemblyResolver.AddSearchDirectory(winphoneAssemblies);
    
            var winphoneCorlib = assemblyResolver.Resolve("mscorlib");
    
            var module = ModuleDefinition.CreateModule("Test", new ModuleParameters
            {
                AssemblyResolver = assemblyResolver,
                Runtime = TargetRuntime.Net_2_0,
                Kind = ModuleKind.Dll,
            });
    
            // trick to force the module to pick the winphone corlib
            module.Import(winphoneCorlib.MainModule.GetType("System.Object"));
    
            var type = new TypeDefinition("Test", "Type", TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Abstract, module.TypeSystem.Object);
            module.Types.Add(type);
    
            var method = new MethodDefinition("Identity", MethodAttributes.Public | MethodAttributes.Static, module.TypeSystem.Int32);
            method.Parameters.Add(new ParameterDefinition("i", ParameterAttributes.None, module.TypeSystem.Int32));
    
            type.Methods.Add(method);
    
            var il = method.Body.GetILProcessor();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ret);
    
            module.Write("Test.dll");
        }
    }
    

    A few things to note: