如何在项目生成成功后,自动构建 nuget 包并复制或发布到指定位置

1、原来的方式

在传统的 .net framework 类型项目下,我们可以通过 nuget 命令行创建 nuspec 描述文件,然后再通过命令行进行打包。如果需要自动打包的话,可以在项目属性中,找到生成后事件,在里面填写对应的命令行语句即可。只要写好对应的命令,以后在生成时就会自动打包发布了。(参考:https://docs.microsoft.com/zh-cn/archive/msdn-magazine/2011/november/nuget-manage-project-libraries-with-nuget

在新的 .net standard 或 .net core 类型项目下,虽然命令有所更换,但仍然也可以通过以上方式进行自动打包发布。

2、新的问题

但如果在混合目标框架的项目中,有部分内容是不被编译器支持的。

如不能使用 nuget 编译打包 .net standard 项目,告知需要使用 dotnet pack 命令,或者路径重复导致不能正常打包:

Error NU5012: 找不到“binReleaseprojectnameinRelease”。请确保已生成项目。

以及 dotnet 命令又对一些项目的引用不支持。

MSB4803: .NET Core 版本的 MSBuild 不支持“ResolveComReference”。请使用 .NET Framework 版本的 MSBuild。有关更多详细信息,请参阅 https://aka.ms/msbuild/MSB4803

就造成了无法通过一个命令编译通过混合目标框架的尴尬情况,也就无法通过第一点提到的方式进行新类型项目的打包发布。

3、解决方法

其实在新的 PackageReference 类型项目中,VS 直接提供了一个选项,在项目属性的“打包”配置中,可以勾选“在构建时生成 nuget 包”,这个构建不知道为什么,可以做到对两种目标框架的兼容,可能内部有一些判断吧,暂时还不清楚。

但是又产生了一个新的问题,这个方式的 nuget 包是在生成后事件执行完成后再打包的,所以原来的脚本(复制到指的位置及发布到指的 nuget 服务)是不能直接在生成后事件中使用的。

通过查找,在这个问题中找到了答案:

https://*.com/questions/47576451/net-core-2-0-generate-nuget-package-on-build-issue-with-post-build-events

并且官方文档也给出了说明:

https://docs.microsoft.com/zh-cn/nuget/reference/msbuild-targets#target-build-order

但需要手动修改项目文件,将原来的

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="nuget.bat" />
</Target>

其中 PostBuildEvent 修改为 Pack,如下:

<Target Name="CopyPackage" AfterTargets="Pack">
    <Copy SourceFiles="$(OutputPath)$(PackageId).$(PackageVersion).nupkg" DestinationFolder="D:\nuget" />
    <Exec Command="nuget.bat" />
</Target>

另外还有了直接可以进行复制的命令【Copy】,将 nupkg 可以不再通过 bat 执行复制到目标路径

然后依然可以执行命令行或bat,通过发布命令发布到指的的 nuget 服务:

nuget.exe push binReleaseprojectname.*.nupkg apikey -Source http://nugetserver

然后就好了~