CurrentDomain.AssemblyResolve无法解析'某些'程序集

时间:2011-02-12 23:09:41

标签: c# assembly-resolution

在找到答案后,关于汇编解决的最后一个问题(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。有解决办法吗?

1 个答案:

答案 0 :(得分:4)

这里的一个常见问题是在您有机会注册assembly-resolve事件之前使用这些类型。特别要注意的是,系统必须能够在启动运行方法之前JIT方法 - 包括Main()

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

做主要的最低限度;将“真实”代码移动到另一个方法,只有在事件被明确订阅后才会调用。

例如:

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

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