使用 MSBuild 创建 NuGet 包
从代码中创建 NuGet 包时,会将该功能打包到一个组件中,该组件可以与任意数量的其他开发人员共享和使用。 本文介绍如何使用 MSBuild 创建包。 MSBuild 预安装了包含 NuGet 的所有 Visual Studio 工作负荷。 此外,还可以通过 dotnet CLI 借助 dotnet msbuild 来使用 MSBuild。
对于使用 SDK 样式格式的 .NET Core 和 .NET Standard 项目,以及任何其他 SDK 样式项目,NuGet 直接使用项目文件中的信息创建包。 对于使用 <PackageReference>
的非 SDK 样式的项目,NuGet 还使用项目文件来创建包。
默认情况下,SDK 样式的项目具有可用的包功能。 对于非 SDK 样式的 PackageReference 项目,需要将 NuGet.Build.Tasks.Pack 包添加到项目依赖项中。 有关 MSBuild 包目标的详细信息,请参阅作为 MSBuild 目标的 NuGet 包和还原。
用于创建包的命令 msbuild -t:pack
,其功能相当于 dotnet pack
。
重要
本主题适用于 SDK 样式的项目(通常是 .NET Core 和 .NET Standard 项目)以及使用 PackageReference 的非 SDK 样式的项目。
设置属性
创建包需要以下属性。
PackageId
,包标识符,在托管包的库中必须是唯一的。 如果未指定,默认值为AssemblyName
。Version
,窗体 Major.Minor.Patch[-Suffix] 中特定的版本号,其中 -Suffix 标识预发布版本。 如果未指定,默认值为 1.0.0。- 包标题应出现在主机上(例如 nuget.org)
Authors
,作者和所有者信息。 如果未指定,默认值为AssemblyName
。Company
,公司名称。 如果未指定,默认值为AssemblyName
。
此外,如要打包使用 PackageReference 的非 SDK 类项目,则需要满足以下要求:
PackageOutputPath
(调用 pack 时生成的包的输出文件夹)。
在 Visual Studio 中,可以在项目属性中设置这些值(在解决方案资源管理器中右键单击项目,选择“属性”,然后选择“包”选项卡)。 也可以直接在项目文件 (.csproj) 中设置这些属性。
<PropertyGroup>
<PackageId>ClassLibDotNetStandard</PackageId>
<Version>1.0.0</Version>
<Authors>your_name</Authors>
<Company>your_company</Company>
</PropertyGroup>
重要
为包提供一个在 nuget.org 中唯一或你使用的任何包资源的标识符。
以下示例显示了包含这些属性的简单、完整的项目文件。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageId>ClassLibDotNetStandard</PackageId>
<Version>1.0.0</Version>
<Authors>your_name</Authors>
<Company>your_company</Company>
</PropertyGroup>
</Project>
另外,还可以设置可选属性,例如 Title
、PackageDescription
和 PackageTags
,如 MSBuild 包目标、控制依赖项资产和 NuGet 元数据属性中所述。
注意
对于面向公共使用而生成的包,请特别注意 PackageTags 属性,因为这些标记可帮助其他人查找包并了解其用途。
有关声明依赖项并指定版本号的详细信息,请参阅项目文件中的包引用和包版本控制。 还可以使用 <IncludeAssets>
和 <ExcludeAssets>
特性直接在包中呈现依赖项的资产。 有关详细信息,请参阅控制依赖项资产。
添加可选说明字段
包的可选说明显示在包 nuget.org 页的“自述文件”选项卡上。 说明从项目文件的 <Description>
中或 .nuspec 文件的 $description
中拉取。
以下示例显示 .NET 包的 .csproj 文件中的 Description
。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PackageId>Azure.Storage.Blobs</PackageId>
<Version>12.4.0</Version>
<PackageTags>Microsoft Azure Storage Blobs;Microsoft;Azure;Blobs;Blob;Storage;StorageScalable</PackageTags>
<Description>
This client library enables working with the Microsoft Azure Storage Blob service for storing binary and text data.
For this release see notes - https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/storage/Azure.Storage.Blobs/README.md and https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/storage/Azure.Storage.Blobs/CHANGELOG.md
in addition to the breaking changes https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/storage/Azure.Storage.Blobs/BreakingChanges.txt
Microsoft Azure Storage quickstarts and tutorials - https://learn.microsoft.com/azure/storage/
Microsoft Azure Storage REST API Reference - https://learn.microsoft.com/rest/api/storageservices/
REST API Reference for Blob Service - https://learn.microsoft.com/rest/api/storageservices/blob-service-rest-api
</Description>
</PropertyGroup>
</Project>
选择唯一的包标识符并设置版本号
包标识符和版本号唯一标识包中包含的确切代码。
按照以下最佳做法创建包标识符:
该标识符必须在 nuget.org 和承载包的所有其他位置中是唯一的。 为了避免冲突,最好使用公司名作为标识符的第一部分。
使用点表示法遵循类似于 .NET 命名空间的命名规则。 例如,使用
Contoso.Utility.UsefulStuff
而不是Contoso-Utility-UsefulStuff
或Contoso_Utility_UsefulStuff
。 如果将包标识符与代码使用的命名空间匹配,这对使用者也很有帮助。如果生成展示如何使用另一个包的示例代码包,请附加
.Sample
作为标识符的后缀,就像Contoso.Utility.UsefulStuff.Sample
中一样。示例包依赖于原始包。 创建示例包时,请添加值为
contentFiles
的<IncludeAssets>
。 在内容文件夹中,排列名为 \Samples\<标识符>的文件夹中的示例代码,例如 \Samples\Contoso.Utility.UsefulStuff.Sample。
遵循以下最佳做法设置包版本:
一般情况下,将包版本设置为与项目或程序集版本相匹配,但这不是必须的。 如果将包限制为单个程序集,那么匹配版本很简单。 解析依赖项时,NuGet 自己处理包版本而不是程序集版本。
如果使用非标准版本方案,请确保考虑使用 NuGet 版本控制规则,如包版本控制中所述。 NuGet 主要与语义化版本控制 2.0.0兼容。
注意
有关依赖项解析的详细信息,请参阅使用 PackageReference 进行依赖项解析。 有关可帮助你了解版本控制的信息,请参阅以下系列博客文章:
添加 NuGet.Build.Tasks.Pack 包
如果将 MSBuild 与非 SDK 样式项目和 PackageReference 一起使用,请将 NuGet.Build.Tasks.Pack 包添加到项目中。
打开项目文件并在
<PropertyGroup>
元素后面添加以下内容:<ItemGroup> <!-- ... --> <PackageReference Include="NuGet.Build.Tasks.Pack" Version="6.7.0" PrivateAssets="all" /> <!-- ... --> </ItemGroup>
打开开发人员命令提示符(在“搜索”框中,键入“开发人员命令提示符”)。
用户通常习惯从“开始”菜单中启动“适用于 Visual Studio 的开发人员命令提示符”,因为它将使用 MSBuild 的所有必需路径进行配置。
切换到包含项目文件的文件夹,然后键入以下命令以安装 NuGet.Build.Tasks.Pack 包。
# Uses the project file in the current folder by default msbuild -t:restore
确保 MSBuild 输出指示生成已成功完成。
运行 msbuild -t:pack 命令
若要从项目中生成 NuGet 包(.nupkg
文件),运行 msbuild -t:pack
命令,它也会自动生成项目:
在 Visual Studio 开发人员命令提示处,键入以下命令:
# Uses the project file in the current folder by default
msbuild -t:pack
输出将显示 .nupkg
文件的路径。
Microsoft (R) Build Engine version 16.1.76+g14b0a930a7 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
Build started 8/5/2019 3:09:15 PM.
Project "C:\Users\username\source\repos\ClassLib_DotNetStandard\ClassLib_DotNetStandard.csproj" on node 1 (pack target(s)).
GenerateTargetFrameworkMonikerAttribute:
Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the input files.
CoreCompile:
...
CopyFilesToOutputDirectory:
Copying file from "C:\Users\username\source\repos\ClassLib_DotNetStandard\obj\Debug\netstandard2.0\ClassLib_DotNetStandard.dll" to "C:\Use
rs\username\source\repos\ClassLib_DotNetStandard\bin\Debug\netstandard2.0\ClassLib_DotNetStandard.dll".
ClassLib_DotNetStandard -> C:\Users\username\source\repos\ClassLib_DotNetStandard\bin\Debug\netstandard2.0\ClassLib_DotNetStandard.dll
Copying file from "C:\Users\username\source\repos\ClassLib_DotNetStandard\obj\Debug\netstandard2.0\ClassLib_DotNetStandard.pdb" to "C:\Use
rs\username\source\repos\ClassLib_DotNetStandard\bin\Debug\netstandard2.0\ClassLib_DotNetStandard.pdb".
GenerateNuspec:
Successfully created package 'C:\Users\username\source\repos\ClassLib_DotNetStandard\bin\Debug\AppLogger.1.0.0.nupkg'.
Done Building Project "C:\Users\username\source\repos\ClassLib_DotNetStandard\ClassLib_DotNetStandard.csproj" (pack target(s)).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:01.21
在生成期间自动生成包
若要在生成和还原项目时自动运行 msbuild -t:pack
,请将以下行添加到 <PropertyGroup>
中的项目文件内:
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
在解决方案上运行 msbuild -t:pack
时,会打包解决方案中可打包的所有项目(<IsPackable>
属性设置为 true
)。
注意
自动生成包时,打包时间会增加项目的生成时间。
测试包安装
发布包前,通常需要测试将包安装到项目的过程。 测试确保所有文件一定在项目中正确的位置结束。
可以在 Visual Studio 中手动测试安装,或是使用常规包安装步骤在命令行上测试。
重要
包是不可变的。 如果更正了问题,请更改包的内容并再次打包,重新测试时,仍将使用旧版本的包,直到清除全局包文件夹。 在测试每次生成时不使用唯一预发布标签的包时,这尤为重要。
后续步骤
创建包(.nupkg
文件)后,可以将其发布到选择的库,如发布包中所述。
你可能还希望扩展包的功能,或者支持其他方案,如以下主题所述:
最后,有需要注意的其他包类型: