diff --git a/src/Workspaces/MSBuild/Core/MSBuild/BuildHostProcessManager.cs b/src/Workspaces/MSBuild/Core/MSBuild/BuildHostProcessManager.cs index 5600ee46d9ac2..2a85ccb6ed9d2 100644 --- a/src/Workspaces/MSBuild/Core/MSBuild/BuildHostProcessManager.cs +++ b/src/Workspaces/MSBuild/Core/MSBuild/BuildHostProcessManager.cs @@ -30,6 +30,9 @@ internal sealed class BuildHostProcessManager : IAsyncDisposable private readonly SemaphoreSlim _gate = new(initialCount: 1); private readonly Dictionary _processes = []; + private static string MSBuildWorkspaceDirectory => Path.GetDirectoryName(typeof(BuildHostProcessManager).Assembly.Location)!; + private static bool IsLoadedFromNuGetPackage => File.Exists(Path.Combine(MSBuildWorkspaceDirectory, "..", "..", "microsoft.codeanalysis.workspaces.msbuild.nuspec")); + public BuildHostProcessManager(ImmutableDictionary? globalMSBuildProperties = null, IBinLogPathProvider? binaryLogPathProvider = null, ILoggerFactory? loggerFactory = null) { _globalMSBuildProperties = globalMSBuildProperties ?? ImmutableDictionary.Empty; @@ -186,10 +189,7 @@ private ProcessStartInfo CreateDotNetCoreBuildHostStartInfo(string pipeName) internal static string GetNetCoreBuildHostPath() { - // The .NET Core build host is deployed as a content folder next to the application into the BuildHost-netcore path - var buildHostPath = Path.Combine(Path.GetDirectoryName(typeof(BuildHostProcessManager).Assembly.Location)!, "BuildHost-netcore", "Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll"); - AssertBuildHostExists(buildHostPath); - return buildHostPath; + return GetBuildHostPath("BuildHost-netcore", "Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll"); } private ProcessStartInfo CreateDotNetFrameworkBuildHostStartInfo(string pipeName) @@ -221,16 +221,34 @@ private ProcessStartInfo CreateMonoBuildHostStartInfo(string pipeName) private static string GetDotNetFrameworkBuildHostPath() { - // The .NET Framework build host is deployed as a content folder next to the application into the BuildHost-net472 path - var netFrameworkBuildHost = Path.Combine(Path.GetDirectoryName(typeof(BuildHostProcessManager).Assembly.Location)!, "BuildHost-net472", "Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.exe"); - AssertBuildHostExists(netFrameworkBuildHost); - return netFrameworkBuildHost; + return GetBuildHostPath("BuildHost-net472", "Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.exe"); } - private static void AssertBuildHostExists(string buildHostPath) + private static string GetBuildHostPath(string contentFolderName, string assemblyName) { + // Possible BuildHost paths are relative to where the Workspaces.MSBuild assembly was loaded. + string buildHostPath; + + if (IsLoadedFromNuGetPackage) + { + // When Workspaces.MSBuild is loaded from the NuGet package (as is the case in .NET Interactive, NCrunch, and possibly other use cases) + // the Build host is deployed under the contentFiles folder. + // + // Workspaces.MSBuild.dll Path - .nuget/packages/microsoft.codeanalysis.workspaces.msbuild/{version}/lib/{tfm}/Microsoft.CodeAnalysis.Workspaces.MSBuild.dll + // MSBuild.BuildHost.dll Path - .nuget/packages/microsoft.codeanalysis.workspaces.msbuild/{version}/contentFiles/any/any/{contentFolderName}/{assemblyName} + + buildHostPath = Path.GetFullPath(Path.Combine(MSBuildWorkspaceDirectory, "..", "..", "contentFiles", "any", "any", contentFolderName, assemblyName)); + } + else + { + // When Workspaces.MSBuild is deployed as part of an application the build host is deployed as a content folder next to the application. + buildHostPath = Path.Combine(MSBuildWorkspaceDirectory, contentFolderName, assemblyName); + } + if (!File.Exists(buildHostPath)) throw new Exception(string.Format(WorkspaceMSBuildResources.The_build_host_could_not_be_found_at_0, buildHostPath)); + + return buildHostPath; } private void AppendBuildHostCommandLineArgumentsConfigureProcess(ProcessStartInfo processStartInfo, string pipeName) diff --git a/src/Workspaces/MSBuild/Core/Microsoft.CodeAnalysis.Workspaces.MSBuild.csproj b/src/Workspaces/MSBuild/Core/Microsoft.CodeAnalysis.Workspaces.MSBuild.csproj index fb336b31260da..fb6da908cb6bc 100644 --- a/src/Workspaces/MSBuild/Core/Microsoft.CodeAnalysis.Workspaces.MSBuild.csproj +++ b/src/Workspaces/MSBuild/Core/Microsoft.CodeAnalysis.Workspaces.MSBuild.csproj @@ -97,6 +97,7 @@ <_NetFrameworkBuildHostProjectReference Include="..\..\..\Workspaces\MSBuild\BuildHost\Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.csproj"> net472 + BuildHost-net472 @@ -105,6 +106,7 @@ <_NetFrameworkBuildHostProjectReference Include="..\..\..\Workspaces\MSBuild\BuildHost\Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.csproj"> $(NetRoslynBuildHostNetCoreVersion) + BuildHost-netcore @@ -118,6 +120,8 @@ + +