How to run MSBuild pack target in Visual Studio 2017

14,781

Solution 1

EDIT: The latest updates to VS2017 have added the Pack action to the project context menu, so the below action can be changed as follows:

  • AfterTargets=Pack
  • Remove the Exec element
  • If you are targeting multiple frameworks, you may have to insert a \$(Configuration) after the \bin in the NugetPackages Include.

Ok, this issue solved it for me. For now, we have to use dotnet instead of msbuild or nuget.

So, my custom target in the imported .targets file becomes

<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>

Solution 2

I was wanting to know the same thing, so I went spelunking in the MSBuild files, namely: C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Sdks\NuGet.Build.Tasks.Pack\build and look for the "Pack" target.

Beyond that, I would refer to general MSBuild command line syntax here, but a few examples:

msbuild.exe -t:Pack -p:IncludeSymbols=true
msbuild.exe -t:Pack -p:Configuration=Release -p:VersionSuffix="alpha" # or "-alpha" - not sure

EDIT: A little more research and work on my scenario and I found this documentation of the important properties.

Solution 3

Please note that dotnet pack or msbuild /t:Pack currently doesn't support .NET Framework projects. They only work NETCore projects.

Solution 4

You can even improve Ken G answer if you want to push the nuget using this:

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

It will only run after you choose pack from context menu and configuration is Release, so you don't push debug packages, remove that condition if you really don't need it

Source

Share:
14,781
Ken G
Author by

Ken G

Updated on June 12, 2022

Comments

  • Ken G
    Ken G almost 2 years

    My question is similar to this and this.

    I want to package a .Net Framework library in Visual Studio 2017 RC. In VS 2015 with project.json build system, I was able to accomplish this by importing a custom targets file into the .xproj file. This custom targets file took care of creating the nuspec file if it didn't exist, then running nuget pack, copying the resulting packages to local feed location, etc.

    Do I need to do something similar in 2017 (haven't made a serious effort yet) or can I somehow enable the pack target in my .csproj file?

    The docs here only show to run the pack target from the command line.

    EDIT: I'm trying the below custom target referencing a Nuget 4.0 exe from the nightly builds...

    <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>
    

    But I get the following error

    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)
    

    Something to do with one of the properties in the csproj? Does NugetFramework refer to the TargetFramework?

    I am targeting net452 in my csproj, in case that helps.

    EDIT: That exception is indeed about nuget attempting to parse the TargetFramework, but it is not clear whether it is failing at my csproj or at a dependency...

  • Ken G
    Ken G about 7 years
    So far, I'm probably just going to do what I did with VS2015, and use custom targets to run nuget pack on the project root, making sure to reference v4 nuget. I briefly tried calling msbuild cli from a custom target, but that didn't seem to work.
  • Ken G
    Ken G about 7 years
    May not be supported, but dotnet pack does work for .NET Framework projects.
  • VictorV
    VictorV about 7 years
    Run dotnet pack -c Release or change RELEASE with your environment. Works for me.
  • MikeJansen
    MikeJansen almost 7 years
    I am looking to pack a .net class library target = .net 4.6 via msbuild. The "pack" target does not exist, so I'll probably need to go back to a .nuspec file and nuget.exe
  • rohit21agrawal
    rohit21agrawal almost 7 years
    @MikeJansen the only way you can pack a .NET framework project using msbuild if it is a .NETCore based project with target framework = net46 . You can do File -> New Project -> .NET Core Class Library and then edit the csproj to have target framework net46. You can then even right click the project and pack using VS.
  • Denis Pitcher
    Denis Pitcher about 6 years
    More details on the nuget integration in the latest version of Visual Studio is available here: blog.nuget.org/20170316/…
  • red888
    red888 about 5 years
    so with nuget pack I was using prerelease= does msbuild pack support prerelease ?