【问题标题】:CurrentDomain.AssemblyResolve not being able resolve 'some' assembliesCurrentDomain.AssemblyResolve 无法解析“某些”程序集
【发布时间】:2011-02-12 23:09:40
【问题描述】:

在找到我关于程序集解析的最后一个问题 (AppDomain.CurrentDomain.AssemblyResolve asking for a <AppName>.resources assembly?) 的答案后,现在我可以在我的程序中嵌入引用程序集,除非这对某些引用不起作用。

首先,我在 Program.cs 的第一个入口设置我的程序集解析器

    // attach our embedded assembly loader.
    AppDomain.CurrentDomain.AssemblyResolve += AssemblyManager.Instance.Resolver;

这是我的实际解析器;

public Assembly Resolver(object sender, ResolveEventArgs args)
{
    AssemblyName askedAssembly = new AssemblyName(args.Name);

    lock (this)
    {
        Assembly assembly;

        string resourceName = string.Format("Assets.Assemblies.{0}.dll", askedAssembly.Name);
        using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
        {
            if (stream == null)
            {
                LogManager.Instance.Write(LogMessageTypes.Fatal, string.Format("Can not resolve asked assembly: {0}", askedAssembly.Name));
                MessageBox.Show(i18n.CanNotLoadRequiredAssembliesMessage, i18n.CanNotLoadRequiredAssembliesTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(-1);
            }

            byte[] assemblyData = new byte[stream.Length];
            stream.Read(assemblyData, 0, assemblyData.Length);
            assembly = Assembly.Load(assemblyData);
        }

        LogManager.Instance.Write(LogMessageTypes.Trace, "Loaded embedded assembly: " + askedAssembly.Name);

        return assembly;
    }
}

现在我的程序引用了这些库程序集。

  • Esent.Collections.dll
  • Esent.Interop.dll
  • HtmlAgilityPack.dll
  • Ionic.Zip.Reduced.dll
  • System.Windows.Forms.Calendar.dll
  • AxInterop.ShockwaveFlashObjects
  • Interop.ShockwaveFlashObjects
  • irrKlang.NET4.dll
  • ikpMP3.dll
  • Nini.dll(已解决)

上面有我的解析器;我可以嵌入 Esent.Collections、Esent.Interop、HtmlAgilityPack、Ionic.Zip.Reduced、System.Windows.Forms.Calendar、AxInterop.ShockwaveFlashObjects、Interop.ShockwaveFlashObjects 并在运行时解决这些问题。

问题出现在 irrKlang.NET.4、Nini 和 ShockwaveFlash 程序集中,如果我尝试在其中嵌入这些程序集并尝试在运行时解决它们,我就会遇到问题。

对于 irrKlang,我可以理解这个问题,因为 irrKlang.NET4 程序集引用了我自己无法找到的非托管 ikpMP3.dll。

对于 Nini.dll,实际上我可以嵌入这个程序集并使用运行的 VS 调试/发布配置它工作正常,但是当我从资源管理器自己启动程序时,程序只是拒绝启动(没有错误或任何信息)。

任何帮助表示赞赏。

更新 现在,感谢 Marc Gravell 的回答,我可以加载 Nini.dll。

对于 irrKlang 部分,由于 irrKlang.NET4.dll 是一个托管程序集,它需要 ikpMp3.dll - 一个非托管程序集 - 如果我尝试在运行时解析 irrKlang.NET4.dll 它可以访问其所需依赖 ikpMp3。有解决办法吗?

【问题讨论】:

  • 您使用Main 方法中的任何类型吗?它必须能够完全 JIT Main 才能启动应用程序...
  • Nini.dll 实际上是从 Main 方法访问的。我会试一试,然后把它移走。

标签: c# assembly-resolution


【解决方案1】:

这里的一个常见问题是在您有机会注册程序集解析事件之前使用类型。特别要注意,系统必须能够 JIT 方法才能开始运行方法 - 包括 Main()

因此,如果您的入口点 (Main()) 执行事件挂钩 并且还 与有问题的类型进行对话,它将尝试解析类型(对于 JIT)之前 或有机会订阅。

在main中做最小;将“真实”代码移至另一个方法,该方法仅在事件被确定订阅后才被调用。

例如:

static void Main() {
    SubscribeAssemblyResolver();
    ExecuteApplication();
}

在极端情况下,您甚至可能需要使用 MethodImplAttribute 来禁用上述方法的内联。

【讨论】:

  • 是的,感谢从 Main() 移动对 Nini 程序集的调用完成了魔法,JIT 现在可以加载程序,并且使用我提供的解析器正确解析进一步的 Nini.dll 引用。
猜你喜欢
  • 2015-04-08
  • 1970-01-01
  • 2010-12-31
  • 1970-01-01
  • 2016-11-07
  • 2011-06-18
  • 2016-04-26
  • 2014-12-25
  • 1970-01-01
相关资源
最近更新 更多