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

时间:2019-05-15 17:38:05

标签: c# nuget .net-standard-2.0

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

  • root / runtimes / win-x86 / native / file.dll
  • root / runtimes / win-x64 / native / file.dll

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

<ItemGroup>
    <Content Include="runtimes\**" PackagePath="runtimes" Visible="true" />
</ItemGroup>

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);
}

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

1 个答案:

答案 0 :(得分:1)

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

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的传统项目),您将需要bundle your own props and targets file in the package。您说您尝试过,但没有成功,不幸的是,这只是意味着您做错了。 NuGet关于如何必须命名道具和目标文件的约定。如果您做对了,那么实现复制文件的方式就行不通了。您可以使用MSBuild增加的详细程度,也可以结合msbuild -blMSBuild structured log viewer来调试目标文件。

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