如何在Visual Studio 2017中运行MSBuild打包目标

8
我的问题类似于 thisthis
我想在 Visual Studio 2017 RC 中打包一个 .Net Framework 库。在使用 project.json 构建系统的 VS 2015 中,我能够通过将自定义 targets 文件导入到 .xproj 文件中来完成此操作。这个自定义 targets 文件负责创建 nuspec 文件(如果不存在),然后运行 nuget pack,将生成的 packages 复制到本地 feed 位置等。
在 2017 中,我需要做类似的事情吗(还没有认真尝试过),或者我可以在我的 .csproj 文件中启用 pack target?
文档 here 只显示从命令行运行 pack target 的方法。
编辑: 我正在尝试下面的自定义 target,引用来自 nightly builds 的 Nuget 4.0 exe...
<Target Name="PackNugets"  AfterTargets="Build">    
  <PropertyGroup>
    <NugetV4Path>$([System.IO.Path]::GetFullPath('path to nuget.exe'))</NugetV4Path>
  </PropertyGroup>

  <Exec Command="&quot;$(NugetV4Path)\nuget.exe&quot; pack &quot;$(MSBuildProjectDirectory)\$(PackageId).csproj&quot; -Symbols -OutputDirectory bin -Properties Configuration=Release"/>
</Target>

但是我收到了以下错误。
System.InvalidCastException: Unable to cast object of type 'System.String' to type 'NuGet.Frameworks.NuGetFramework'.
  at NuGet.ProjectManagement.NuGetProject.GetMetadata[T](String key)
  at NuGet.ProjectManagement.PackagesConfigNuGetProject..ctor(String folderPath, Dictionary`2 metadata)
  at CallSite.Target(Closure , CallSite , Type , Object , Dictionary`2 )
  at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
  at NuGet.CommandLine.ProjectFactory.AddDependencies(Dictionary`2 packagesAndDependencies)
  at NuGet.CommandLine.ProjectFactory.ProcessDependencies(PackageBuilder builder)
  at NuGet.CommandLine.ProjectFactory.CreateBuilder(String basePath, NuGetVersion version, String suffix, Boolean buildIfNeeded, PackageBuilder builder)
  at NuGet.Commands.PackCommandRunner.BuildFromProjectFile(String path)
  at NuGet.CommandLine.PackCommand.ExecuteCommand()
  at NuGet.CommandLine.Command.ExecuteCommandAsync()
  at NuGet.CommandLine.Command.Execute()
  at NuGet.CommandLine.Program.MainCore(String workingDirectory, String[] args)

这与csproj中的某个属性有关吗?NugetFramework是否指TargetFramework

我正在我的csproj中针对net452进行目标设置,如果有帮助的话。

编辑:该异常确实与nuget尝试解析TargetFramework有关,但不清楚它是在我的csproj还是依赖项上失败了...

4个回答

8

编辑:最新的VS2017更新已经在项目上下文菜单中添加了打包操作,因此可以更改以下操作:

  • AfterTargets=Pack
  • 删除Exec元素
  • 如果你正在针对多个框架进行操作,则需要在NugetPackages Include\bin后插入\$(Configuration)

好的,这个问题为我解决了。目前,我们必须使用dotnet而不是msbuildnuget

因此,在导入的.targets文件中,我的自定义目标变为

<Project ToolsVersion="15.0">
 <Target Name="PackNugets"  AfterTargets="AfterBuild">  

  <!-- Swap out nuget for dotnet and update the cli args -->
  <!-- Might actually be able to leave out the csproj path, since
       this target should run in the project directory. Test it first. -->
  <Exec Command="dotnet pack &quot;$(MSBuildProjectDirectory)\$(PackageId).csproj&quot; --no-build --include-symbols -o bin -c Release"/>

  <!-- If you want to copy to a local feed -->
  <ItemGroup>
    <NugetPackages Include="$(MSBuildProjectDirectory)\bin\$(PackageId).$(PackageVersion)*.nupkg"/>
   </ItemGroup>

  <Copy SourceFiles="@(NugetPackages)" DestinationFolder="path to local feed" />
 </Target>  
</Project>

运行 dotnet pack -c Release 或者将 RELEASE 替换为你的环境。对我来说有效。 - VictorV
最新版本的Visual Studio中有关Nuget集成的更多细节,请参阅此处:https://blog.nuget.org/20170316/NuGet-now-fully-integrated-into-MSBuild.html - Denis Pitcher

5
我想知道同样的事情,所以我在MSBuild文件中进行了搜索,即: C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Sdks\NuGet.Build.Tasks.Pack\build 并查找 "Pack" 目标。
除此之外,我建议您参考通用的MSBuild命令行语法这里,以下是几个示例:
msbuild.exe -t:Pack -p:IncludeSymbols=true
msbuild.exe -t:Pack -p:Configuration=Release -p:VersionSuffix="alpha" # or "-alpha" - not sure

编辑:经过进一步的研究和我的场景工作,我找到了这个文档,其中包含了重要属性。


到目前为止,我可能会像使用VS2015一样使用自定义目标在项目根目录上运行nuget打包,并确保引用v4 nuget。我简要尝试了从自定义目标调用msbuild cli,但似乎没有起作用。 - Ken G
使用NuGet打包时,我使用了prerelease=参数,那么msbuild pack支持prerelease吗? - red888

2
请注意,dotnet packmsbuild /t:Pack目前不支持.NET Framework项目,它们只适用于NETCore项目。

1
可能不被支持,但是 dotnet pack 对于 .NET Framework 项目确实有效。 - Ken G
我正在寻求通过msbuild打包一个目标为.net 4.6的.net类库。由于“pack”目标不存在,因此我可能需要返回到.nuspec文件和nuget.exe。 - MikeJansen
@MikeJansen,如果你想使用msbuild打包一个.NET框架项目,那么唯一的方法就是将其转换为基于.NETCore的项目,并且目标框架设置为net46。你可以通过选择“文件”->“新建项目”->“.NET Core类库”,然后编辑csproj文件以设置目标框架为net46。之后,你甚至可以右键单击该项目并使用VS进行打包。 - rohit21agrawal

1

如果您想使用以下方法推送nuget包,甚至可以改进Ken G的答案

<Target Name="PushNugetPackage" AfterTargets="Pack" Condition="'$(Configuration)' == 'Release'">
  <Exec Command="nuget.exe push -Source &quot;mysource&quot; -ApiKey VSTS $(OutputPath)..\$(PackageId).$(PackageVersion).nupkg" />
</Target>

只有在选择上下文菜单和配置为 Release 后,它才会运行,因此您不需要推送调试包,如果您确实不需要它,请删除该条件。 源代码

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接