NuGet / Home

Repo for NuGet Client issues
Other
1.5k stars 253 forks source link

nuget creates spurious space in path during build in VS 2019 #10704

Closed gallettoNL closed 3 years ago

gallettoNL commented 3 years ago

I need to upgrade NuGet.exe from 2.7.3 to address a SemVer versioning issue with preview packages, so I downloaded and installed Nuget 5.8.1. Then I ran into issues with a path generated by Nuget.exe, containing a spurious space (see logging below).

I could get around that by upgrading ALL projects but one (ASP.NET) to use package reference instead of packages.config, but apparently that's impossible for ASP.NET projects. What are we supposed to do now? I've seen various closed issues on the matter (https://github.com/NuGet/Home/issues/7657), but no solution as yet, as far as I can see....

Please advise.

Thanks!

NuGet product used (NuGet.exe | Visual Studio | MSBuild.exe | dotnet.exe): Visual Studio 2019 Version 16.9.2

Product version: 5.8.1

Worked before? If so, with which NuGet version: 2.7.3

Verbose Logs

43>C:\Users\will\Source\Repos\PLANproducten501.nuget\NuGet.targets(92,9): error : Kan een gedeelte van het pad C:\Users\will\Source\Repos\PLANproducten501\ \packages\Microsoft.AspNet.WebApi.Core.5.2.7 niet vinden. 43>C:\Users\will\Source\Repos\PLANproducten501.nuget\NuGet.targets(92,9): error : Kan een gedeelte van het pad C:\Users\will\Source\Repos\PLANproducten501\ \packages\Microsoft.AspNet.Razor.3.2.7 niet vinden. 43>C:\Users\will\Source\Repos\PLANproducten501.nuget\NuGet.targets(92,9): error : Kan een gedeelte van het pad C:\Users\will\Source\Repos\PLANproducten501\ \packages\Microsoft.AspNet.WebApi.Client.5.2.7 niet vinden. 43>C:\Users\will\Source\Repos\PLANproducten501.nuget\NuGet.targets(92,9): error : Kan een gedeelte van het pad C:\Users\will\Source\Repos\PLANproducten501\ \packages\Microsoft.AspNet.WebApi.WebHost.5.2.7 niet vinden. 43>C:\Users\will\Source\Repos\PLANproducten501.nuget\NuGet.targets(92,9): error : Kan een gedeelte van het pad C:\Users\will\Source\Repos\PLANproducten501\ \packages\Microsoft.AspNet.WebPages.3.2.7 niet vinden. 43>C:\Users\will\Source\Repos\PLANproducten501.nuget\NuGet.targets(92,9): error : Kan een gedeelte van het pad C:\Users\will\Source\Repos\PLANproducten501\ \packages\DevExpress.Web.Themes.19.2.7 niet vinden. 43>C:\Users\will\Source\Repos\PLANproducten501.nuget\NuGet.targets(92,9): error : Kan een gedeelte van het pad C:\Users\will\Source\Repos\PLANproducten501\ \packages\Microsoft.AspNet.WebPages.Data.3.2.7 niet vinden. 43>C:\Users\will\Source\Repos\PLANproducten501.nuget\NuGet.targets(92,9): error : Kan een gedeelte van het pad C:\Users\will\Source\Repos\PLANproducten501\ \packages\Microsoft.AspNet.WebHelpers.3.2.7 niet vinden. 43>C:\Users\will\Source\Repos\PLANproducten501.nuget\NuGet.targets(92,9): error : Kan een gedeelte van het pad C:\Users\will\Source\Repos\PLANproducten501\ \packages\Microsoft.AspNet.WebPages.WebData.3.2.7 niet vinden.

zivkan commented 3 years ago

@gallettoNL I provided a solution in the thread you linked at the time the issue was closed: https://github.com/NuGet/Home/issues/7657#issuecomment-469901706

A better solution would be to migrate to automatic package restore that does not depend on the files created by "Enable NuGet Package Restore" in VS2010, VS2012 and VS2013.

gallettoNL commented 3 years ago

Hi Andy, thanks for your link, I gave it another try.

I changed the lines in Nuget.Targets, but I still get this when using NuGet v 5.8.1:

43>C:\Users\will\Source\Repos\PLANproducten501.nuget\NuGet.targets(93,9): error : Kan een gedeelte van het pad C:\Users\will\Source\Repos\PLANproducten501\ \packages\Castle.Windsor.5.0.1 niet vinden.

This is an ASP.NET project.

I'm confused by this: "anyone using the "solution right click -> Enable NuGet Package Restore" should no longer have build errors." I don't see this option in VS 2019? You mean right-click on the solution in the Solution Explorer, right?

Migrating to automatic restore is tempting, but then I'll need to change all (about 100) project files in our solution, and I'm not sure it'll fix the issue of not having package references in the ASP.NET project.

Any ideas on that?

Cheers, Will de Haan

zivkan commented 3 years ago

I'm confused by this: "anyone using the "solution right click -> Enable NuGet Package Restore" should no longer have build errors." I don't see this option in VS 2019?

Correct, it was removed from VS2015 and later.

Migrating to automatic restore is tempting, but then I'll need to change all (about 100) project files in our solution, and I'm not sure it'll fix the issue of not having package references in the ASP.NET project.

Assuming that your projects were originally created in VS2013 or earlier, then whoever did the "solution right click -> Enable NuGet Package Restore" caused the 100 projects to be modified.

Additionally, assuming that the targets file is causing nuget.exe to restore your project on every build, you're experiencing slower performance because of it. NuGet does its own restore in Visual Studio before msbuild build is triggered, with intelligence on how to skip restore when it detects no package changes were made since the last restore. Plus restore in VS benefits from being able to restore all projects in parallel. Then MSBuild runs the "build" target, and the nuget.targets file in your repo is causing "nuget.exe restore" to run in a new process. This nuget.exe restore in a seperate process is duplicating effort that NuGet inside the devenv.exe process has already done, plus since it's a new process each time, it can't do the same "no restore required" check that the stateful NuGet-inside-VS can. And even if MSBuild is running multiple builds in parallel, it's not doing the same level as paralellism as NuGet does inside the VS process.

Any ideas on that?

project files are msbuild scripts, and msbuild is a programming language, despite looking like a declarative xml file. This means, like any programming language, there's infinite possibilities on how someone (a person or a tool) might have modified the files. The VS2010-2013 "enable nuget package restore" is the most common reason this error is encountered, and you appear to have a $(repo)\.nuget\nuget.targets file, which certainly suggests that someone in the project's history used that feature. However, if the instructions I provided in the original issue didn't solve it, then I'll need a sample to debug locally since it appears that your current state is different to the initial state I started with when debugging the original issue. Most people are understandably reluctant to share their closed-source software, even for these types of investigations. This can be done "securely" with Microsoft via Visual Studio's Developer Community (make sure to select the option to make the command visible to Microsoft only). Another option is if you can create a new solution and reproduce the issue, then I can investigate that "free from company intellectual property" sample. But that's going to be challenging since the feature no longer exists after VS2013.

Alternatively, you can do the same investigation that I would if I had a sample to debug. Run a build on the command line at increased verbosity (msbuild -t:build whatever.csproj -v:d), or get a binlog (msbuild -t:build whatever.csproj -bl) and open the msbuild.binlog file in the binlog viewer. You'll then want to find the RestorePackages target, see what the command line is passed to nuget.exe, understand why there's a space in the path given to it, and finally read the rest of the nuget.targets file to understand why the bad command line arguments were generated.

Actually, writing that all out gave me the idea that another possible solution is to replace the contents of your nuget.targets file with the original source. Check a diff between your copy and our copy, maybe you'll get a hint about what's wrong, and if it looks like a custom modification by someone who worked on that project in the past. However, you'll still be subject to the same performance penalty of "invoke nuget.exe restore once per project and wait for it to exit before actually running the build" in VS, and even on the command line it will do a per-project restore, rather than a single solution restore.

gallettoNL commented 3 years ago

Hi Andy, copying the original source for NuGet.Targets did the trick!

There were differences in PackagesProjectConfig Condition and in PaddedSolutionDir Condition

Thanks!

nkolev92 commented 3 years ago

Closing as the original problem has been addressed and there's no further action needed.

Sicos1977 commented 4 months ago

I got here because I had the same problem as the OP .... fixed it by removing the old nuget progress and enabling automatic package restore but now I ended up with this error:

NuGet package restore failed. Please see Error List window for detailed warnings and errors. Error occurred while restoring NuGet packages: An item with the same key has already been added.

Any tips about how to fix that because I already checked the packages.config and there are no duplicates in there.

zivkan commented 4 months ago

@Sicos1977 if you're using VS 2019, as is in the title of this issue, this version of VS is out of support except for security vulnerabilities.

If you're using VS 2022, there was a bug in 17.10.0, fixed in 17.10.2, released earlier this week:

Sicos1977 commented 4 months ago

I'm using Visual Studio 2022 and updated it yesterday and the problem is gone now.