将所有程序集放在一起并将其用作exe中的嵌入式资源

时间:2016-09-14 13:26:47

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

我有一个程序集(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;
}

然后我尝试在我的主机应用程序(MyApp.exe)中使用我的程序集(MyAssembly.dll)作为嵌入式资源,我也使用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(MainResolver)函数中+= new ResolveEventHandler(MyClass.Resolver)上的main,那么有用! 有一个程序集是必要的,因为我将在多个应用程序中使用它,并且我不想每次都在所有应用程序中包含所有引用的程序集。

所以,我的问题是如何在宿主应用中解决所有依赖关系(MyAssembly.dll以及MyAssembly.dll中包含的所有内部属性作为嵌入式资源)?

提前致谢!

1 个答案:

答案 0 :(得分:0)

我解决了这个问题。当主机应用程序运行并且找不到所需的程序集时,它会调用 XmlNode parentNode = fh.findNode(xmlFile.DocumentElement.ChildNodes, selectedTreeNode); XmlNode initialNode = parentNode; foreach (XmlNode node in parentNode.ChildNodes) { if (node.Name == this.lbElements.SelectedItem.ToString()) { parentNode.InsertAfter(node, node); this.xmlFile.DocumentElement.ReplaceChild(initialNode, parentNode); this.rtbText.Text = textIndentation(xmlFile); treeView1.Invalidate(); break; } } 事件。所以,我必须使用名为AssemblyResolve的事件处理程序来加载MainResolver。然后在使用MyAssembly.dll方法之前,必须将其从MyAssembly.dll中移除,因为应用尝试使用AssemblyResolve按顺序解析依赖关系(它调用{ {1}}然后ResolveEventHandler)。因此,主机应用程序失败,因为它无法在MainResolver中找到所需的程序集。解决方案是在调用Resolver后重新排序MainResolver或从ResolveEventHandler删除MainResolver。我认为排除无用的处理程序更容易。

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

MyClass

现在它就像一个魅力!