Home: vsfeedback: msbuild /t:restore fails on ProjA (packageRef/.net461) w/ ref to ProjB (.netstandard)

Created on 8 Feb 2017  ·  45Comments  ·  Source: NuGet/Home

vsfeedback 801748 & https://developercommunity.visualstudio.com/content/problem/17821/restoring-packages-from-vs-and-from-the-msbuild-re.html

Given two net45 projects referencing, one referencing the other, if second is using the new way of declaring itss nuget dependencies using the new declaration style, restoring via "msbuild /t:restore" will fail the build, and from the VS context menus, the build will pass.

When restored from the command line, the subsequent build error is the following: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\NuGet\15.0\Microsoft.NuGet.targets(197,5): error : The project.json is referencing the project 'E:\Agent01\1\s\src\XXX\XXXe (net45)\XXX (net45).csproj', but an output path was not specified on an item in the ProjectReferencesCreatingPackages property. [E:\Agent01\1\s\src\XXX.Tests\XXX.Tests.csproj]

Rob: sounds like Proj1 depends on Proj2. Proj2 uses PackageReferences?

Restore PackageReference Bug

Most helpful comment

I put a workaround for the project.json issue based on code @bbowman wrote on this MyGet feed https://www.myget.org/F/msbuildsdkextras/api/v3/index.json. Install Microsoft.NuGet.Build.Tasks.Workaround

All 45 comments

This one is a dupe of https://github.com/NuGet/Home/issues/4515,
Repro step:

  1. Create .net framework 4.6.1 lib
  2. referenced a .net standard 1.4 lib.
  3. install newtonsoft.json as package reference in .net framework 4.6.1 lib
  4. msbuild /t:restore
  5. msbuild /t:build

the issue is during msbuild build,
In C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\NuGet\15.0Microsoft.NuGet.targets

it check ".xproj" extension to get ProjectReferencesCreatingPackages, since there is no xproj project, ProjectReferencesCreatingPackages is not specified.

nuget doesn't own this code, need to ask other team to fix this.

@zhili1208 and i worked on the workaround.
putting the following in your csproj after the targets import, avoids the build error in the simple case.
very weird that VS2017 targets still mention .xproj at all. Need to figure out how to address for 4.0.1 --
in Microsoft.NuGet.Targets (https://github.com/NuGet/NuGet.BuildTasks/blob/776bb2b300e1333a6bc3297d441eabba2d640264/src/Microsoft.NuGet.Build.Tasks/Microsoft.NuGet.targets)
<Target Name="ResolveNuGetPackageAssets" DependsOnTargets="$(ResolveNuGetPackageAssetsDependsOn)" Condition="'$(ResolveNuGetPackages)' == 'true' and exists('$(ProjectLockFile)')"> </Target>

We are seeing this issue as well. 2 .NET framework 4.6.2 libraries. A and B. A has a bunch of nuget references.

I've found the main difference I can see between a VS17 restore packages, which works, to a nuget restore is the project.assets.json.

Here is a snippet of what Restore Packages in VS17 generates for the project.assets.json for project B. This is the project that fails to compile.

  "project": {
    "version": "1.0.0",
    "restore": {
      "projectUniqueName": "B.csproj",
      "projectName": "B",
      "projectPath": "B.csproj",
      "outputPath": "B\\obj\\",
      "projectStyle": "PackageReference",
      "originalTargetFrameworks": [
        "net462"
      ],
      "frameworks": {
        "net462": {
          "projectReferences": {
            "A.csproj": {
              "projectPath": "A.csproj"
            }
          }
        }
      }
    },
    "dependencies": {
      "EntityFramework": {
        "target": "Package",
        "version": "6.1.3"
      }
    },
   "frameworks": {
      "net462": {
        "dependencies": {
          "EntityFramework": {
            "target": "Package",
            "version": "6.1.3"
        }    
      }
   }

Here is what nuget restore looks like (paths redacted, but I can get those if they seem important)

"project": {
    "version": "1.0.0",
    "restore": {
      "projectUniqueName": "B.csproj",
      "projectName": "B",
      "projectPath": "B.csproj",
      "outputPath": "B\\obj\\",
      "projectStyle": "PackageReference",
      "skipContentFileWrite": true,
      "originalTargetFrameworks": [
        ".NETFramework,Version=v4.6.2"
      ],
      "files": {
        "lib/net462/B.dll": "B.dll"
      },
      "frameworks": {
        "net462": {
          "projectReferences": {
            "A.csproj": {
              "projectPath": "A.csproj"
            }
          }
        }
      }
    },
    "frameworks": {
      "net462": {
        "dependencies": {
          "EntityFramework": {
            "target": "Package",
            "version": "6.1.3"
          }    
        }
      }
    }

So you'll notice where the VS17 restore packages has the dependencies tree directly in the root of the project (and also under frameworks.net462) but the regular nuget restore does not have the dependencies tree at the root of the project node.

What could cause these differences? I was under the impression VS17 was using NuGet 4.0.

If this is an issue that is to be fixed in a new drop, can anyone think of a workaround? The one above does NOT work for me.

For anyone else who comes by, I had to actually convert one of the projects to the packages.config style of nuget instead of the packagereference style. Then, I had to nuget restore prior to calling msbuild /t:restore;build.

@jabrown85 you mentioned "VS17 restore packages and regular nuget restore?
Could you explain more about that? what's "VS17 restore packages" and "regular nuget restore"?

Does "regular nuget restore" mean nuget.exe restore? VS17 restore packages means "auto restore"?

Yes exactly. Restoring via the VS17 solution context menu works. Using nuget cli directly does not.

@jabrown85 I can repro your issue, but the workaround above works for me, Did you put that under project node in your B.csproj?

I feel like I did. I recall putting it in both projects to be safe.
On Fri, Feb 17, 2017 at 4:36 PM Zhi Li notifications@github.com wrote:

@jabrown85 https://github.com/jabrown85 I can repro your issue, but the
workaround above works for me, Did you put that in your B.csproj?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/NuGet/Home/issues/4532#issuecomment-280785664, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAwR1zChEQRN52i49TpvcUw_bqG65JQaks5rdiECgaJpZM4L7GVl
.

the difference between nuget.exe restore and VS solution restore is project.assert file from nuget.exe restore contains "compile section" for A.csproj. This will hit the "ProjectReferencesCreatingPackages" Null issue.

@jabrown85 Can you verify the workaround again? Because the workaround totally skip the "ResolveNuGetPackageAssets", it should not hit that again.

Following is one example:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{59626FD2-8417-401E-8DFA-1FE4E5B1429E}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>ClassLibrary1</RootNamespace>
    <AssemblyName>ClassLibrary1</AssemblyName>
    <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Class1.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\ClassLibrary2\ClassLibrary2.csproj">
      <Project>{aee3c5d4-3184-48b8-90d1-813cc5fc6169}</Project>
      <Name>ClassLibrary2</Name>
    </ProjectReference>
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="EntityFramework">
      <Version>6.1.3</Version>
    </PackageReference>
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <Target Name="ResolveNuGetPackageAssets"
         DependsOnTargets="$(ResolveNuGetPackageAssetsDependsOn)"
         Condition="'$(ResolveNuGetPackages)' == 'true' and exists('$(ProjectLockFile)')">
</Target>
</Project>

I can confirm the workaround does not work for me. In the project I was working with I get errors regarding the assemblies referenced in project B that should be pulled down from NuGet for project B (xUnit/NSubstitute). I don't see any compilation errors referencing project A NuGet dependencies.

I'm not entirely clear on what the workaround is trying to accomplish but if it's skipping restore entirely for project B that would explain it. I need project B to bring in project A's NuGet packages AND restore project B's direct NuGet packages.

I see, so looks like the workaround avoided the "but an output path was not specified on an item in the ProjectReferencesCreatingPackages property" error but will got Project B NuGet dependencies error. will look into that. thanks for your infomation

I've been trying to get around this, as this completely breaks a build server scenario, making the new projet format unusable.

It seems that the code in the NuGet.PackageManager assembly, which is used by VS2017, is interacting differently with the restore process, and it's also not adding "placeholder" paths I can see when running the restore from the command line.

VS produces:

 "MyBinary/1.0.0": {
    "type": "project",
    "framework": "MonoAndroid,Version=v7.0"
  },

and Nuget CLI produces:

"MyBinary/1.0.0": {
    "type": "project",
    "framework": "MonoAndroid,Version=v7.0",
    "compile": {
      "bin/placeholder/monoandroid70/MyBinarydll": {}
    },
    "runtime": {
      "bin/placeholder/monoandroid70/MyBinary.dll": {}
    }
  },

The workaround specified above prevents any of the dependencies to be added to the build, so it's not working either.

Is there any other possible workaround ?

I didn't find a good workaround for this, if you remove following section from asset file:

"compile": {
      "bin/placeholder/monoandroid70/MyBinarydll": {}
    },
    "runtime": {
      "bin/placeholder/monoandroid70/MyBinary.dll": {}
    }

it will work, otherwise we need a fix in NuGet.BuildTasks

@jeromelaban The workaround I've got in place is not ideal but works. Project B has to revert and use the packages.config style NuGet. The build server then becomes nuget restore with nuget 4, msbuild /t:Restore;Build to get a proper build.

@jabrown85 Thanks for the workaround! Though I won't be able to use it in my case, since I'm using the <TargetFrameworks> node, and conditional package inclusion through the <PackageReference> node.

Even I were not to be using this, the fact that Package.config does not support transitive references makes it indeed not ideal :)

I'll try to write probably write a small task that sits before the BeforeBuild task and strips out the necessary data from the assets.json file, until this is fixed.

@jeromelaban can you post your msbuild task for others if you do indeed go that route? I assume it'll help out others in the same position.

@jabrown85 will do!

There you go: https://github.com/jeromelaban/NugetFixups

Deleting both the runtime and compile section fix the issue.

Btw, awesome work on the packing integration in the IDE! It makes this very easy to work with 👍

So I've now gone farther down the line, and I'm hitting more differences between the way the CLI differs from the VS Context Menu, only when using nodes.

  • For UWP heads (not libraries, afaik), the target platform generated by the CLI is confused by the Min and Target SDK versions. CLI forces the MinVersion as a runtime, while VS uses the Target version.
  • for some reason on my build server, a net46 mstest project raises this error C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\NuGet\15.0\Microsoft.NuGet.targets(197,5): Error : Your project.json doesn't have a runtimes section. You should add '"runtimes": { "win": { } }' to your project.json and then re-run NuGet restore., but there's no project.json file. Does not happen on my machine, either via CLI or VS. There must be a difference I'm not seeing.

Android and iOS projects can reference x-plat csproj fine, using my NuGetFix package.

@jeromelaban these are known issues. You can override the target framework property used in Visual Studio to fix this. See: https://github.com/NuGet/NuGet.BuildTasks/blob/dev/src/Microsoft.NuGet.Build.Tasks/Microsoft.NuGet.targets#L77

The TPMV issue is here: https://github.com/NuGet/Home/issues/4443

Need to review with RoslynProjectSystem team, but great fix for 4.0.1

When is this fix just going to "work"? If nuget 4.0.1 gets released will VS 2017 pickup the updated Build.Tasks?

The VS2017 release seems to have the same issue which I guess means this fix didn't make the release.

@jabrown85 this fix didn't make the release, VS will not pickup the fix when nuget 4.0.1 release, but next VS will release with nuget 4.0.1, VS release will pick up this fix.

@zhili1208 is there anyway to reference the updated Build.Tasks from a nightly build or anything (csproj change I'm guessing?)

Since it's open source project, you can git clone the repo and build it, https://github.com/NuGet/NuGet.BuildTasks, copy&paste all dlls and overwrite all files under C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\NuGet\15.0

Thanks. I wasn't sure if there was a version that would allow me to reference it in the proj file so my team didn't have to mess with the installed files. Thanks though! This still is useful to know as a last resort.

@jabrown85

You can include a patched version of Microsoft.NuGet.Build.Tasks.dll and Microsoft.NuGet.targets to your source code repository.

Somewhat like that: https://github.com/kekekeks/Perspex/commit/485fe1364eb4833edab133700d1eb0ce541af584#diff-1e14de79abf1c04cd7c5351c30ae82ffR1

I've done the update using 057af5b6ff9521551cf6dcee5cd737993a943472 (and small project.json updates to allow it to build under VS2017 without 2015 installed) and it works ! It's pretty awesome to be able to do that with such a core component of VS :) Thanks @zhili1208 !

I put a workaround for the project.json issue based on code @bbowman wrote on this MyGet feed https://www.myget.org/F/msbuildsdkextras/api/v3/index.json. Install Microsoft.NuGet.Build.Tasks.Workaround

I have created a repo demonstrating the issue with pure VS 2017 projects

https://github.com/Mertsch/NuGet-issue-4532

@onovotny That workaround package worked great!

@ctaggart glad it worked!! Hopefully it'll get fixed for real soon :-)

VS 15.1 is out, but this fix doesn't seem to have been released.

Yes, it would be nice to know as soon as we can remove workarounds from our projects. Will you update us?

@gulbanana @jnm2 I just checked VS 15.1, this fix is in that release, and I can't repro this issue any more. If you still hit the problem and get same error message, the msbuild might not be updated for some reason on your machine. If you get other error message, Please share the log, then I can take a look. thanks

@zhili1208 I was just waiting to see some release note confirming that it was time to try again. Just now, tested working on 15.1.26303.3! This resolves the project.json(1,1): error MSB4025: The project file could not be loaded. Data at the root level is invalid. Line 1, position 1. issue because now there is no more reason to use project.json with traditional csproj. I'm quite happy with how quickly this was resolved, only a month! Thank you!

dotnet msbuild -version returns 15.1.1012.6693
The problem I have is actually "Your project.json doesn't have a runtimes section.", which I thought was closed as a duplicate of this issue, but it might actually just be a misleading message. I'll try adding some <RuntimeIdentifiers> to my PackageReference-using old csprojes..

That didn't help, but I'll file a more-specific issue.

dotnet msbuild does not support old style csprojs.

I'm upgrading my .net 4.0 app to 4.7 and I referenced Roslyn and it's putting it in packagereferences instead of packages.config and my build is blowing up pretty hard... I called msbuild /t:restore but build still fails from the cli. Any ideas on how to resolve this in 15.2?

Another internal customer just hit this error with "ProjectReferencesCreatingPackages" -- when they had vs 2017 15.0 on their CI machine. Updating the CI machine to VS 2017 15.2 fixed it for them.

Okay. So we're still tracking this bug. And I bet its far down on the Github issues page because its so old.

Sigh.

Was this page helpful?
0 / 5 - 0 ratings