Anycpu nuget 包需要 32 位或 64 位包

Anycpu nuget package the requires either 32 bit or 64 bit package

我有一个 (anycpu) nuget 包 "my_shared_library",它必须引用一个 32 位或 64 位的 nuget 包 "non_anycpu_dependency"(它是数据库访问 dll)。

我希望 32 位和 64 位应用程序都能够使用 "my_shared_library"。

如何让 32 位和 64 位程序都使用 "my_shared_library"?

我在想我要么必须有 2 个版本的 "my_shared_library",要么可能在 运行 时有某种方法来选择正确的 [=27= 的 32 位/64 位 nuget 包] 基于 运行 时间位。

有人解决过这个问题吗?由于大多数数据库 dll 不是任何 cpu,我认为这是一个常见问题。

提前致谢,

一旦您引用了针对特定位数的包,您就会陷入困境。您可能能够获得足够的间接编译,但您最终会在运行时得到 BadImageFormatException

您可以做的是创建一个 AnyCPU 程序集,其中包含与您拥有的特定程序集中找到的具体实现相匹配的接口。那么您所有的 AnyCPU 程序集都应该只引用接口。

在要驱动应用程序的 EXE 中,您必须选择它是 64 位还是 32 位。在此 EXE 程序集中,您可以适当地引用原始 32 位或 64 位程序集(或 nuget 包)。

要使用此解决方案,诸如 Autofac、StructureMap 或 Unity 之类的依赖项注入框架将有助于减少管理向您的 类 提供具体实现的痛苦。

Has anyone solved this problem?

是的,微软有。他们需要为他们的 SQL Server Compact 包解决这个完全相同的问题。它有一个托管程序集 System.Data.SqlServerCe.dll,充当托管程序的适配器,以及一堆实现实际数据库引擎的本机 DLL。它们绑定到本机 DLL 入口点的方式不是我推荐的方式,我会假设您使用 pinvoke。我推荐你使用this technique来保证客户端程序可以运行 AnyCPU.

重复post的本质,您想在初始化方法或静态构造函数中的某处执行此代码:

public static void SetupDatabaseBinaries() {
    var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
    path = Path.Combine(path, IntPtr.Size == 8 ? "amd64" : "x86");
    bool ok = SetDllDirectory(path);
    if (!ok) throw new System.ComponentModel.Win32Exception();
}

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool SetDllDirectory(string path);

唯一重要的步骤是让用户的项目将本机 DLL 复制到项目的 amd64/x86 目录中。这需要一个 post-build 步骤,就像 Compact 包那样。您需要下载 Nuget 包以查看他们是如何做到这一点的,这不是很简单。 运行 VS 提升,创建虚拟控制台模式项目并检索 Sql Server Compact 的 Nuget 包。安装后,使用 Project + Properties,Build events 选项卡并注意它是如何添加此 post 构建事件的:

if not exist "$(TargetDir)x86" md "$(TargetDir)x86"
xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\x86\*.*" "$(TargetDir)x86"
if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64"
xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64"

没什么,它只是创建 x86 和 amd64 子目录并将 DLL 复制到其中。棘手的部分是让您的 Nuget 包添加此构建事件。查看包文件夹,了解完成此操作的魔法。您可能希望尽可能地遵循示例以避免错误。查看 packages\Microsoft.SqlServer.Compact.4.0.8876.1\tools 目录,它包含两个执行此操作的 PowerShell 脚本文件。 Install.ps1 运行s 在安装结束时。创建 post-build 步骤的函数在 VS.psm1,Add-PostBuildEvent 中。祝你好运。