Home: nuget.exe fails to pack NETCore project

Created on 3 Feb 2017  路  53Comments  路  Source: NuGet/Home

Using nuget.exe 4.0.0 build 2266

Steps

  1. Create a NETstandard class library
  2. nuget.exe pack <path to csproj>

Expected

Package will be created

Actual

Unable to cast object of type 'System.String' to type 'NuGet.Frameworks.NuGetFramework'.
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 build
IfNeeded, 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)
Pack Icebox 3 NuGet.exe Bug

Most helpful comment

Guys, I just got bitten by this and spent a DAY figuring it out. Why bother adding support for the new-format csproj if you aren't bloody well going to add support for the things inside that file, like PackageReference?

It's been two and a half years, for crying out loud and this isn't fixed, so it's pretty obvious it isn't going to be fixed. Meanwhile the current behaviour of generating an apparently-working NuGet package that has no dependencies listed is not only not helpful, it's actively harmful.

Pull your thumbs out and do what #7778 suggests. Right now you are just wasting developers' time.

All 53 comments

Let's discuss options here.
Seems like in rtm milestone, we should recommend "dotnet pack", right?

We already know this doesn't work. This is planned for 4.0.1

Yes dotnet pack or msbuild /t:pack

let's take a nuget.exe fix for rtm. Get it reviewed, tested and then merge - no shiproom needed.

perhaps something like:

In order to pack a .NET Core based project, use "dotnet.exe pack" or "msbuild /t:pack"

We already know this doesn't work. This is planned for 4.0.1

My main concern here is preventing the crash and improving the user experience. If it works or not is a different issue.

We should really look at the user experience here before shipping 4.0.0 RTM.

I have a F# "legacy" fsproj file referencing a project that targets net461 using the new csproj format.

I am also getting this error. Using dotnet pack or msbuild /t:pack does not work, as it will work only on the new project. Does this mean I have to run dotnet pack on one project and nuget pack on the other one? ( requires me manually enumerating the project files of each type in my build script).

Does this mean I have to run dotnet pack on one project and nuget pack on the other one?

@petertiedemann currently, yes. That is what you would need to do.

I worked around this by adding a Pack target to my legacy projects that ran an Exec with nuget.exe pack to pack the project, then it was possible to run Pack on all projects without manually splitting them up.

The workaround of manually packing different project types does not work if you have a legacy project referencing a non-legacy project.

We are now on version 4.1.0, how does this relate to the milestone of 4.0.2 this issue is still assigned to?

I noticed this was removed from the milestone and added to the backlog. Does this mean that packing SDK projects with the NuGet CLI is deprecated and we shouldn't expect it to work anytime soon?

Related to #5979

We have added a reference to NuGet.Build.Tasks.Pack in a .NET 4.6.1 project.

If we configure the TargetFramework property in csproj an error occurs:

The project system has enountered an error.

'dimensionValuesMap' must contain at least one element.
Parameter name: dimensionValuesMap

But if we set the TargetFramework property through the command line works fine:
msbuild.exe -t:Pack -p:Configuration=Release -p:TargetFramework=net461

Thanks in advance

... I had the same problem; and perhaps it's been noted since there are multiple issues: only on "older" .csproj project styles; which I only had projects targeting net471.

To solve: I simply deleted the .csproj files and pasted in new style files with

<TargetFramework>net471</TargetFramework>

... And dotnet pack will now run without complaint --- I am now simply able to run dotnet pack and push on all projects uniformly.

... But this might be an issue for full Wpf projects, since I'm not sure that the new project style will support the Xaml designer etc. (It's fine for me because the packaged projects are libraries, though they DO reference presentation framework core, and WindowsBase ... It works fine.)

This appears to still be an issue with 4.6.0 preview 3 (4.6.0.4825).

Additionally, dotnet pack is not a viable workaround due to https://github.com/dotnet/cli/issues/3959 which in turn references https://github.com/NuGet/Home/issues/3891

The latter was opened in November 2016. For internal package producers (a common use case for enterprise), this is quite problematic. The workarounds of maintaining particular references are highly undesirable.

Lastly, msbuild /t:pack does not appear to support including project references.

@awesley msbuild /t:pack is same as dotnet.exe pack. There are workarounds available in dotnet.exe/msbuild to include P2P references in the package. See: https://github.com/NuGet/Home/issues/3891#issuecomment-330668337

@daveaglick Backlog means that it's in the list of things that we will consider, it doesn't mean we won't be pursuing this. However, I can't give you an ETA for this right now.

@juanperezADD do you have a repro project i could look at for your problem?

@rohit21agrawal That is a highly undesirable workaround (that I will have to accept) due to the fact that it requires maintenance of such references.

This seems like a very common use case to me and I am having difficulty understanding the duration at which this issue has been allowed to persist. Surely it is significant in reducing adoption and improving developer experience.

@awesley are you worried about having to list down each P2P reference with the workaround provided and concerned that every time a P2P changes, you'll have to update this list? If that is the case, i can help you do this dynamically so it automatically obtains the list of p2p reference DLLs and adds it to your package.

I am aware that this is a significant issue and like I said, we do plan on fixing this really soon, and until then we plan on helping everyone get unblocked through means of workaround.

@rohit21agrawal That is it exactly - and a manner in which to do it dynamically would alleviate my concerns.

@awesley give me some time, will spend some time over the weekend and get back to you..if you have a particular P2P scenario, feel free to attach as a zip file (or a URL if it is open source, and i'll check it out).

@rohit21agrawal

We have decided to wait for the new version of VS 16.0 that will support the new csproj format in .NET projects (see https://github.com/dotnet/project-system/blob/master/docs/repo/roadmap.md).

Right now in the WPF projects we use a .nuspec file where we keep the dependencies updated manually (it includes references to projects and third party software such as NuGet packages).

Thanks for your interest.

In VS2017 under project properties, Select the Package tab.
There is an option there to Generate NuGet package on build.
This works for me on .Net Standard 2.0 libraries

In VS2017 under project properties, Select the Package tab.
There is an option there to Generate NuGet package on build.
This works for me on .Net Standard 2.0 libraries

Confirmed this works. Thank you solfried.

So.. it's Feb 2018 and this issue has been open for over a year and still no fix? .NET core and .NET standard are second-class citizens it seems.

@conficient it's not that .NET Core and .NET Standard are second-class citizens, they have first class support for packing through dotnet.exe, msbuild and VS.

@awesley One workaround that would work with dotnet.exe pack or msbuild /t:pack if you are packing a project with project references and want to include references as DLLs instead of dependencies in output nuspec:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>netstandard2.0;net47</TargetFrameworks>
    <TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\ClassLibrary2\ClassLibrary2.csproj" PrivateAssets="all" />
    <ProjectReference Include="..\ClassLibrary3\ClassLibrary3.csproj" Condition="'$(TargetFramework)' == 'net47'" PrivateAssets="all" />
  </ItemGroup>

  <Target Name="CopyProjectReferencesToPackage" DependsOnTargets="ResolveReferences">
    <ItemGroup>
      <BuildOutputInPackage Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" />
    </ItemGroup>
  </Target>
</Project>

Documentation for these extension points in the pack target can be found here: https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#advanced-extension-points-to-create-customized-package

Nuget push/pack is suggetsed in VS online build and packaging document then ending up with frustrating error like "System.InvalidCastException: Unable to cast object of type 'System.String' to type 'NuGet.Frameworks.NuGetFramework'"

This document also should be probably updated
Publish NuGet packages from Team Build to Package Management
which suggests NuGet push / pack, but does not mention that it will not work for core projects

Any plans to fix, the issue is already more than one year old :(

and it is this kind of politics that push users over to python, java and other non-.net languages: the frustration that common issues just get put on the long run. I'M GETTING TIRED OF YOUR ENTIRE "WE LISTEN TO USER FEEDBACK" TO THEN NOTICE THAT YOU DON'T GIVE A SHIT ABOUT USER FEEDBACK. you wonder why apple is so popular? THEY SOLVE ISSUES INSTEAD OF POSTPONING THEM!!!!!!!!!!!!!!!!!!! grow a pair and start doing the job you're all getting payed for at MS. this is why I'm disliking agile development: NOBODY GETS THE JOB DOME WITH ALL THIS DEBATING AND ABUSING THE PHILOSOPHY BEHIND AGILE

@d4e666 Is something blocking you from using dotnet.exe pack or msbuild /t:pack? Because those support .NET Core projects just fine.

the major issue I have is that I try to get all this running on VSTS to pack all projects after a successful RELEASE built and afaik VTST does not have a task for dotnet build (yet)

I even have another big issues with the fact that you have a great framework with nuget and that now you are creating yet another framework to do exactly the same thing. Why do you at MS keep creating the same thing over and over again??? Either think your solutions through or create a shitty version and stick to that. The major issue most developers have with .NET is the constant inconsistencies in the tooling. I can understand dat .NET and .NET core are 2 different runtimes, but this doesn't mean that the tooling should be completely different as well. I don't see a nuget packagemanager besides a dotnet package manager either, so why should the packing engine be any different. Behind the scenes I don't care that nuget is split, just keep the frontend consistent. as long as both abide an interface like IPackager for instance, you're set for the future without having to worry that the visual or CI interfaces have to change making automation a lot easier

PS. think about the seperation of UI and the logic for ALL future projects instead of creating your scala of utilites you have to support, I'd rather see a single tool backuped by several indendent teams than 2 completely different utilities that tend to get lost in the vast swamp of support websites at MS

@d4e666 i am sorry about the confusion in VSTS. Running msbuild on a NETCore project in VSTS is the same as running dotnet build. And therefore, running msbuild /t:pack on VSTS is the same as running dotnet pack on a NETCore project.

There is a dotnet tool to do all the commands you can use from dotnet.exe on VSTS:

image

I was having this same issue when trying to run NuGet.exe pack on a new-style project. I just tried it with NuGet 4.7.0 and it seems to work. Maybe some others that were having this problem can try and verify.

@thomas-hammond please don't use NuGet.exe to pack new-style (SDK Style Package REference based projects). While it won't error out, it would skip packing any package references as dependencies in the nuspec of the produced package

@rohit21agrawal Does that mean that all SDK Style projects need to use the built-in packaging support? Is there any plan to make NuGet.exe support this? The only reason I ask is that it is nice to have the separate nuspec file as the place where the details are kept. Also, what does this mean for teams that want to do all packaging at the end of the build and unit test phase?

unfortunately I can't give a timeline on when NuGet.exe will support SDK style projects, but that will happen, yes.

I am not sure I understand why you want NuGet.exe to pack SDK style projects given the in-built packaging support (in msbuild and dotnet.exe) for packing those projects. Could you elaborate on this:

The only reason I ask is that it is nice to have the separate nuspec file as the place where the details are kept.

@rohit21agrawal We have an MSBuild-based build system we developed that does our NuGet packaging at the end based on the existence of the nuspec file. It runs after build and unit tests. If NuGet.exe worked, I wouldn't have to make any changes to our system. I can try working in support for the built-in packaging. Maybe it will end up working out better.

at the end of the existence of the nuspec file? Is this nuspec file generated dynamically? If you are using a nuspec file to create the package, using NuGet.exe is perfectly fine.

Sounds like I have a similar situation at work. We have an MSBuild-based build system for a fairly large project (~1700 C# projects, out of which ~400 are built as nuget packages). We do the nuget packaging at the end of our CI run, after unit tests pass etc. We do have nuspec files for all the packages, but we only have basic package metadata in them - we don't manually put package dependencies there, rather we rely on nuget.exe to generate them for us automatically on the fly (both dependencies on external nuget packages that are installed in a given project and dependencies on our own ones that are getting built in the same solution thanks to the IncludeReferencedProjects nuget.exe option).

Do the MSBuild package task or dotnet pack support IncludeReferencedProjects? They didn't when I last checked sometime in 2017.

are these all packages.config based projects?

Most of them (99%), yes, but we're starting to selectively migrate to PackageReference - for now only in end applications, not in projects built as packages, but eventually we'd like to be using SDK style projects and PackageReference across the whole codebase.

A related problem for us right now is that we also want to start migrating our packages to .NET Standard, which as I understand means we have to use SDK style projects. This leads to a situation where, if we have package A which depends on package B (from the same solution), and we retarget B to .NET Standard, then when we package A, the packaging tool must correctly interpret B as well (so that it builds package A with a dependency on B - and on a correct version of it).

In the current state of the MS/.NET tooling, we're stuck - nuget.exe can't package SDK projects and we're not really into changing our build system which is battle-tested and stable. We will eventually do that to modernize it, but definitely not as a first step when we're not even sure how it will all work out. Our vision is that we keep the build system (probably update VS/MSBuild/nuget.exe to the latest versions) and start gradually migrating projects to SDK style csproj's, PackageReference and .NET Standard. If at the end we manage to migrate everything, we'd like to switch the build system to pure MSBuild (with nuget.exe only for pushing packages) or to the dotnet cli, if they provide feature parity to nuget.exe pack.

It would be great if nuget.exe (or msbuild.exe) could figure out the dependencies to bring in when packing Nuget files from PackageReference-style csproj files targeting .Net Framework output

@rohit21agrawal We have pretty much the same issue as @jjanuszkiewicz, although on a smaller scale.

Is there any progress on this that is documented elsewhere or will including PackageReferences using nuget pack be unsupported for the forseable future?

After a lot of work migrating all of our projects to the new project format, it is very frustrating to realize that our build system cannot both build maintenance branches and new branches post project updates due to nuget pack not working in both cases. I also can't change the system to use msbuild since the Pack task is not installed in our older branches.

The only option I'm left with is creating two build chains, one for old and one for new. I'd really like to avoid that...

I have the same problem too because I can only migrate to PackageReference but not the new csproj format because XAML is not yet supported in the new csproj system. So I wrote a small PowerShell function:

function Add-NuGetDependencyFromCsprojToNuspec($PathToCsproj, $PathToNuSpec)
{
    $csproj = [xml](Get-Content $PathToCsproj)
    $packageDependency = $csproj.Project.ItemGroup.PackageReference | Where-Object { $null -ne $_ }
    $nuspec = [xml](Get-Content $PathToCsproj)

    $dep = $nuspec.CreateElement('dependencies', $nuspec.package.metadata.NamespaceURI)

    $packageDependency | ForEach-Object {
      $onedependency = $dep.AppendChild($nuspec.CreateElement('dependency', $nuspec.package.metadata.NamespaceURI))
      $onedependency.SetAttribute('id', $_.Include)
      $onedependency.SetAttribute('version', $_.Version)
    }

    $nuspec.package.metadata.AppendChild($dep)

    $nuspec.Save($PathToNuSpec)
}

@bergmeister Thanks! We are running the following script based on the one you provided to automate the process in our CI/CD environment:

Get-ChildItem -recurse | 
    where {$_.extension -eq ".nuspec"} |
    Foreach-Object {
        $PathToCsproj = $_.DirectoryName + "\" + $_.BaseName + ".csproj"
        $PathToNuSpec = $_.DirectoryName + "\" + $_.BaseName + ".nuspec"
        $csproj = [xml](Get-Content $PathToCsproj)
        $packageDependency = $csproj.Project.ItemGroup.PackageReference | Where-Object { $null -ne $_ }
        $nuspec = [xml](Get-Content $PathToNuSpec)

        $dep = $nuspec.CreateElement('dependencies', $nuspec.package.metadata.NamespaceURI)

        $packageDependency | ForEach-Object {
          $onedependency = $dep.AppendChild($nuspec.CreateElement('dependency', $nuspec.package.metadata.NamespaceURI))
          $onedependency.SetAttribute('id', $_.Include)
          $onedependency.SetAttribute('version', $_.Version)
        }

        $nuspec.package.metadata.AppendChild($dep)

        $nuspec.Save($PathToNuSpec)
    }

@Rzpeg I suppose you don't have any project-references that you include directly? I mean, if you have project references that also generate nuget packages, this should work.

In one of our solutions only one project generates a nuget package. Meaning I'd have to expand this to recursively iterate over all project dependencies and include their PackageRefereces as well.

@gautelo You are right, it won't work in your case.
I only have project references, that are built as nuget packages as well. The packages are built with
"nuget pack -IncludeReferencedProjects", after patching nuspecs with the script above, and everything is fine.

Please share the script if you happen to expand it.

Scenario: Creating a nuget package from a csproj, targeting 4.6.2 with package references.

  • nuget.exe pack doesn't work as dependencies are not inferred.
  • After adding the nuget.build.tasks.pack nuget, fixing the csproj to import the target file, msbuild /t:pack gives the below error.
    msbuild /t:pack /p:PackageOutputPath="..\Packages" /p:TargetFramework=net462 /p:Authors="CI" /p:PackageVersion=2.0.0

C:\Users\.nuget\packages\nuget.build.tasks.pack\5.0.2\build\NuGet.Build.Tasks.Pack.targets(216,15): error MSB4064:
The "ProjectReferencesWithVersions" parameter is not supported by the "PackTask" task. Verify the parameter exists on the task, and it is a settable public instance property. [XXX.csproj]
C:\Users\XXX.nuget\packages\nuget.build.tasks.pack\5.0.2\build\NuGet.Build.Tasks.Pack.targets(199,5): error MSB4063: The "PackTask" task could not be initialized with its input parameters. [XXX.csproj]

related to #4254

Use dotnet task with pack option. That worked for me with multiple platform project.

Guys, I just got bitten by this and spent a DAY figuring it out. Why bother adding support for the new-format csproj if you aren't bloody well going to add support for the things inside that file, like PackageReference?

It's been two and a half years, for crying out loud and this isn't fixed, so it's pretty obvious it isn't going to be fixed. Meanwhile the current behaviour of generating an apparently-working NuGet package that has no dependencies listed is not only not helpful, it's actively harmful.

Pull your thumbs out and do what #7778 suggests. Right now you are just wasting developers' time.

We are now actively investigating implementing #7778. We currently don't plan to add the ability to pack SDK style projects to nuget.exe.

This is really very depressing, since we have already a lot of automation scripts built upon "nuget pack".

After converting a project from "packages.confg" to "PackageReference", we now have to add referenced package one by one manually; that is really pain, especially the missing of dependency will only be known when we run a project.

I really donot think this patching needs two years, as the dependencies are listed under the project references in our very eyes.

Was this page helpful?
0 / 5 - 0 ratings