C# 为.Net提供其他依赖于平台的.dll

C# 为.Net提供其他依赖于平台的.dll,c#,.net,wpf,dll,C#,.net,Wpf,Dll,我有一个应用程序(.Net 4.6.1,WPF),它需要在生产系统上运行一个特定的.dll(非托管)。DLL有两个版本(x64和x86)。如何(应该)为不同平台打包项目中的DLL 当然,有可能创建两个项目,一个仅针对x64,一个分别针对x86,但我希望避免这种开销 理想情况下,我会考虑像文件夹结构这样的东西 cwd/ app.exe component.dll lib/ x86/ provided.dll x64/

我有一个应用程序(.Net 4.6.1,WPF),它需要在生产系统上运行一个特定的.dll(非托管)。DLL有两个版本(x64和x86)。如何(应该)为不同平台打包项目中的DLL

当然,有可能创建两个项目,一个仅针对x64,一个分别针对x86,但我希望避免这种开销

理想情况下,我会考虑像文件夹结构这样的东西

cwd/
    app.exe
    component.dll
    lib/
        x86/
            provided.dll
        x64/
            provided.dll
其中,应用程序在启动时根据运行时平台(x64/x86)加载正确提供的DLL

不幸的是,我无法更改应用程序本身的程序集加载(在启动时自动完成)

关于搜索路径,我检查了[1],但找不到特定于平台的加载信息

有没有实现这一目标的方法(最佳实践)


[1] 它有办法做到这一点

简单的方法是将DLL编译为可以在x86和x64中使用的任何CPU,但您的DLL不受管理,可能无法编译为任何CPU

另一种方法是使用宏。在x86和x64中添加差异宏,如在x86中添加
x86

您可以编写代码来加载差异DLL

#if x86
        public const string DLL_FILE_NAME = "DLL_32.dll";
#else
        public const string DLL_FILE_NAME = "DLL_64.dll";
#endif

        [DllImport(DLL_FILE_NAME, EntryPoint = "Foo", CallingConvention = CallingConvention.Cdecl)]
        private static extern int Foo1(int var1, int var2);
另一种方法是使用两种方法来调用x64和x86

    [DllImport("DLL_32.dll", EntryPoint = "Foo",
        CallingConvention = CallingConvention.Cdecl)]
    private static extern int Foo32(int txcuiwKjvwu, int hhmzfadnHexkmr);

    [DllImport("DLL_64.dll", EntryPoint = "Foo",
        CallingConvention = CallingConvention.Cdecl)]
    private static extern int Foo64(int txcuiwKjvwu, int hhmzfadnHexkmr);
您可以使用
Environment.Is64BitProcess
将应用程序设置为x86或x64

   public int Foo(int txcuiwKjvwu, int hhmzfadnHexkmr)
    {
        if (Environment.Is64BitProcess)
        {
            return Foo64(txcuiwKjvwu, hhmzfadnHexkmr);
        }

        return Foo32(txcuiwKjvwu, hhmzfadnHexkmr);
    }
最新但并非最不重要的是使用
setdldirectory
设置目录

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool SetDllDirectory(string path);
   var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
      path = Path.Combine(path, Environment.Is64BitProcess ? "x64" : "x86");
      SetDllDirectory(path);
设置查找DLL的路径可以轻松加载一些不受管理的DLL

不幸的是,我无法更改应用程序本身的程序集加载(在启动时自动完成)

然后,您必须将应用程序与适当的DLL一起部署


你可以提供两个版本的应用程序;一个32位版本包括
x86/provided.dll
,另一个64位版本包括
x64/provided.dll
。然后,用户必须根据其CPU体系结构安装适当的版本。

感谢您的回复,但这些解决方案需要更改我无法控制的程序集加载过程(外部提供的代码,在启动时按名称加载程序集)。将FooX64.dll放在同一文件夹中时,会找到它,但会因x86运行时的badimage而崩溃,反之亦然。您需要以某种方式将应用程序与x64 dll一起分发到64位系统,反之亦然。您当前如何部署该应用程序?当前,该应用程序是通过处理优化的发布版本以及所需的DLL来部署的。在当前的生产环境中,只有x64设备,因此主应用程序(任何CPU)以及x64的DLL都可以正常运行。现场正在部署具有x64和x86体系结构(Win 7和Win 10)的新系统。应用程序应该可以在两个系统上运行,自动加载正确的DLL。由于我无法控制加载顺序本身,因此最好将两个版本中的DLL打包到(子)文件夹中,运行时链接器可以选择正确的DLL。问题是,这是可能的,还是我需要为它提供不同的应用程序二进制文件?如果你不能修改代码,你将不得不提供不同的二进制文件。但是,如果您手动复制应用程序文件,这应该不是问题。只需提供两个版本的应用程序;一个32位版本和一个64位版本。@mm8我很害怕。。。我希望在链接器级别上有另一个解决方案-谢谢你的澄清-祝你有愉快的一天!