从Path加载程序集

我需要从某个位置而不是从GAC加载程序集。 我无法从GAC中删除程序集,因为我的程序必须在不同的计算机上运行,​​我无法控制程序集是否在GAC中。

我在我的项目中添加了对DLL-File的引用。 不幸的是,汇编是从GAC加载的。

我在Startup -Event中的App.xaml.cs中尝试了以下代码

 var directory = Thread.GetDomain().BaseDirectory; var dllPath = Path.Combine(directory, "MyAssembly.dll"); var assembly = Assembly.LoadFrom(dllPath); 

不幸的是,程序集仍然是从GAC加载的。

即使程序集在GAC中,我还能从指定位置加载它?

不幸的是,您将无法绕过GAC – Assembly.LoadFrom()Assembly.LoadFile() ,甚至将其加载到字节数组中并使用Assembly.Load(byte[])将首先检查GAC具有相同标识的程序集,然后加载它。

曾经能够在.net 1.1中执行您想要的操作,但从2.0开始,首先检查GAC。 请参阅运行时如何查找程序集 – 请注意,第3步是在探测目录之前检查GAC(即使您已完全指定它)

如果要为Reflection加载一个(检查程序集,而不是运行它),可以使用Assembly.ReflectionOnlyLoadFrom()

查看MSDN上的Assembly.LoadFrom()

来自MSDN:

 Assembly SampleAssembly; SampleAssembly = Assembly.LoadFrom("c:\\Sample.Assembly.dll"); // Obtain a reference to a method known to exist in assembly. MethodInfo Method = SampleAssembly.GetTypes()[0].GetMethod("Method1"); // Obtain a reference to the parameters collection of the MethodInfo instance. ParameterInfo[] Params = Method.GetParameters(); // Display information about method parameters. // Param = sParam1 // Type = System.String // Position = 0 // Optional=False foreach (ParameterInfo Param in Params) { Console.WriteLine("Param=" + Param.Name.ToString()); Console.WriteLine(" Type=" + Param.ParameterType.ToString()); Console.WriteLine(" Position=" + Param.Position.ToString()); Console.WriteLine(" Optional=" + Param.IsOptional.ToString()); } 

即使在加载自定义程序集之后,也不能像通常那样简单地调用方法或使用类型。 看看这个从这个问题中偷来的例子,它应该指向正确的方向:

  Assembly assembly = Assembly.LoadFile("myAssembly"); Type type = assembly.GetType("myAssembly.ClassName"); if (type != null) { MethodInfo methodInfo = type.GetMethod("MyMethod"); if (methodInfo != null) { object result = null; ParameterInfo[] parameters = methodInfo.GetParameters(); object classInstance = Activator.CreateInstance(type, null); if (parameters.Length == 0) { //This works fine result = methodInfo.Invoke(classInstance, null); } else { object[] parametersArray = new object[] { "Hello" }; //The invoke does NOT work it throws "Object does not match target type" result = methodInfo.Invoke(classInstance, parametersArray); } } } 

看一下ILMerge ( 使用ILMerge合并.NET程序集的文章)

它应该允许您将DLL与您的代码合并,因此不会下载外部任何内容,也不会支付reflection成本,因此性能应该更好。

ILMerge获取一组输入程序集并将它们合并到一个目标程序集中。 输入程序集列表中的第一个程序集是主程序集。 当主程序集是可执行文件时,目标程序集将创建为具有与主程序集相同的入口点的可执行文件。 此外,如果主程序集具有强名称,并且提供了.snk文件,则使用指定的键重新签名目标程序集,以使其具有强名称。

另一个选择是从该DLL中删除强名称。 在这里看看C#中的assembly操作

Reflexil能够删除程序集强名称和更新引用程序集。 您也可以使用汇编编辑器自行完成:删除公钥并将HasPublicKey标志设置为false。