Skip to content

Commit

Permalink
Handle unsupported paths in ProjectInSolution.AbsolutePath
Browse files Browse the repository at this point in the history
dotnet#5950 introduced a call to `Path.GetFullPath()` to get a path that is normalized.  However, in some cases Visual Studio stores unsupported paths which will cause `Path.GetFullPath()` to throw.

`Path.GetFullPath()` can also throw a `PathTooLongException` which is now handled.

Fixes dotnet#6236
  • Loading branch information
jeffkl committed Mar 10, 2021
1 parent 7bc761a commit 97a9a16
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 7 deletions.
61 changes: 61 additions & 0 deletions src/Build.UnitTests/Construction/SolutionProjectGenerator_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2477,6 +2477,67 @@ public void DirectorySolutionPropsTest(string projectName, bool enable)
}
}

/// <summary>
/// Regression test for https://github.com/dotnet/msbuild/issues/6236
/// </summary>
[Theory]
[InlineData("http://localhost:8080")]
[InlineData("a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-a-really-long-string-")]
public void AbsolutePathWorksForUnsupportedPaths(string relativePath)
{
string solutionFileContents =
$@"
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31025.194
MinimumVisualStudioVersion = 10.0.40219.1
Project(""{{E24C65DC-7377-472B-9ABA-BC803B73C61A}}"") = ""WebSite1"", ""{relativePath}"", ""{{{{96E0707C-2E9C-4704-946F-FA583147737F}}}}""
ProjectSection(WebsiteProperties) = preProject
UseIISExpress = ""true""
TargetFrameworkMoniker = "".NETFramework,Version%3Dv4.0""
Debug.AspNetCompiler.VirtualPath = ""/localhost_8080""
Debug.AspNetCompiler.PhysicalPath = ""C:\Users\UserA\Documents\My Web Sites\WebSite1\""
Debug.AspNetCompiler.TargetPath = ""PrecompiledWeb\localhost_8080\""
Debug.AspNetCompiler.Updateable = ""true""
Debug.AspNetCompiler.ForceOverwrite = ""true""
Debug.AspNetCompiler.FixedNames = ""false""
Debug.AspNetCompiler.Debug = ""True""
Release.AspNetCompiler.VirtualPath = ""/localhost_8080""
Release.AspNetCompiler.PhysicalPath = ""C:\Users\UserA\Documents\My Web Sites\WebSite1\""
Release.AspNetCompiler.TargetPath = ""PrecompiledWeb\localhost_8080\""
Release.AspNetCompiler.Updateable = ""true""
Release.AspNetCompiler.ForceOverwrite = ""true""
Release.AspNetCompiler.FixedNames = ""false""
Release.AspNetCompiler.Debug = ""False""
SlnRelativePath = ""C:\Users\UserA\Documents\My Web Sites\WebSite1\""
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{{{{96E0707C-2E9C-4704-946F-FA583147737F}}}}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{{{{96E0707C-2E9C-4704-946F-FA583147737F}}}}.Debug|Any CPU.Build.0 = Debug|Any CPU
{{{{96E0707C-2E9C-4704-946F-FA583147737F}}}}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{{{{96E0707C-2E9C-4704-946F-FA583147737F}}}}.Release|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {{{{87CFA95B-DF37-4C4B-B629-44656ED585AB}}}}
EndGlobalSection
EndGlobal";

SolutionFile solution = SolutionFile_Tests.ParseSolutionHelper(solutionFileContents);

ProjectInSolution projectInSolution = solution.ProjectsInOrder.ShouldHaveSingleItem();

projectInSolution.AbsolutePath.ShouldBe(Path.Combine(solution.SolutionFileDirectory, projectInSolution.RelativePath));
}

#region Helper Functions

/// <summary>
Expand Down
24 changes: 17 additions & 7 deletions src/Build/Construction/Solution/ProjectInSolution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,21 @@ public string AbsolutePath
{
if (_absolutePath == null)
{
_absolutePath = Path.Combine(ParentSolution.SolutionFileDirectory, _relativePath);

try
{
#if NETFRAMEWORK && !MONO
_absolutePath = Path.GetFullPath(Path.Combine(ParentSolution.SolutionFileDirectory, _relativePath));
_absolutePath = Path.GetFullPath(_absolutePath);
#else
_absolutePath = FileUtilities.NormalizePath(Path.Combine(ParentSolution.SolutionFileDirectory, _relativePath));
_absolutePath = FileUtilities.NormalizePath(_absolutePath);
#endif
}
catch (Exception)
{
// The call to GetFullPath can throw if the relative path is a URL or the paths are too long for the current file system
// This falls back to previous behavior of returning a path that may not be correct but at least returns some value
}
}

return _absolutePath;
Expand Down Expand Up @@ -229,9 +239,9 @@ public IReadOnlyDictionary<string, ProjectConfigurationInSolution> ProjectConfig

internal string TargetFrameworkMoniker { get; set; }

#endregion
#endregion

#region Methods
#region Methods

private bool _checkedIfCanBeMSBuildProjectFile;
private bool _canBeMSBuildProjectFile;
Expand Down Expand Up @@ -529,13 +539,13 @@ private static bool ElementContainsInvalidNamespaceDefitions(XmlElement mainProj
return false;
}

#endregion
#endregion

#region Constants
#region Constants

internal const int DependencyLevelUnknown = -1;
internal const int DependencyLevelBeingDetermined = -2;

#endregion
#endregion
}
}

0 comments on commit 97a9a16

Please sign in to comment.