Skip to content

Conversation

@xen2
Copy link
Contributor

@xen2 xen2 commented Nov 3, 2021

Fixes #6782
Follow-up of #6890

Context

Tried DisableInProcNode = false and couldn't make it work.
After some investigations, it turns out the code in NodeProviderOutOfProcBase.GetCurrentHost() has some issues:

string dotnetExe = Path.Combine(FileUtilities.GetFolderAbove(BuildEnvironmentHelper.Instance.CurrentMSBuildExePath, 2),

In my case, CurrentMSBuildToolsDirectory returns C:\Program Files\dotnet\sdk\6.0.100\MSBuild.dll.
FileUtilities.GetFolderAbove() 2 levels makes it try to resolve dotnet.exe from C:\Program Files\dotnet\sdk\dotnet.exe instead of C:\Program Files\dotnet\dotnet.exe.
I believe this is because the filename itself was not taken into account (it counts as 1 extra step for FileUtilities.GetFolderAbove())

Changes Made

Used CurrentMSBuildToolsDirectory rather than CurrentMSBuildExePath.
Another option would be to use 3 for FileUtilities.GetFolderAbove, but since the function explicitely contains "folder" in its name, I preferred to avoid the case where it is later changed to ignore the top-level file rather than considering it as a folder.

Testing

I tested with a simple console app.
(Note: without being careful it could quickly crash the PC as mentioned in #6782 because it calls itself in infinite loop (instead of dotnet.exe), unless you add some check on args.Length as done in this test code)

using Microsoft.Build.Execution;
using Microsoft.Build.Locator;

// Avoid infinite loop => system crash (until MSBuild bug to properly resolve dotnet.exe is fixed)
if (args.Length > 0) return;

var projectPath = @"C:\dev\ConsoleApp8\ConsoleApp8.csproj";

MSBuildLocator.RegisterDefaults();
RunTest();

void RunTest()
{
    var mainBuildManager = new BuildManager();
    var pc = new Microsoft.Build.Evaluation.ProjectCollection();
    var parameters = new BuildParameters(pc) { DisableInProcNode = true };

    // Run a MSBuild /t:Restore <projectfile>
    var request = new BuildRequestData(projectPath, new Dictionary<string, string>(), null, new[] { "Restore" }, null, BuildRequestDataFlags.None);
    mainBuildManager.Build(parameters, request);
}

Notes

…bove count, dotnet executable was looked up in sdk subfolder
@xen2 xen2 mentioned this pull request Nov 3, 2021
10 tasks
@rainersigwald rainersigwald requested a review from Forgind November 3, 2021 15:34
Copy link
Contributor

@Forgind Forgind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks 😅

I remember having looked at this in a debugger to see how many folders up, but I assumed it would be constant.

I was going to ask about bitness, but I think this should always be 64-bit, so it isn't an issue.

@Forgind
Copy link
Contributor

Forgind commented Nov 3, 2021

Actually, I looked again, and I have a dotnet.exe in both dotnet and sdk. I'm not sure which is "standard;" I should probably make sure it's expected in dotnet but not sdk.

@Forgind
Copy link
Contributor

Forgind commented Nov 3, 2021

Sounds like it's weird that I have dotnet.exe in sdk, so this looks good. 👍

@xen2
Copy link
Contributor Author

xen2 commented Nov 4, 2021

Actually, I looked again, and I have a dotnet.exe in both dotnet and sdk. I'm not sure which is "standard;" I should probably make sure it's expected in dotnet but not sdk.

Ha, that explains it!
Double-checked on two computers and both of them have it only in dotnet top-level folder, not in sdk.

In that case, feel free to switch to the other approach FileUtilities.GetFolderAbove(BuildEnvironmentHelper.Instance.CurrentMSBuildExePath, 3) rather than FileUtilities.GetFolderAbove(BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory, 2) if you prefer.

@Forgind
Copy link
Contributor

Forgind commented Nov 4, 2021

I don't really have a preference between the two, but I can check in our PR review meeting whether anyone else does.

Copy link
Member

@rainersigwald rainersigwald left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @xen2!

@Forgind can we update the version check in Locator to keep specifying the environment for 17.0?

I was going to ask about bitness, but I think this should always be 64-bit, so it isn't an issue.

The .NET SDK has a 32-bit x86 version. However, because MSBuild doesn't support cross-processor-architecture task execution on .NET Core, we don't have an amd64 directory and the position of dotnet.exe relative to MSBuild.dll doesn't change in the 32-bit SDK.

@Forgind Forgind added the merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now. label Nov 4, 2021
@rokonec rokonec merged commit a490a68 into dotnet:main Nov 5, 2021
@xoofx
Copy link
Member

xoofx commented Nov 29, 2021

Ran exactly into this bug today, I was going mad! Then I debugged and found also the issue, but found that it was also already fixed here, thank you @xen2! 🤗

@xen2
Copy link
Contributor Author

xen2 commented Nov 29, 2021

Ran exactly into this bug today, I was going mad! Then I debugged and found also the issue, but found that it was also already fixed here, thank you @xen2! 🤗

Small world! ;)
You're welcome!

rainersigwald pushed a commit to microsoft/MSBuildLocator that referenced this pull request Dec 1, 2021
The change in #135 was supposed to be made unnecessary by dotnet/msbuild#6890, but apparently my setup is the only one that has dotnet.exe under both the dotnet folder and the sdks folder, so it didn't work. @xen2 fixed the problem in dotnet/msbuild#7013, but that won't get in 'til 17.1, so we need to prolong the version check here.

Co-authored-by: xen2 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-when-branch-open PRs that are approved, except that there is a problem that means we are not merging stuff right now.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Out-of-proc builds in a custom .NET Core process are not possible

5 participants