【问题标题】:Using Mono.Cecil with .NET CompactFramework on Windows Mobile devices在 Windows Mobile 设备上使用 Mono.Cecil 和 .NET CompactFramework
【发布时间】:2013-02-08 01:40:24
【问题描述】:

我正在尝试移植 Mono.Cecil 以在 Windows Mobile 6 设备上使用 .NET CompactFramework 3.5。首先,我不得不对 Mono.Cecil 的源代码进行一些奇怪的调整(来自its GitHub 页面,提交:ec2a54fb00)。在试图理解为什么需要这些调整时,我有点惊讶。

第一个变化: Mono.Cecil 的源代码有表达式,对 System.Array 类型的对象调用“IsNullOrEmpty()”方法。但是,这种方法在微软实现的.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 代码并检查它的不同方面。

【问题讨论】:

    标签: visual-studio-2008 windows-mobile compact-framework mono.cecil


    【解决方案1】:

    我假设您构建的 Mono Cecil 仍在引用完整的框架系统程序集,因此不会加载到 Compact Framework 程序集中。

    当我将 iTextSharp 移植到紧凑型框架时,我在一个 Visual Studio 会话中打开了 iTextSharp 源代码,并在另一个新的紧凑型框架 (C# SmartDevice) 项目会话中启动了一个新的 iTextSharpCF。

    然后我在新的 Compact Framework 项目中添加了所有代码文件和子目录,因为它们已加载到原始完整框架项目中。

    复制完所有文件后,我必须添加在 Compact Framework 项目中使用的相应 Compact Framework 程序集。

    然后尝试编译 Compact Framework 版本并重写或添加代码以使 Compact Framework 项目构建成功。最后,您将获得一个 Compact Framework 程序集,它仅引用 Compact Framework 程序集,并将在智能设备上运行。

    MS 构建系统不够灵活,您只需设置编译器指令即可将完整的框架项目切换到 Compact Framework 项目。

    【讨论】:

    • 事实上,在开始为 CompactFramework 构建 Mono.Cecil 时,我在 Visual Studio 2008 IDE 中启动了一个新的 C#“智能设备项目”,添加了我下载的所有 Mono.Cecil 文件作为来自 GitHub 的 zip 文件。我什至通过查看显示用于构建项目的确切命令的输出窗口,交叉验证了构建是针对 CompactFramework 程序集而不是完整框架进行的。该命令包括 csc.exe、引用的程序集、源代码文件和定义的符号。因此,我认为,您在这里应用的推理被排除在外。
    • 正如我在原始帖子中所述,我能够在我的 CompactFramework 项目(智能设备项目)中成功使用 Mono.Cecil 库 (DLL) 来读取程序集、浏览类型、方法、方法体、指令等。只有在写出程序集时,库才让我失望 - 新写出的程序集未被识别为有效的 Pocket PC 应用程序。
    • +1 表示在尝试使用 Visual Studio IDE 将针对 .NET 完整框架的项目转换为针对 Compact Framework 的项目时存在缺陷。
    • Mono cecil 是一个库。您是否通过启动智能设备库项目开始移植到 CF?你为什么要读/写一个exe文件?对不起,我不清楚 lib 的使用。通常,您会在应用程序中使用 cecil 来“反编译”另一个 mono 或 dotnet lib:“如今 Mono Debugger、错误查找和合规性检查工具 Gendarme、MoMA、DB4O 以及许多其他工具都在使用它。”我使用 .Net Reflector 和其他 CIL 工具来检查 DLL 和 dotnet 应用程序。
    • 是的,我通过启动一个智能设备库项目开始移植到 CF。我正在读/写的 exe 文件是标准的 .NET 程序集(PE 格式)。所以,它必须仍然在 Mono Cecil 的范围内才能读/写它。我的目标是使用原始 exe 文件创建一个新的 exe,并在适当的位置添加诊断/检测代码。
    猜你喜欢
    • 1970-01-01
    • 2010-09-26
    • 2010-11-17
    • 2016-02-29
    • 2010-10-25
    • 2019-09-20
    • 2016-08-12
    • 2011-11-26
    • 1970-01-01
    相关资源
    最近更新 更多