【问题标题】:How to execute dynamically created assembly in a given application domain?如何在给定的应用程序域中执行动态创建的程序集?
【发布时间】:2016-10-23 23:28:55
【问题描述】:

我在尝试在给定应用程序域中执行动态程序集时遇到问题。该程序集正在使用System.Reflection.Emit.AssemblyBuilder 类构建,如图所示

    // Utility method for building 'MathClient' assembly in memory. 
    public static void CreateMathClient(AppDomain domainForAssembly)
    {
        // Assembly name... 
        AssemblyName assemblyName = new AssemblyName();
        assemblyName.Name = "MathClient";
        assemblyName.Version = new Version("1.0.0.0");

        AssemblyBuilder assembly = domainForAssembly.DefineDynamicAssembly(
            assemblyName, AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder module = assembly.DefineDynamicModule(
            "MathClient", "MathClient.exe", false);

        // Defining 'Program' class... 
        TypeBuilder programClass = module.DefineType(
            "MathClient.Program",
            TypeAttributes.Public | TypeAttributes.Class); 

        // Defining Main() method... 
        MethodBuilder mainMethod = programClass.DefineMethod(
            "Main",
            MethodAttributes.Public | MethodAttributes.Static,
            null, 
            new Type[] { typeof(string[]) });
        ILGenerator mainMethodILGenerator = mainMethod.GetILGenerator();
        LocalBuilder aLocalVariable = mainMethodILGenerator.DeclareLocal(typeof(int), true);
        mainMethodILGenerator.Emit(OpCodes.Ldc_I4, 10);
        mainMethodILGenerator.Emit(OpCodes.Stloc, aLocalVariable);      // a = 10 

        // List 'a' value... 
        mainMethodILGenerator.Emit(OpCodes.Ldstr, "a = {0}");
        mainMethodILGenerator.Emit(OpCodes.Ldloc, aLocalVariable);
        mainMethodILGenerator.Emit(OpCodes.Box, typeof(int));
        Type consoleType = typeof(System.Console);
        MethodInfo writeLineMethod = consoleType.GetMethod(
            "WriteLine",
            new Type[] { typeof(string), typeof(object) });
        mainMethodILGenerator.Emit(OpCodes.Call, writeLineMethod);

        mainMethodILGenerator.Emit(OpCodes.Ret);

        // Bake 'Program' class type... 
        programClass.CreateType(); 

        // Set Main() method as an entry point...
        assembly.SetEntryPoint(mainMethod, PEFileKinds.ConsoleApplication);

        // Optionally save to disk...
        //assembly.Save("MathClient.exe");
    }

当我尝试在默认应用程序域中执行程序集时

    static void Main(string[] args)
    {
        AppDomain currentDomain = AppDomain.CurrentDomain; 

        // Create new assembly in memory... 
        CreateMathClient(currentDomain);

        // Execute 'MathClient.exe' in the current domain... 
        currentDomain.ExecuteAssemblyByName(
            "MathClient,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null");

        Console.ReadLine();
    }

以下异常正在抛出

System.IO.FileNotFoundException 未处理 H结果=-2147024894 消息=无法加载文件或程序集“MathClient,版本=1.0.0.0,文化=中性,PublicKeyToken=null”或其依赖项之一。系统找不到指定的文件。

但是,如果程序集被初步保存到磁盘

        // Optionally save to disk...
        assembly.Save("MathClient.exe");

一切正常。
为什么我不能用ExecuteAssemblyByName() 执行程序集?

【问题讨论】:

    标签: c# reflection .net-assembly reflection.emit


    【解决方案1】:

    由于您想将其加载到当前 AppDomain 中,您应该能够将其序列化为 byte[] 并使用 Assembly.Load(byte[] bytes) 加载它。

    MemoryStream stream = new MemoryStream();
    formatter.Serialize(stream, assembly);
    Assembly.Load(stream.ToArray());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-24
      • 2011-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多