Anycpu nuget包需要32位或64位包

ant*_*ell 5 .net 32bit-64bit nuget nuget-package

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

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

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

我想我要么必须有2个版本的"my_shared_library",要么可能在运行时根据运行时位选择正确的32位/ 64位nuget包"non_anycpi_dependency".

有人解决了这个问题吗?由于大多数数据库dll都不是anycpu,我认为这是一个常见的问题.

提前致谢,

Han*_*ant 10

有人解决了这个问题吗?

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

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

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);
Run Code Online (Sandbox Code Playgroud)

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

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"
Run Code Online (Sandbox Code Playgroud)

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