Nuget 包在构建时不复制本机 DLL

Log*_*n K 5 c# nuget .net-standard-2.0

我正在尝试创建一个托管库并将其与 Nuget 打包。托管库使用另一个用 C 编写的 DLL,并通过 [DllImport] P/Invoke 调用进行调用。在项目的根目录中,我有一个类似以下的文件夹结构:

  • 根/运行时/win-x86/native/file.dll
  • 根/运行时/win-x64/native/file.dll

我没有使用 .nuspec 文件,而是从 .NET STandard 2.0 项目的 .csproj 文件生成 Nuget 包。我将这些文件包含在 .csproj 文件中。

<ItemGroup>
    <Content Include="runtimes\**" PackagePath="runtimes" Visible="true" />
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

nuget 包在 lib/netstandard2.0 目录中具有托管 DLL,甚至在 root/runtimes/RID/native 目录中具有非托管 DLL。使用此 nuget 包的项目可以完美安装并构建,没有错误。

消费者将与之交互的托管 DLL 尝试像这样使用本机 DLL

[DllImport("file_name.dll")]
private static extern IntPtr CscanHOpen(string connectionString);
//...
public void Open(string connectionString, int port) {
    _handle = CscanHOpen(connectionString, port);
}
Run Code Online (Sandbox Code Playgroud)

我从安装 nuget 包的项目中收到“文件无法找到”错误,当我查看构建目录时,我没有看到该非托管 DLL。我尝试使用目标文件将非托管 DLL 复制到使用项目的输出目录,但它从未显示。

ziv*_*kan 3

我一直在回顾这个问题,因为没有答案,所以我将重复我们在评论中讨论的内容。

NuGet 的功能runtimes仅适用于使用您的包的项目PackageReference,而不是packages.config. 事实上,尽管我是 NuGet 客户端团队的一员,但我实际上不确定这是否runtimes是 SDK 样式的项目功能,或者它是否也适用于传统项目。老实说,我希望它只适用于 SDK 样式的项目,因为它需要构建系统的其余部分知道如何使用这些资产。

因此,您的问题的答案是使用 SDK 样式的项目来测试您的包。所有 .NET Core 应用程序都是 SDK 样式,但您也可以编辑项目并将其更改<TargetFramework>netcoreapp2.2</TargetFramework>为“net48”,或者将 xml 标记设置为复数,并将值设置为以分号分隔的 TFM 列表。

另请注意,类库没有主机,因此没有 RID。因此您可能看不到运行时 dll。您需要确保使用该包的测试项目具有主机和入口点,例如控制台应用程序。

为了支持packages.config项目(可能还有使用的传统项目PackageReference),您需要将您自己的道具和目标文件捆绑到包中。你说你尝试过,但没有成功,不幸的是,这意味着你做错了。NuGet 对于如何命名props 和目标文件有一个约定。如果你做对了,那么你实现复制文件的方式就不起作用了。您可以使用 MSBuild 增加的详细程度,或msbuild -blMSBuild 结构化日志查看器结合使用来调试目标文件。

使用该runtimes功能非常罕见,我对此没有任何经验,也不知道如何支持传统项目,同时runtimes在 SDK 样式项目中使用集成支持。我建议您需要确保您的目标只有在不是 SDK 样式项目时才运行,但我不知道您如何检测到这一点。