在Windows Mobile设备上使用Mono.Cecil和.NET Compact Framework

3
我正在尝试将Mono.Cecil移植到Windows Mobile 6设备上的.NET CompactFramework 3.5。首先,我必须对Mono.Cecil的源代码(来自GitHub页面,提交:ec2a54fb00)进行一些奇怪的调整。令我惊讶的是,我试图理解为什么需要这些调整。 第一个更改: Mono.Cecil的源代码包含在System.Array类型的对象上调用“IsNullOrEmpty()”方法的表达式。但是,在Microsoft实现的.NET框架中根本不存在这样的方法。因此,代码无法编译。因此,我向System.Array类添加了一个扩展方法:
static class ArrayExtensions
{
    public static bool IsNullOrEmpty(this System.Array a)
    {
        return a.Length == 0;
    }
}
第二个修改: Mono.Cecil的源代码试图在System.String类型的对象上调用"ToLowerInvariant()"方法。但是,在CompactFramework中不存在这样的方法。因此,这是第二个微调:
static class StringExtensions
{
#if PocketPC
    public static string ToLowerInvariant(this String a)
    {
        return a.ToLower();
    }
#endif
}

在这里,我只是将对“ToLowerInvariant”方法的调用转发到String类的“ToLower”方法。

我使用Visual Studio 2008构建了Mono.Cecil的源代码,并定义了以下编译符号:

PocketPC
CF

接下来,我需要测试使用上述步骤构建的Mono.Cecil DLL文件。我的方法是读取一个程序集并以不同的名称重新创建它。为此,我创建了一个简单的应用程序,可以在Windows Mobile设备上运行,并将其命名为SmartDeviceProject1.exe。我读取与此应用程序对应的程序集,并将其写成不同的名称:
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");
        }
    }
}

新的程序集名为 SmartDeviceProject1New.exe。当我尝试在 Windows Mobile 设备上运行新应用程序 SmartDeviceProject1New.exe 时,它无法运行。错误消息报告该文件不是有效的 PocketPC 应用程序。

我做错了什么吗?

P.S:然而,使用我上面构建的 Mono.Cecil DLL 文件,我能够浏览 CIL 代码并检查其不同方面。

1个回答

1
我假定您所构建的Mono Cecil仍然引用全框架系统程序集,因此无法加载到紧凑框架程序集中。
当我将iTextSharp移植到紧凑框架时,我在一个Visual Studio会话中打开了iTextSharp源代码,并在另一个新的紧凑框架(C# SmartDevice)项目会话中启动了一个新的iTextSharpCF。
然后,我将所有代码文件和子目录添加到新的紧凑框架项目中,就像它们在原始的全框架项目中一样被加载。
在复制所有文件后,我必须添加在紧凑框架项目中使用的相应紧凑框架程序集。
然后尝试编译紧凑框架版本并重写或添加代码以使紧凑框架项目成功构建。最终得到一个仅引用紧凑框架程序集并可在智能设备上运行的紧凑框架程序集。
MS构建系统并不那么灵活,您不能仅通过设置编译器指令将全框架项目切换为紧凑框架项目。

事实上,当我开始为CompactFramework构建Mono.Cecil时,我在Visual Studio 2008 IDE中启动了一个新的C#“智能设备项目”,并添加了我从GitHub下载的所有Mono.Cecil文件的zip文件。我甚至进行了交叉验证,以确保构建是针对CompactFramework程序集而不是完整框架进行的,方法是查看输出窗口,该窗口显示用于构建项目的确切命令。该命令包括csc.exe、引用的程序集、源代码文件和定义的符号。因此,我认为您在这里应用的推理被排除了。 - ghd
正如我在原始帖子中所述,我能够成功地在我的CompactFramework项目(智能设备项目)中使用Mono.Cecil库(DLL)来读取程序集,浏览类型、方法、方法体、指令等等,没有任何问题。只有在写出程序集时,该库才会让我失望 - 新编写的程序集不能被识别为有效的口袋PC应用程序。 - ghd
在尝试使用Visual Studio IDE将针对.NET完整框架的项目转换为针对Compact Framework的项目时,有一个需要注意的陷阱。建议+1。 - ghd
Mono Cecil是一个库。你是否通过启动一个智能设备库项目来开始将它移植到CF?为什么要尝试读/写一个exe文件?很抱歉,但我对这个库的使用不太清楚。通常情况下,你会在一个应用程序中使用Cecil来“反编译”另一个Mono或DotNet库:“如今它被Mono调试器、错误查找和合规性检查工具Gendarme、MoMA、DB4O以及许多其他工具所使用。”我使用.Net Reflector和其他CIL工具来检查DLL和DotNet应用程序。 - josef
是的,我开始通过启动智能设备库项目来将其移植到CF。我正在读/写的exe文件是一个标准的.NET程序集(PE格式)。因此,它仍然必须在Mono Cecil的范围内进行读取/写入。我的目标是使用原始exe文件,在适当的位置添加诊断/工具箱代码来创建一个新的exe文件。 - ghd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接