网上有大量关于创建 nuget 包的 Material ,但是,似乎也有大量的选项(dotnet pack、nuget.exe pack、msbuild t:pack 等)。我尝试了 official docs 中的几个建议,但我所能管理的就是将 *.dll 复制到使用项目的二进制输出文件夹中。我很挣扎,因为我在网上找到的大多数文档都没有提到文档是否谈论当前的 nuget 包输出文件夹或消费者。这种区别对我来说意义重大。
这就是我想要的
- 我有三个文件:some.dll、some.tlb 和 some.txt。包含在 myNuGetPackage.nupkg 中
- 当 msbuild 为消费 csproj 运行时,我希望将它们全部复制到消费解决方案/csproj 的二进制输出文件夹
- 使用
<PackageReference>
在消费 csproj 中 - 我不一定要构建 myNuGetPackage.csproj,因为我没有创建任何内容。我有这些文件并想将它们压缩。如果除了创建 myNuGetPackage.csproj 之外没有其他选择,我会这样做。
- 我希望解决方案尽可能简单。我更愿意打开一个像“nuget package explorer”这样的工具,添加我的三个文件,但我认为这是不可能的?
- 我认为这并不重要,但我想以 .NETFramework 4.8 为目标
这是我尝试过但失败的方法:
- 我只尝试使用
nuget.exe pack my.nuspec
创建我自己的 my.nuspec -
copyToOutput
来自contentFiles
see here
这是我的myPackage.nuspec
的确切内容
<?xml version="1.0"?>
<package >
<metadata>
<id>myPackage</id>
<version>1.0.0</version>
<authors>me</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>bla bla</description>
<dependencies>
<group targetFramework=".NETFramework4.8.0" />
</dependencies>
<contentFiles>
<files include="**/*.tlb" buildAction="None" copyToOutput="true" flatten="true" />
<files include="any/any/*.txt" buildAction="Compile" copyToOutput="true" flatten="true"/>
<files include="any/any/*.xml" buildAction="EmbeddedResource" copyToOutput="true" flatten="true"/>
</contentFiles>
</metadata>
</package>
我的文件结构是
lib\net48\my.dll
--> 被复制以构建消费者的输出
content\any\any\my.tlb
content\any\any\my.xml
content\any\any\my.txt
--> 这些都不会被复制来构建消费者的输出。
我注意到我的所有文件都包含在 .nupkg 中,并且所有文件都被提取到 <users>\packages\myPackage\1.0.0\content\any\any
不管我是否设置 copyToOutput
至true
或false
。这告诉我,copyToOutput
实际上应该将文件复制到使用的构建文件夹中。为什么它在我的情况下不起作用?
最佳答案
我会尽力将其分解。我创建了一个sample project如果您愿意,也可以跟随此处 ( https://github.com/BenjaminMichaelis/Samples/tree/main/CopyFilesInNugetPackage )。要生成 .nupkg,您只需运行 dotnet pack -o .
在根目录中。
首先在您的 nuget 项目的 .csproj 中。第一行对于模式来说是特殊的,告诉它在构建时不执行任何操作。 PropertyGroup只是一些标准设置。
有趣的是,在 ItemGroup 中,我们首先声明 Include=
它使用通配模式指向我们想要抓取的项目的相对路径。在我的示例存储库中,您会看到有一个 file3.json
在 TestFiles/Folder1 中,这不会被拾取,因为它只在 TestFiles 中搜索。然而,TestFiles/Folder1 中的 file2.html 确实被拾取,因为 ** 全局模式事先告诉它递归搜索。相同的逻辑适用于 markdown 和 .targets 文件。您可以使用此逻辑将所需的任何文件包含到 nuget 包中。 .targets 文件对于自动复制到目标项目至关重要。您可以更改这些值以从 bin 内或任何地方获取您想要的文件。
然后是PackagePath=
指向我们希望将其存储在包本身中的目录。
最终使用 dotnet pack -o .
打包项目后我可以使用https://github.com/NuGetPackageExplorer/NuGetPackageExplorer
轻松检查 .nupkg
文件以查看我的包裹内部并确保一切都像我预期的那样。 (如果您不想制作,我也将生成的 nupkg 包含在存储库中)。
CopyFilesNuget.csproj:
<Project Sdk="Microsoft.Build.NoTargets/3.7.0">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<NoWarn>NU5128</NoWarn>
<IsPackable>true</IsPackable>
<VersionPrefix>1.1.0</VersionPrefix>
</PropertyGroup>
<ItemGroup>
<None Include="TestFiles/*.json" Pack="true" PackagePath="TestFiles" />
<None Include="TestFiles/**/*.html" Pack="true" PackagePath="TestFiles" />
<None Include="Markdown/*.md" Pack="true" PackagePath="Markdown" />
<None Include="Build/CopyFilesNuget.targets" Pack="true" PackagePath="build\CopyFilesNuget.targets"/>
</ItemGroup>
</Project>
最后,要在 MyProjectName.targets 文件中复制生成的文件(.targets 扩展名对于 https://learn.microsoft.com/visualstudio/msbuild/customize-your-build?view=vs-2019&WT.mc_id=8B97120A00B57354#import-order 很重要),您可以执行以下操作:
CopyFilesNuget.targets:
<Project>
<ItemGroup>
<TestFilesFilesToCopy Include="$(MSBuildThisFileDirectory)../TestFiles/**/*.*"/>
<MarkdownFilesToCopy Include="$(MSBuildThisFileDirectory)../Markdown/*.*"/>
</ItemGroup>
<Target Name="CopyContent" BeforeTargets="Build">
<Copy SourceFiles="@(TestFilesFilesToCopy)" DestinationFolder="$(ProjectDir)TestFiles/%(RecursiveDir)" SkipUnchangedFiles="true" />
<Copy SourceFiles="@(MarkdownFilesToCopy)" DestinationFolder="$(ProjectDir)Markdown/%(RecursiveDir)" SkipUnchangedFiles="true" />
</Target>
</Project>
在这里,在第一个 ItemGroup 中,我们设置了要从 nuget 包中复制出来的目录的路径(我们在 csproj 中将它们设置为包中的目标),然后将其传递到复制任务中Target 作为 SourceFiles 变量。这些被复制到的位置是 DestinationFolder 值。
这里的一个重要部分是 <Target>
使用标签。这会自动被使用项目使用,并且 BeforeTargets 告诉它在 msbuild 顺序中的哪个位置运行(在本例中是在 Build 之前)。
使用此 nupkg 文件,您可以在其他项目中使用它,但您通常会这样做(来自 nuget.org、本地、私有(private) nuget feed 等)
如果有任何问题请告诉我!
关于c# - 如何创建一个 nuget 包,将文件复制到消费者的构建输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77542596/