这是解决您问题的有效解决方案:
将 2 个 DLL(x86 和 x64)添加到您的解决方案的子文件夹中。让它们“如果更新则复制”
参考您用于开发的正确 DLL,以便从您添加的 2 个 DLL 中进行调试。使其 Copy Local=false。
这样做是当您的应用程序启动时,DLL 不会自动加载。在您使用该程序集中的类型之前,它不会被加载。一旦发生这种情况,将在 .Net 中触发一个事件,询问它在哪里可以找到您的程序集。
因此,在第一次使用该程序集之前,请确保您将自己附加到该事件中。
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
在处理程序的内容中,确保您在请求时加载 DLL(x86 或 x64)。
static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
if (args.Name.Equals("MyFullAssemblyName")) {
var path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
if (IntPtr.Size > 4) {
var dll = System.IO.Path.Combine(path, @"MySubDir\MyDLL_x64.dll");
return System.Reflection.Assembly.LoadFile(dll);
}
else {
var dll = System.IO.Path.Combine(path, @"MySubDir\MyDLL.dll");
return System.Reflection.Assembly.LoadFile(dll);
}
}
return null;
}
瞧。您现在可以以 32 位和 64 位的方式运行您的应用程序。
除了在子文件夹中添加 DLL 之外,您还可以将它们作为嵌入式资源,然后像这样加载它们:
static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
if (args.Name.Equals("MyFullAssemblyName")) {
var ass = Assembly.GetExecutingAssembly();
if (IntPtr.Size > 4) {
var strm = ass.GetManifestResourceStream("the.resource.name.for.MyDLL_x64.dll");
var data = new byte[strm.Length];
strm.Read(data, 0, data.Length);
return Assembly.Load(data);
}
else {
var strm = ass.GetManifestResourceStream("the.resource.name.for.MyDLL.dll");
var data = new byte[strm.Length];
strm.Read(data, 0, data.Length);
return Assembly.Load(data);
}
}
return null;
}
这不适用于所有程序集。一些“混合”程序集往往会失败,除非它们是从磁盘加载的(可以通过在加载之前将它们写入磁盘来解决)。