-
Notifications
You must be signed in to change notification settings - Fork 258
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nuget.exe breaking relative path #7657
Comments
Can u describe the relative path part of this repro? |
Here is the line from my csproj:
Seems that 2 of my 5 projects in one solution seems to be having this problem. I thought it was at our code level but I don't see any code changes that would impact this as well as just swapping to an older nuget.exe resolves the issue. |
Reading a few of these may be helpful? |
Thank you. I will do some reading but still something must be broken within the system that has now caused an instability and broken backwards compatibility. |
I have the same issue. Please take a look at the original post and the part: E:\work\4e6219bf893eb490\ \packages\RabbitMQ.Client.3.6.2 There is a space between "4e6219bf893eb490" and "\packages\RabbitMQ.Client.3.6.2". In my case that space should be a folder name where my solution is located. When I replace the nuget.exe in the folder ".nuget" by the previous version (4.7.1) everything works fine, so this must be a bug introduced in version 4.9.2. |
@PNI-GS @bscheutjens I'm unable to reproduce the error. From the information provided, I can see that your project uses I created a sample repo, using the RabbitMQ tutorials. I created one project with no spaces in the path, and another one with spaces in the path. But my build was completed successfully. If you can't provide us with a sample reproduction, can you look at my sample and tell me what differences there are between my attempt and your repo? For example, I didn't include a nuget.config. Do you use a nuget.config? If so, which settings do you set? Can you reproduce on your local machine by downloading nuget.exe and running |
@PNI-GS @bscheutjens are you guys running Also, what is this path |
The If I'm correct, my recommendation is to delete the I'm creating a VM to download/install these old versions of VS onto, to test my theory, but it's slow to do all this. If you read this comment before I finish testing, you can test it more quickly than me. If this is the root-cause, then downloading new |
I'm using VS2013 Professional. We use SVN for version control and we auto ignore executables, so the nuget.exe is never added to SVN. So when somebody checks something out we always have to use the option "Enable NuGet Package Restore" on the solution from within VS (I'm not sure which command is executed), which creates the .nuget subfolder (if that was also not added to SVN) and and three files within. It appears the nuget.exe is downloaded and is always the latest version. Since yesterday this downloads version 4.9.2 and the solutions don't build anymore. When I replace nuget.exe with version 4.7.1, which I copied from another solution, the issue is solved and I'm able to build the solution again. Because, when you know this, it is very simple to reproduce I've attached the most simple project I could create which already has the issue. Please note I just created this solution, it has not been on SVN. I really didn't so anything special. I just created the solution, installed a random package and clicked "Enable NuGet Package Restore". After these steps I was unable to compile the solution. I get the following three errors (sorry that they are in Dutch):
The first two error messages are similar to the one from the first post, stating that a part of the folder can't be found. As you can see there is also a space. The correct path (which doesn't have any space in it) is shown in the last error message. |
Thanks for the sample, it was useful. I managed to get VS2013 installed on a VM today and test myself, and find the root cause. Unfortunately it doesn't have an obvious, simple solution Root causeChange to NuGet.exeIn NuGet 4.8 we added long path support, which involves setting the Why NuGet.exe is being called with a space in the SolutionDir pathThe reason that NuGet.exe is looking at a directory whose name is a space because in VS2013 when you tell it to enable package restore on the solution, it adds a NuGet V2-era NuGet.targets file to the solution, and makes your The path is being surrounded by double quotes to support spaces in the path. The reason a space is added to the end is easiest to show using examples of arguments on the command line, and what is available in
So, my guess as to why the space was being added to the end of the directory was to avoid the second case in the table above where the double quotes character got added to the path. WorkaroundsAffected customers can do either of two things to avoid this issue:
When "Enable package restore" is selected in Visual Studio 2012 or 2013's solution right click menu, it creates a directory named
This functionality was removed from Visual Studio 2015 and later, so customers can prepare for future upgrades by no longer using it before upgrading. Visual Studio 2013 will still restore packages on build, so it will not affect development work. If the customer has a CI build, they will need the build script call If a customer has a solution where package restore has already been enabled, the steps to undo the changes are not difficult, but there is no simple UI to do it automatically. It involves deleting the FixReverting support for long paths is not an option. One option is to trim trailing spaces from the solution path in NuGet.exe. There are some issues with this option. First, NTFS (and I expect other file systems) technically support directories whose name is just a single space. As unlikely as it is that anyone would want to use this, it's technically valid. This issue appearing only now that we enabled long path support is a good example of why we shouldn't make assumptions about characters in a path, so I fear trimming spaces may lead to new bugs in the future. The .NET team are removing path validation from the .NET runtime and just using the operating system's error codes when accessing files/directories, because of false positives and false negatives from their existing validation logic, particularly since different file systems on different operating systems have different rules. If the .NET runtime is removing validation/normalisation, we should learn from them and avoid adding any. Secondly, nuget.exe was only doing what it was told. Removing unwanted characters should be done at the source, not later in the workflow when we've lost context about whether it was intentional or not. Another option is to investigate changing NuGet.targets so that it no longer calls nuget.exe with a path containing a trailing space. Given that the NuGet team is no longer servicing VS2013, we cannot modify the NuGet extension. However, since enabling package restore on the solution automatically downloads the latest NuGet client (probably from the NuGet.CommandLine package), there's a chance that the NuGet.targets file is also downloaded (probably from the NuGet.Build package), so we might be able to simply push a new update of this package. This should be investigated. |
In addition to the workarounds I proposed in the comment above, I want to add a 3rd option: Edit
with
This is also my proposed fix for the issue, but we need to wait until next week for the people needed to approve fixes to old versions of VS to come back to work. However, my suggestion is still to avoid using "Enable NuGet Package Restore". It's simply not needed, even with VS2013 and no longer exists after that version. |
Thanks for the explanation. I just came back to the office from my holiday and I will check everything out and come back with a full reply. I do have one remark though. I totally understand you guys stopped supporting older version. However, in this case I really would like you to make an exception, if possible. In the situation as-is an issue is automatically pushed to certain users and that should be avoided, even if their version is no longer supported. |
As promised my full reply. First of all thanks for the detailed explanation. It makes things clear to me and I understand the reasons behind the proposed workarounds and the reason why this can't just be fixed. But more on these later on. Workaround 1 - Use older version Workaround 2 - Don't use Package Restore Workaround 3 - Replace a line in nuget.targets
Fix |
I have a project that also affected by this problem, but I use VS 2015. My csproj file has these two lines:
Workaround #1 is probably not a viable option, certainly not long term. Workaround #2 does not seem to be relevant, unless it is somehow related to the above entries. I see two checkboxes in the UI under "Package Restore" ("Allow NuGet to download missing packages" and "Automatically check for missing packages during build in Visual Studio"). Although these are not project-specific, I'm vaguely guessing that they might be related to that setting. I haven't tried changing those settings or manually setting RestorePackages to false, but if this is required, then this is not merely a VS2013 problem. Workaround #3 also does not seem to be relevant, since there is no PaddedSolutionDir entry in my NuGet.targets file. My local build is working fine. This problem is only happening on the CI build on TeamCity. The line that seems to set SolutionDir in NuGet.targets is:
It doesn't seem likely that that line could be responsible for adding a trailing space. |
It appears that the solution is to change the PackageOutputDir from |
Turns out my proposed fix was a red herring. It is consistently building correctly on one of the build agents and failing on the other. Not sure what the difference is between the two, so now I'm not sure if/how it's related the problem in this thread. |
@bscheutjens thanks for testing the workarounds and reporting the error with my 3rd workaround. I installed VS2017 on my VS2013 VM to test something, and I forgot I was using MSBuild 15. I'll make sure I test older msbuild versions for a better fix. @tombogle I did another test of using "Enable NuGet Package Restore" in VS2013, and it added the following lines to my
and near the end of the file, as a child of the root
This is in addition to creating a Since you see some of the above in your project that you use with VS2015, my best guess is that it was originally created, or at least used, in VS2010, VS2012 or VS2013, and someone had used "Enable NuGet Package Restore" on the solution. Newer versions of Visual Studio will not delete these changes, but after installing VS2015 onto my VM, creating new projects and trying things within the IDE, I can't find a way for any of these things to be added. New project templates don't contain it. |
@zivkan You're welcome and no problem. I'm happy to test any new possible fix. |
The line
|
… SolutionDir This allows it to work with the latest version of NuGet. Since some packages that HearThis needs require a more recent version of NuGet, I also added a conditional command to update nuget to the latest version if it already exists. (See NuGet/Home#7657 for background)
Well, I've solved my problems and I feel about 80% confident that what I did was at least mostly correct. Here's what I did:
I'm especially uncertain about that last part, as it seems like it ought to be the default behavior. I'm almost sure that when building in VS2015, it it using some other version of NuGet.exe because some of our packages claim to require a newer version that what I see in the .nuget folder. But since I found a plethora of very outdated versions in the .nuget folders of several different products, and since it appeared as though that was the difference on our build agents, I decided it was best to force this. (Interestingly, when I ran the build on the agent that I suspected of having the outdated version, the output seemed to suggest otherwise. Both agents seemed to claim to have the current version already.) In cleaning up various other projects, I discovered that one had already replaced the trialing space with a period. It appears that that solution works regardless of what version of NuGet is used. So if anyone needs to use NuGet.targets and wants it to work with older and newer versions of NuGet, that's probably a good approach. |
An update to my workaround 3, it should be possible to replace the PaddedSolutionDir definition for the Windows_NT OS with the following two lines:
I tested with VS2013 and VS2010. I didn't test with VS2012, but if it works with both the newer and older version, I feel confident. Another option is similar to what tombogle wrote earlier:
Although I haven't tested it. |
I tested this with VS2013 in combination with the current version of NuGet.exe (4.9.2) and the previous version (4.7.1). Both work.
I can't get this one to work. I replaced the existing two lines with this single line and what happens is that it creates extra subfolders in each project folder and puts the packages in each of those. In case of this test solution it does build, but when I try this on a live solution with multiple projects the packages are downloaded to these subfolders in each project, but the build fails with errors. All of these errors are on our internal NuGet packages (we use an internal package source for our commonly used libraries and components) and only the packages which have been released as a prerelease. Also all errors are on source files. I can't really post a screenshot because I would have to mask some parts and the masked image isn't really clear. |
Hello anyone still looking at this issue. I published a new NuGet.Build package, which is where Visual Studio gets the NuGet.targets file which is added to the solution. Therefore, anyone using the "solution right click -> Enable NuGet Package Restore" should no longer have build errors. Anyone who did this before the 20th of December should also be unaffected, since it was before we published the NuGet.CommandLine package that no longer used legal path normalization. Any customer affected, those who enabled the feature between the 20th of December and today, should manually edit their NuGet.targets file in the same way that the PR modified the file: https://github.com/NuGet/NuGet2/pull/125/files#diff-ded6a780d99e2610a3eebaafa90a4622 Change <PaddedSolutionDir Condition=" '$(OS)' == 'Windows_NT'">"$(SolutionDir) "</PaddedSolutionDir>
<PaddedSolutionDir Condition=" '$(OS)' != 'Windows_NT' ">"$(SolutionDir)"</PaddedSolutionDir> to <PaddedSolutionDir Condition=" '$(OS)' == 'Windows_NT' and HasTrailingSlash('$(SolutionDir)')">"$(SolutionDir)\"</PaddedSolutionDir>
<PaddedSolutionDir Condition=" '$(OS)' == 'Windows_NT' and !HasTrailingSlash('$(SolutionDir)')">"$(SolutionDir)"</PaddedSolutionDir>
<PaddedSolutionDir Condition=" '$(OS)' != 'Windows_NT' ">"$(SolutionDir)"</PaddedSolutionDir> |
I just reviewed this after coming across this problem and I am confused with the logic of the provided solution above. Shouldn't you change this:
...to this:
If Right? |
@brwertz80 sorry, I missed this back in August. Please review this comment, specifically the "Why NuGet.exe is being called with a space in the SolutionDir path" section. The generated command line needs the path to have zero or two trailing slashes, but one trailing slash is precisely the cause of the problem. |
Thanks @zivkan! Took me a bit to remember what I was asking but that makes sense now. 👍 |
Replacing in NuGet.targets worked for me. |
Details about Problem
NuGet product used (NuGet.exe | VS UI | Package Manager Console | dotnet.exe): NuGet.exe
NuGet version (x.x.x.xxx): 4.8.x+
dotnet.exe --version (if appropriate):
VS version (if appropriate): VS2017
OS version (i.e. win10 v1607 (14393.321)): Windows 2008R2 & Azure DevOps
Worked before? If so, with which NuGet version: 4.7.x
Detailed repro steps so we can see the same problem
...
Other suggested things
Verbose Logs
TeamCity:
E:\work\4e6219bf893eb490.nuget\nuget.targets(87,9): error : Could not find a part of the path 'E:\work\4e6219bf893eb490\ \packages\RabbitMQ.Client.3.6.2'.
Azure DevOps:
##[error].nuget\nuget.targets(87,9): Error : Could not find a part of the path 'D:\a\1\s\ \packages\RabbitMQ.Client.3.6.2'.
Sample Project
Very helpful if you can zip a project and paste into this issue!
Unfortunately I do not have a sample project I can provide at this time.
The text was updated successfully, but these errors were encountered: