Skip to content

[Bug]: Check for determining "project file" does not correctly work for solution filter files #9587

@stefan-schweiger

Description

@stefan-schweiger

Issue Description

When running dotnet build in a folder which only contains a .slnf the commands won't work because no valid "project file" can be determined, but if you run dotnet build MyFilter.slnf the commands correctly work.

Steps to Reproduce

Create a solution with the following structure and run dotnet build in the folder ServiceA

/
├─ ServiceA/
│  ├─ ServiceA.QueryHandling/
│  │  ├─ ServiceA.QueryHandling.csproj
│  ├─ ServiceA.slnf
├─ MySolution.sln

Expected Behavior

The build should correctly pick up the solution filter file and work like it would in the / and ServiceA.QueryHandling folders.

Actual Behavior

If you run it in the ServiceA folder you get this error:
MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file.

Analysis

I think the problem is on line 3422 here that it only looks for *.sln files and therefore never picks up *.slnf files, so it should probably be changed to *.sln* to actually correctly pick up the solution filter files.

msbuild/src/MSBuild/XMake.cs

Lines 3422 to 3497 in 5d663a0

string[] potentialSolutionFiles = getFiles(projectDirectory ?? ".", "*.sln");
List<string> actualSolutionFiles = new List<string>();
List<string> solutionFilterFiles = new List<string>();
if (potentialSolutionFiles != null)
{
foreach (string s in potentialSolutionFiles)
{
if (!extensionsToIgnore.Contains(Path.GetExtension(s)))
{
if (FileUtilities.IsSolutionFilterFilename(s))
{
solutionFilterFiles.Add(s);
}
else if (FileUtilities.IsSolutionFilename(s))
{
actualSolutionFiles.Add(s);
}
}
}
}
// If there is exactly 1 project file and exactly 1 solution file
if (actualProjectFiles.Count == 1 && actualSolutionFiles.Count == 1)
{
// Grab the name of both project and solution without extensions
string solutionName = Path.GetFileNameWithoutExtension(actualSolutionFiles[0]);
string projectName = Path.GetFileNameWithoutExtension(actualProjectFiles[0]);
// Compare the names and error if they are not identical
InitializationException.VerifyThrow(string.Equals(solutionName, projectName, StringComparison.OrdinalIgnoreCase), projectDirectory == null ? "AmbiguousProjectError" : "AmbiguousProjectDirectoryError", null, projectDirectory);
projectFile = actualSolutionFiles[0];
}
// If there is more than one solution file in the current directory we have no idea which one to use
else if (actualSolutionFiles.Count > 1)
{
InitializationException.VerifyThrow(false, projectDirectory == null ? "AmbiguousProjectError" : "AmbiguousProjectDirectoryError", null, projectDirectory, false);
}
// If there is more than one project file in the current directory we may be able to figure it out
else if (actualProjectFiles.Count > 1)
{
// We have more than one project, it is ambiguous at the moment
bool isAmbiguousProject = true;
// If there are exactly two projects and one of them is a .proj use that one and ignore the other
if (actualProjectFiles.Count == 2)
{
string firstPotentialProjectExtension = Path.GetExtension(actualProjectFiles[0]);
string secondPotentialProjectExtension = Path.GetExtension(actualProjectFiles[1]);
// If the two projects have the same extension we can't decide which one to pick
if (!string.Equals(firstPotentialProjectExtension, secondPotentialProjectExtension, StringComparison.OrdinalIgnoreCase))
{
// Check to see if the first project is the proj, if it is use it
if (string.Equals(firstPotentialProjectExtension, ".proj", StringComparison.OrdinalIgnoreCase))
{
projectFile = actualProjectFiles[0];
// We have made a decision
isAmbiguousProject = false;
}
// If the first project is not the proj check to see if the second one is the proj, if so use it
else if (string.Equals(secondPotentialProjectExtension, ".proj", StringComparison.OrdinalIgnoreCase))
{
projectFile = actualProjectFiles[1];
// We have made a decision
isAmbiguousProject = false;
}
}
}
InitializationException.VerifyThrow(!isAmbiguousProject, projectDirectory == null ? "AmbiguousProjectError" : "AmbiguousProjectDirectoryError", null, projectDirectory);
}
// if there are no project, solution filter, or solution files in the directory, we can't build
else if (actualProjectFiles.Count == 0 &&
actualSolutionFiles.Count == 0 &&
solutionFilterFiles.Count == 0)
{
InitializationException.Throw("MissingProjectError", null, null, false);
}

Versions & Configurations

MSBuild version 17.8.3+195e7f5a3 for .NET
17.8.3.51904%

dotnet 8.0.100

macOS 14.2.1 (23C71)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Priority:3Work that is nice to havebughelp wantedIssues that the core team doesn't plan to work on, but would accept a PR for. Comment to claim.triaged

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions