将所有程序集放在一起并将其用作 exe 中的嵌入式资源
put together all assemblies and use it as embedded resource in exe
我有一个程序集 (MyAssembly.dll)(类似于包装器),其中有一些对其他程序集(3rdAssembly1.dll、3rdAssembly2.dll)的引用。这些引用的程序集作为嵌入式资源嵌入到我的程序集中。在我的程序集中,我有 main class(MyClass) 调用这些第三方程序集中的一些函数。这个 class 有一个默认构造函数,我在其中尝试解析所需的依赖项,如下所示:
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 并将其与主机应用程序放在同一文件夹中,并在 main
中的 += new ResolveEventHandler(MyClass.Resolver)
上替换 += new ResolveEventHandler(MainResolver)
功能然后它工作!
必须有一个程序集,因为我要在多个应用程序中使用它,我不想每次都在所有应用程序中包含所有引用的程序集。
所以,我的问题是如何解决主机应用程序中的所有依赖项(MyAssembly.dll 和包含在 MyAssembly.dll 中作为嵌入式资源的所有内部依赖项)?
提前致谢!
我解决了这个问题。当主机应用程序运行但找不到所需的程序集时,它会调用 AssemblyResolve
事件。因此,我必须使用名为 MainResolver
的事件处理程序来加载 MyAssembly.dll
。然后在使用 MyAssembly.dll
的方法之前,有必要将其从 AssemblyResolve
中删除,因为该应用程序会尝试使用 ResolveEventHandler
来解决依赖项的添加顺序(它调用 MainResolver
然后 Resolver
)。结果,主机应用程序失败,因为它无法在 MainResolver
中找到所需的程序集。解决方案是在 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();
}
现在它就像一个魅力!
我有一个程序集 (MyAssembly.dll)(类似于包装器),其中有一些对其他程序集(3rdAssembly1.dll、3rdAssembly2.dll)的引用。这些引用的程序集作为嵌入式资源嵌入到我的程序集中。在我的程序集中,我有 main class(MyClass) 调用这些第三方程序集中的一些函数。这个 class 有一个默认构造函数,我在其中尝试解析所需的依赖项,如下所示:
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 并将其与主机应用程序放在同一文件夹中,并在 main
中的 += new ResolveEventHandler(MyClass.Resolver)
上替换 += new ResolveEventHandler(MainResolver)
功能然后它工作!
必须有一个程序集,因为我要在多个应用程序中使用它,我不想每次都在所有应用程序中包含所有引用的程序集。
所以,我的问题是如何解决主机应用程序中的所有依赖项(MyAssembly.dll 和包含在 MyAssembly.dll 中作为嵌入式资源的所有内部依赖项)?
提前致谢!
我解决了这个问题。当主机应用程序运行但找不到所需的程序集时,它会调用 AssemblyResolve
事件。因此,我必须使用名为 MainResolver
的事件处理程序来加载 MyAssembly.dll
。然后在使用 MyAssembly.dll
的方法之前,有必要将其从 AssemblyResolve
中删除,因为该应用程序会尝试使用 ResolveEventHandler
来解决依赖项的添加顺序(它调用 MainResolver
然后 Resolver
)。结果,主机应用程序失败,因为它无法在 MainResolver
中找到所需的程序集。解决方案是在 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();
}
现在它就像一个魅力!