【问题标题】:put together all assemblies and use it as embedded resource in exe将所有程序集放在一起并将其用作exe中的嵌入式资源
【发布时间】:2017-01-22 08:03:56
【问题描述】:

我有一个程序集(MyAssembly.dll)(类似于包装器),它有一些对其他程序集(3rdAssembly1.dll、3rdAssembly2.dll)的引用。这些引用的程序集作为嵌入式资源嵌入到我的程序集中。在我的程序集中,我有主类(MyClass),它从这些第三方程序集中调用一些函数。此类有一个默认构造函数,我尝试在其中解析所需的依赖项,如下所示:

public MyClass{
  AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(Resolver);
}

public static System.Reflection.Assembly Resolver(object sender, ResolveEventArgs args)
{
    string source = "MyAssembly.Resources."+args.Name.Remove(args.Name.IndexOf(','))+".dll";
    //source = "MyAssembly.Resources.3rdAssembly1.dll"
    //source = "MyAssembly.Resources.3rdAssembly2.dll"

    Assembly a1 = Assembly.GetExecutingAssembly();
    Stream s = a1.GetManifestResourceStream(source);
    byte[] block = new byte[s.Length];
    s.Read(block, 0, block.Length);
    Assembly a2 = Assembly.Load(block);
    return a2;
}

然后我尝试将我的程序集(MyAssembly.dll)用作我的主机应用程序(MyApp.exe)中的嵌入式资源,我还使用Resolver 函数。

static void main(string[] args){
  AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MainResolver);

  MyClass my = new MyClass();
  my.DoWork();
}

static System.Reflection.Assembly MainResolver(object sender, ResolveEventArgs args)
{
    string source = "MyApp.Resources."+args.Name.Remove(args.Name.IndexOf(','))+".dll";
    //source = "MyApp.Resources.MyAssembly.dll"
    Assembly a1 = Assembly.GetExecutingAssembly();
    Stream s = a1.GetManifestResourceStream(args.Name);
    byte[] block = new byte[s.Length];
    s.Read(block, 0, block.Length);
    Assembly a2 = Assembly.Load(block);
    return a2;
}

问题是我的主机应用程序无法解析内部程序集(3rdAssembly1.dll、3rdAssembly2.dll),因为从未调用 MyClass 中的 Resolver 函数。主机应用程序尝试解决所有问题,结果失败。我玩弄了它,发现如果我从嵌入式资源中排除 MyAssembly.dll 并将其定位在与主机应用程序相同的文件夹中,并在 += new ResolveEventHandler(MyClass.Resolver) 上替换 += new ResolveEventHandler(MainResolver) 上的 main 函数,那么它可以工作! 必须有一个程序集,因为我将在多个应用程序中使用它,并且我不想每次都在所有应用程序中包含所有引用的程序集。

那么,我的问题是如何解决宿主应用程序中的所有依赖项(MyAssembly.dll 和包含在 MyAssembly.dll 中作为嵌入式资源的所有内部依赖项)?

提前致谢!

【问题讨论】:

    标签: c# .net visual-studio assemblies embedded-resource


    【解决方案1】:

    我解决了这个问题。当宿主应用程序运行并且没有找到所需的程序集时,它会调用AssemblyResolve 事件。所以,我必须使用名为MainResolver 的事件处理程序来加载MyAssembly.dll。然后在使用MyAssembly.dll 的方法之前,有必要将其从AssemblyResolve 中删除,因为该应用程序尝试使用ResolveEventHandler 解决依赖关系,以便它们被添加(它调用MainResolver,然后是Resolver)。结果主机应用程序失败,因为它在MainResolver 中找不到所需的程序集。解决方案是在调用AssemblyResolve 后重新排序ResolveEventHandler 或从AssemblyResolve 中删除MainResolver。我认为排除无用的处理程序更容易。

    所以,我不需要更改 MyClass 中的任何内容。在创建MyClass 的实例之前,我需要在主机应用程序中添加以下代码。

    static MyApp(){
      AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MainResolver);
    }
    
    static void main(string[] args){
      //remove MainResolver
      AppDomain.CurrentDomain.AssemblyResolve -= MainResolver;
    
      MyClass my = new MyClass();
      my.DoWork();
    }
    

    现在它就像一个魅力!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-07
      • 2013-03-06
      • 2017-11-27
      • 2011-10-17
      • 1970-01-01
      • 2018-09-21
      • 1970-01-01
      • 2014-05-04
      相关资源
      最近更新 更多