Skip to content

Isolate MSBuildTaskHost from the rest of MSBuild Codebase#13232

Open
DustinCampbell wants to merge 141 commits intomainfrom
dev/dustinca/isolate-taskhost
Open

Isolate MSBuildTaskHost from the rest of MSBuild Codebase#13232
DustinCampbell wants to merge 141 commits intomainfrom
dev/dustinca/isolate-taskhost

Conversation

@DustinCampbell
Copy link
Member

Summary

MSBuildTaskHost.exe provides legacy support for running .NET Framework 3.5 tasks. It is itself a .NET Framework 3.5 application and loads the Microsoft.Build.* 3.5.0.0 assemblies from the GAC when .NET 3.5 is installed. Today, common targets force three .NET 3.5 tasks to run in MSBuildTaskHost: RegisterAssembly, UnregisterAssembly, and especially, GenerateResource. For .NET 3.5 builds, it is essentially that the 3.5 version of GenerateResource runs, since the BinaryFormatter output format changed between CLR 2.0 and CLR 4.0.

For more than 15 years, MSBuildTaskHost has been compiled from the same shared source files as the rest of MSBuild. This made sense in the .NET Framework 4.0 era, when the delta between 3.5 and 4.0 was small. But as MSBuild has evolved, this arrangement has become increasingly restrictive. Any shared code that uses modern .NET features (Span<T>, Task<T>, immutable collections, etc.) becomes problematic because MSBuildTaskHost cannot consume them. Shared code changes also risk breaking MSBuildTaskHost and, by extension, the ability to build legacy .NET 3.5 projects.

This PR isolates MSBuildTaskHost into its own self‑contained codebase, decoupled from the rest of MSBuild.

Approach

The isolation work follows these steps:

  1. Copy all shared files into MSBuildTaskHost.
  2. Remove conditional compilation constants from MSBuildTaskHost’s sources:
    • Dead code paths, including those under NET, RUNTIME_TYPE_NETCORE, or FEATURE_* flags irrelevant to .NET 3.5 (e.g., FEATURE_VISUALSTUDIOSETUP).
    • Always‑true code paths, such as those under CLR2COMPATIBILITY or FEATURE_ASSEMBLY_LOCATION.
  3. Remove OS/architecture‑specific code that MSBuildTaskHost does not support (i.e., anything outside Windows/x86/x64).
  4. Remove uncalled members and unused types.
  5. Remove MSBuild public API types that were added solely to make MSBuildTaskHost compile but do not exist in Microsoft.Build.Framework 3.5.0.0 (e.g., IBuildEngine3, ITaskItem2, RunInSTAAttribute).
  6. Clean up each file to reflect its new, isolated context.

Additional Changes Outside MSBuildTaskHost

Refactor handshake components to make the tools directory path deterministic by using the MSBuildTaskHost.exe directory when computing handshake salt. (22fb64e)
Add a test that verifies building a .NET 3.5 WinForms application on Windows/.NET Framework when .NET 3.5 is installed. (9941c15)

Next Steps

Remove dead code paths from all shared MSBuild files now that .NET 3.5 compatibility is no longer required. (In progress)
Audit conditional compilation constants across MSBuild. (In progress)
Move remaining shared code into a dedicated shared binary (Microsoft.Build.Framework). (Requires reworking how string resources are consumed across MSBuild binaries.)

Future Work

Refactor task host communication to introduce a “protocol adapter” layer. Now that MSBuildTaskHost is effectively frozen in time, this adapter would shield it from future protocol changes while allowing MSBuild to evolve independently.

Copies all shared files and files linked from other projects directly into MSBuildTaskHost. In addition, all <Compile> items in MSBuildTaskHost.csproj have been updated to point to the new files.
Split the PropertyGroup for $(DefineConstants) into two: one for net3* and one for net4*
This polyfill is unused in MSBuildTaskHost.
Since MSBuildTaskHost only targets .NET 3.5, it does not require conditional compilation for FEATURE_LEGACY_GETCURRENTDIRECTORY. It *always* includes the code path that provides an optimized GetCurrentDirectory on .NET Framework targets earlier than 4.6.2.
Since MSBuildTaskHost only targets .NET 3.5, it does not require conditional compilation for FEATURE_LEGACY_GETFULLPATH. It *always* includes the code path that provides an optimized GetFullPath on .NET Framework targets earlier than 4.6.2.
Since MSBuildTaskHost only targets .NET 3.5, System.Reflection.Assembly.Location is always available.
The FEATURE_CULTUREINFO_GETCULTURES code path is unused by MSBuildTaskHost.
The FEATURE_APM code path is always used by MSBuildTaskHost. .NET Framework 3.5 does support System.Threading.Tasks, so MSBuildTaskHost uses the older "asynchronous programming model (APM)".
…Host

Many of the FEATURE_* conditional compilation constants defined for .NET 3.5 builds never appear in code compiled within MSBuildTaskHost. This change removes all of those for .NET 3.5 builds.
The FEATURE_PIPE_SECURITY and FEATURE_NAMED_PIPE_SECURITY_CONSTRUCTOR code paths is always used by MSBuildTaskHost.
The FEATURE_SECURITY_PERMISSIONS code paths are always available in MSBuildTaskHost.
The FEATURE_SECURITY_PRINCIPAL_WINDOWS code paths are always available in MSBuildTaskHost.
The FEATURE_THREAD_ABORT code paths are always available in MSBuildTaskHost.
The FEATURE_VISUALSTUDIOSETUP code paths are never available in MSBuildTaskHost. This constant is always removed from .NET 3.5 builds.
The FeatureAppDomain, FeatureSystemConfiguration, and FeatureXamlTypes properties are not used in .NET 3.5 builds.

NOTE: It seems that FeatureAppDomain is the only one of these properties that are used anywhere. However, it is used in a target in Microsoft.Build, which is not built for .NET 3.5.
The FEATURE_REPORTFILEACCESSES code paths are not available in MSBuildTaskHost. This constant was never included in .NET 3.5 builds.
BuildEnvironmentHelper includes a check for AppContext.BaseDirectory that is always returns null on .NET 3.5 and the MSBuildTaskHost. This change removes that check and related code.
VisualStudioLocationHelper.GetInstances() always returns an empty list on .NET 3.5. So, BuildEnvironmentHelper.TryFromSetupApi (the only caller) can be removed from MSBuildTaskHost along with all of VisualStuiodLocationHelper.
RUNTIME_TYPE_NETCORE code paths aren't ever compiled in .NET 3.5 builds.
CopyOnWriteDictionary, ReadOnlyEmptyCollection, and ReadOnlyEmptyDictionary are never used in MSBuildTaskHost and can be safely removed.
Since MSBuildTaskHost only builds for .NET 3.5, there are many code blocks specific to other .NET versions that can be removed.

NOTE: Disabled code blocks were intentionally NOT removed from polyfill types.
BUILDINGAPPXTASKS is not relevant when building MSBuildTaskHost, so code compiled with BUILDINGAPPXTASKS can be removed.
MSBuildTaskHost is always compiled with CLR2COMPATIBILITY, so code blocks that aren't compiled with that conditional compilation constant can be removed.
MSBuildTaskHost is always compiled with TASKHOST. So, code blocks disabled when compiled with TASKHOST can be removed.
MSBuildTaskHost is never compiled with FEATURE_ASSEMBLYLOADCONTEXT.
MSBuildTaskHost is never compiled with FEATURE_PIPEOPTIONS_CURRENTUSERONLY. So, code blocks disabled with FEATURE_PIPEOPTIONS_CURRENTUSERONLY can be removed.
MSBuildTaskHost is always compiled with FEATURE_NET35_TASKHOST.
MSBuildTaskHost is always compiled with NO_FRAMEWORK_IVT. So, code blocks disabled under NO_FRAMEWORK_IVT can be removed.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR isolates MSBuildTaskHost.exe (the .NET Framework 3.5 task host) into a self-contained codebase so it no longer shares/blocks modernization work in the main MSBuild codebase, while keeping the node/taskhost communication protocol compatible and adding coverage for building a legacy .NET 3.5 project.

Changes:

  • Adds a standalone src/MSBuildTaskHost/ codebase (utilities, backend packet protocol, exception transfer, resources).
  • Refactors task host launch/handshake plumbing to make the tools directory/salt computation deterministic.
  • Adds a Windows/.NET Framework + .NET 3.5 installed test that builds a .NET 3.5 WinForms project, gated by a new WindowsNet35OnlyFactAttribute.

Reviewed changes

Copilot reviewed 92 out of 97 changed files in this pull request and generated 62 comments.

Show a summary per file
File Description
src/UnitTests.Shared/WindowsNet35OnlyFactAttribute.cs New test attribute to gate tests on Windows + .NET Framework + .NET 3.5 installed.
src/Shared/UnitTests/ImmutableDictionary_Tests.cs Removes old immutable dictionary tests that depended on the previous taskhost aliasing approach.
src/Shared/LogMessagePacketBase.cs Documents enum value sync requirement with MSBuildTaskHost.
src/Shared/INodePacket.cs Documents packet type sync requirement with MSBuildTaskHost.
src/MSBuildTaskHost/Utilities/StringBuilderCache.cs Adds thread-static StringBuilder cache for allocations reduction in taskhost.
src/MSBuildTaskHost/Utilities/ExceptionHandling.cs Adds taskhost exception classification + dump-to-file support.
src/MSBuildTaskHost/Utilities/ErrorUtilities.cs Adds taskhost-local validation/throw helpers.
src/MSBuildTaskHost/Utilities/EnvironmentUtilities.cs Adds taskhost process/environment helpers (pid/path/session).
src/MSBuildTaskHost/Traits.cs Adds taskhost traits/escape hatches for debug/reuse/long-path toggles.
src/MSBuildTaskHost/TaskLoader.cs Implements task loading and AppDomain isolation logic inside taskhost.
src/MSBuildTaskHost/Resources/xlf/SR.zh-Hant.xlf Taskhost localized resources (zh-Hant).
src/MSBuildTaskHost/Resources/xlf/SR.zh-Hans.xlf Taskhost localized resources (zh-Hans).
src/MSBuildTaskHost/Resources/xlf/SR.tr.xlf Taskhost localized resources (tr).
src/MSBuildTaskHost/Resources/xlf/SR.ru.xlf Taskhost localized resources (ru).
src/MSBuildTaskHost/Resources/xlf/SR.pt-BR.xlf Taskhost localized resources (pt-BR).
src/MSBuildTaskHost/Resources/xlf/SR.pl.xlf Taskhost localized resources (pl).
src/MSBuildTaskHost/Resources/xlf/SR.ko.xlf Taskhost localized resources (ko).
src/MSBuildTaskHost/Resources/xlf/SR.ja.xlf Taskhost localized resources (ja).
src/MSBuildTaskHost/Resources/xlf/SR.it.xlf Taskhost localized resources (it).
src/MSBuildTaskHost/Resources/xlf/SR.fr.xlf Taskhost localized resources (fr).
src/MSBuildTaskHost/Resources/xlf/SR.es.xlf Taskhost localized resources (es).
src/MSBuildTaskHost/Resources/xlf/SR.de.xlf Taskhost localized resources (de).
src/MSBuildTaskHost/Resources/xlf/SR.cs.xlf Taskhost localized resources (cs).
src/MSBuildTaskHost/Resources/SR.resx Taskhost base resource strings.
src/MSBuildTaskHost/Properties/AssemblyInfo.cs Adds IVT for unit tests (moved from removed AssemblyInfo).
src/MSBuildTaskHost/Polyfills/NullableAttributes.cs Adds nullable/analysis attribute polyfills for net35 compilation.
src/MSBuildTaskHost/Polyfills/IsExternalInit.cs Adds init-setter polyfill/type-forwarding support.
src/MSBuildTaskHost/Polyfills/CallerArgumentExpressionAttribute.cs Adds CallerArgumentExpression polyfill/type-forwarding support.
src/MSBuildTaskHost/OutOfProcTaskHostTaskResult.cs Adds task execution result model (success/failure/crash + outputs).
src/MSBuildTaskHost/OutOfProcTaskHost.cs Taskhost main entry point + node lifecycle loop.
src/MSBuildTaskHost/OutOfProcTaskAppDomainWrapper.cs Implements task execution (instantiate, set params, execute, collect outputs) within taskhost.
src/MSBuildTaskHost/LoadedType.cs Adds loaded type metadata container for task instantiation / AppDomain load.
src/MSBuildTaskHost/Immutable/ImmutableDictionary.cs Removes old internal immutable dictionary shim from taskhost.
src/MSBuildTaskHost/FileSystem/MSBuildTaskHostFileSystem.cs Removes legacy taskhost filesystem abstraction.
src/MSBuildTaskHost/Exceptions/InternalErrorException.cs Adds taskhost-local internal error exception type.
src/MSBuildTaskHost/Exceptions/GeneralBuildTransferredException.cs Adds fallback for unknown remote exceptions.
src/MSBuildTaskHost/Exceptions/BuildExceptionSerializationHelper.cs Adds helper for exception serialization keying + factory selection.
src/MSBuildTaskHost/Exceptions/BuildExceptionRemoteState.cs Adds container for remote exception state fields.
src/MSBuildTaskHost/Exceptions/BuildExceptionBase.cs Adds base exception type supporting custom translation over node protocol.
src/MSBuildTaskHost/Collections/CollectionExtensions.cs Adds small dictionary helper extension used by taskhost.
src/MSBuildTaskHost/BackEnd/TranslatorHelpers.cs Adds translation helpers for value-factory based (de)serialization patterns.
src/MSBuildTaskHost/BackEnd/TaskParameterTypeVerifier.cs Adds task parameter type validation helpers.
src/MSBuildTaskHost/BackEnd/TaskHostTaskComplete.cs Adds completion packet type for taskhost→parent communication.
src/MSBuildTaskHost/BackEnd/TaskHostTaskCancelled.cs Adds cancellation packet type for parent→taskhost communication.
src/MSBuildTaskHost/BackEnd/NodeShutdown.cs Adds node shutdown packet type and reason mapping.
src/MSBuildTaskHost/BackEnd/NodePacketFactory.cs Adds packet factory/router used by the taskhost endpoint.
src/MSBuildTaskHost/BackEnd/NodeEngineShutdownReason.cs Adds taskhost’s shutdown reason enum.
src/MSBuildTaskHost/BackEnd/NodeBuildComplete.cs Adds build complete packet.
src/MSBuildTaskHost/BackEnd/InterningBinaryReader.cs Adds string-interning BinaryReader for protocol performance.
src/MSBuildTaskHost/BackEnd/ITranslator.cs Adds taskhost protocol translator interface.
src/MSBuildTaskHost/BackEnd/ITranslatable.cs Adds translatable marker interface for packets.
src/MSBuildTaskHost/BackEnd/INodePacketHandler.cs Adds packet handler interface for routing.
src/MSBuildTaskHost/BackEnd/INodePacketFactory.cs Adds packet factory interface for packet reconstruction/routing.
src/MSBuildTaskHost/BackEnd/INodePacket.cs Adds taskhost packet type enum + protocol version helpers.
src/MSBuildTaskHost/BackEnd/INodeEndpoint.cs Adds taskhost endpoint interface abstraction.
src/MSBuildTaskHost/BackEnd/BufferedReadStream.cs Adds buffered stream wrapper for pipe reads.
src/MSBuildTaskHost/BackEnd/BinaryWriterExtensions.cs Adds optional value serialization helpers.
src/MSBuildTaskHost/BackEnd/BinaryReaderFactory.cs Adds factory for reusable BinaryReader/buffers.
src/MSBuildTaskHost/BackEnd/BinaryReaderExtensions.cs Adds optional value deserialization helpers.
src/MSBuildTaskHost/AssemblyResources.cs Removes old shared resource accessor (taskhost now owns SR).
src/MSBuildTaskHost/AssemblyInfo.cs Removes old assembly-level file (IVT moved to Properties/AssemblyInfo.cs).
src/Directory.BeforeCommon.targets Adjusts feature-constant definitions (no longer applied to net3* targets).
src/Build/Microsoft.Build.csproj Includes new TaskHostLaunchArgs source in build project.
src/Build/BackEnd/Components/Communications/TaskHostLaunchArgs.cs New helper for composing taskhost exe/args/handshake across runtime contexts.
src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcTaskHost.cs Refactors taskhost process creation to use TaskHostLaunchArgs.
src/Build.UnitTests/TestAssets/Net35WinFormsApp/TestNet35WinForms.csproj Adds legacy .NET 3.5 WinForms test project asset.
src/Build.UnitTests/TestAssets/Net35WinFormsApp/Properties/Settings.settings WinForms test asset file.
src/Build.UnitTests/TestAssets/Net35WinFormsApp/Properties/Settings.Designer.cs Generated settings designer for WinForms test asset.
src/Build.UnitTests/TestAssets/Net35WinFormsApp/Properties/Resources.resx Resources for WinForms test asset.
src/Build.UnitTests/TestAssets/Net35WinFormsApp/Properties/Resources.Designer.cs Generated resources designer for WinForms test asset.
src/Build.UnitTests/TestAssets/Net35WinFormsApp/Properties/AssemblyInfo.cs Assembly metadata for WinForms test asset.
src/Build.UnitTests/TestAssets/Net35WinFormsApp/Program.cs WinForms test asset entry point.
src/Build.UnitTests/TestAssets/Net35WinFormsApp/Form1.resx WinForms form resources (includes localized metadata).
src/Build.UnitTests/TestAssets/Net35WinFormsApp/Form1.cs WinForms form code-behind.
src/Build.UnitTests/TestAssets/Net35WinFormsApp/Form1.Designer.cs WinForms designer-generated form code.
src/Build.UnitTests/TestAssets/Net35WinFormsApp/App.config WinForms test asset runtime config (CLR 2).
src/Build.UnitTests/Microsoft.Build.Engine.UnitTests.csproj Excludes the WinForms asset from compilation and removes obsolete immutable dictionary tests.
src/Build.UnitTests/MSBuildTaskHostTests.cs Adds new integration test to build the .NET 3.5 WinForms asset.
Files not reviewed (3)
  • src/Build.UnitTests/TestAssets/Net35WinFormsApp/Form1.Designer.cs: Language not supported
  • src/Build.UnitTests/TestAssets/Net35WinFormsApp/Properties/Resources.Designer.cs: Language not supported
  • src/Build.UnitTests/TestAssets/Net35WinFormsApp/Properties/Settings.Designer.cs: Language not supported

- Fix TaskHostLaunchArgs to exclude empty quotes at front of command-line args.
- Fix XML doc comment
- Don't assert for non-localized string in test.
- Remove company and copyright text from Net35WinFormsApp test assets.
- Fix logic error in BuildExceptionSerializationHelper.DeserializeException.
- Make a few fields read-only.
The App.config in the Net35WinFormsApp test project conflicts with the shared App.config that is linked into MS.Build.Engine.UnitTests. However, that breaks most of those tests since the "Current" toolset is read from the MS.Build.Engine.UnitTests.dll.config. To fix this, add <AppConfig>..\Shared\UnitTests\App.config</AppConfig> to MS.Build.Engine.UnitTests.csproj.
Depending on what runtime MSBuild create the bootstrap layout with, it may have the net10.0 or net472 version Microsoft.NET.Build.Extensions. A .NET 3.5 project will only build when the net472 version is available. So, WindowsNet35OnlyFactAttribute has been tweaked to check the bootstrap folder layout and ensure the net4* version is present.
@DustinCampbell DustinCampbell force-pushed the dev/dustinca/isolate-taskhost branch from 47b8751 to 069a045 Compare February 10, 2026 23:00
When launching the CLR2 task host (i.e. MSBuildTaskHost.exe), TaskHostLaunchArgs passes a predefinedToolsDirectory for the handshake salt when creating a Handshake. However, Handshake's constructor ignores that parameter unless it's being created for .NET task host (and compiled for .NET Framework). This change updates the Handshake constructor to always use the 'toolsDirectory' parameter for the salt if it's provided. However, VerifyThrow methods have been added to ensure that the toolsDirectory parameter is always null it is for the .NET or CLR2 TaskHost (and compiled for .NET Framework).
@DustinCampbell DustinCampbell force-pushed the dev/dustinca/isolate-taskhost branch from 306bd2e to 46709a5 Compare February 20, 2026 18:18

namespace Microsoft.Build.BackEnd;

internal sealed class TaskHostLaunchArgs
Copy link
Member

@rainersigwald rainersigwald Feb 23, 2026

Choose a reason for hiding this comment

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

@YuliiaKovalova has this in #13175; we'll have to come to a compromise.

    internal readonly record struct NodeLaunchData(
        string MSBuildLocation,
        string CommandLineArgs,
        Handshake? Handshake = null,
        IDictionary<string, string>? EnvironmentOverrides = null);

I think we could take either and adjust the other without too much pain--part of her change is removing the need for usingDotNetExe and carrying the environment dictionary here seems ok. Either of y'all disagree?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm good with either approach. I just wanted to clean up a bit when changing the logic for the CLR2 task host. I'm inclined to follow @YuliiaKovalova's lead, since Yulia's super-experienced with this code, and I'm more of a meddler. 😄

Copy link
Member

Choose a reason for hiding this comment

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

I am ready to merge the conflict in this PR myself if we go with the structured data (!)

:D

Copy link
Member Author

Choose a reason for hiding this comment

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

@YuliiaKovalova: Feel free if you have the spare cycles. Otherwise, I can do it. I'd rather base my tweak in that area on your changes to make your PR easier to merge.

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.

This looks great! I really appreciate the reviewability of the commit-based approach you took, because looking at the raw final diff would have been a nightmare.

Comment on lines +262 to +264
// Note: This should always be true in MSBuildTaskHost (and methodInfo should never be null).
// The .NET 3.5 event args have correct "CreateFromStream" methods.
if (eventCanSerializeItself)
Copy link
Member

Choose a reason for hiding this comment

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

Any point in having an assert or anything here to put some teeth behind the "should"?

Comment on lines +34 to +35
/// Checks to see if the .NET Framework version of Microsoft.NET.Build.Extensions is installed.
/// If it isn't, building building for .NET Framework 3.5 will fail.
Copy link
Member

Choose a reason for hiding this comment

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

This part I'm a bit confused about. Are we failing to construct the netfx bootstrap output correctly when the repo is built with core, or is the problem something else?

(To be clear I'm ok with this as a "this gets the test running in at least one PR build leg" solution, but it smells fishy as a "this is how it has to work" thing.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Are we failing to construct the netfx bootstrap output correctly when the repo is built with core, or is the problem something else?

Yes, that's the problem. The Bootstrap build layout isn't correct when building with -msbuildEngine dotnet. The issue is here:

<InstalledMicrosoftExtensions Include="$(MSBuildExtensionsPath)\Microsoft\**\*.*"
Exclude="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\NodeJs\**" />

When building with core, the MSBuildExtensionsPath points to the .NET SDK. So, the net10.0 version of Microsoft.NET.Build.Extensions.dll gets copied into the bootstrap layout. When building with full framework, MSBuildExtensionsPath points to VS, and the net472 version of Microsoft.NET.Build.Extensions.dll is copied instead. This causes an issue building for .NET 3.5 because the targets are looking for the net472 version but isn't there.

To be honest, I'm not sure what the correct fix would be for the bootstrap targets, or if that would even be desirable. So, I added this super hacky fix to work around the test issue. I fully agree that it's 100% fishy and I'm glad you noticed it. Do you have a recommendation?

Copy link
Member

@SimaTian SimaTian left a comment

Choose a reason for hiding this comment

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

review progress:
~110/141 (commit 5487183)
let me correct myself. This PR is amazing and I'm sad I'm almost half done. I want more.

SimaTian

This comment was marked as resolved.

@@ -1494,20 +1427,7 @@ internal static void VerifyThrowWin32Result(int result)

internal static bool SetCurrentDirectory(string path)
Copy link
Member

Choose a reason for hiding this comment

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

It is possible that this is addressed in some follow up, in that case this comment is ignorable.

Since the method now only returns return SetCurrentDirectoryWindows(path); should we remove it altogether and call the inner method directly?

return IsWindows
? FileOrDirectoryExistsWindows(path)
: File.Exists(path) || Directory.Exists(path);
return FileOrDirectoryExistsWindows(path);
Copy link
Member

Choose a reason for hiding this comment

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

same as above, (also for FileExists and for DirectoryExists)
we can lost one layer of indirection in one way or the other.

@@ -160,8 +155,7 @@ private static BuildEnvironment TryFromMSBuildProcess()
}

// First check if we're in a VS installation
Copy link
Member

Choose a reason for hiding this comment

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

Can TaskHost run from VS? doesn't it always run from MSBuild (even if that MSbuild is itself running from VS)

@@ -22,16 +22,7 @@ internal static string GetPlatformSpecificPipeName(int? processId = null)

internal static string GetPlatformSpecificPipeName(string pipeName)
{
Copy link
Member

Choose a reason for hiding this comment

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

this method can be safely discarded

Copy link
Member

@SimaTian SimaTian left a comment

Choose a reason for hiding this comment

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

MSBuildTaskHost doesn't get much benefit from MSBuildNameIgnoreCaseComparer over using StringComparer.OrdinalIgnoreCase. So, this change removes MSBuildNameIgnoreCaseComparer.cs and IConstrainedEqualityComparer.cs from MSBuildTaskHost rather than include the extra complexity.

I'm not disputing this claim but I would love to know a bit more about the reasoning.
(or if we have some sort of benchmark data for this, even better)

is there some difference in the assumptions for the TaskHost as opposed to general MSBuild environment?
is it that we don't care about TaskHost performance since it's legacy support only and so it's "almost deprecated" and so maintainability has high enough priority?
or something else entirely?

Copy link
Member

@SimaTian SimaTian left a comment

Choose a reason for hiding this comment

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

The only bits left in XMakeAttributes are for checking MSBuild's architecture and runtime. This change formalizes that and removes XMakeAttributes.cs.

I love this. This genuinely made me laugh.
First we gut XMakeAttributes few commits ago and then we revisit, notice it is mostly hollow and kill it altogether. Yessssss.


ErrorUtilities.VerifyThrowArgumentNull(paths);

return paths.Aggregate(root, Path.Combine);
Copy link
Member

Choose a reason for hiding this comment

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

Sounds like linq is something we really want to avoid :-)
I'm for it. Good to know.


namespace Microsoft.Build.BackEnd
{
/// <summary>
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if few commits from now on, we will inline this and get rid of the Helpers altogether. This is better than a detective novel.

Copy link
Member

@SimaTian SimaTian left a comment

Choose a reason for hiding this comment

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

Note that "node reuse" is always false in MSBuildTaskHost
Similar confusion about our TaskHost naming as before. Maybe we should make the naming more explicit and rename this one as a "OldTaskHost" or something?
Because sidecar taskshost (and by extension the other taskhost that is different from this one) I was working on before was definitely handling node reuse.

@rainersigwald
Copy link
Member

commit 73e68d4: MSBuildTaskHost can only ever run on Windows. So, runtime checks for the OS platform can be completely removed.

I'm mildly confused here - part of my MSBuild mental model is most likely wrong. If taskhost doesn't run on non-windows OS, where do we kick thread-unsafe tasks in the case of Multithreaded build on *nix machines?

It could be as simple as "we have a naming overload and there are more kinds of task host around" but I never updated my model explicitly for this piece of information. Or are *nix machines to be served only by the NET taskhost?

MSBuildTaskHost.exe, the net35 taskhost, runs only on Windows (where we can have .NET Framework 3.5 installed). TaskHosts for the .NET (core) runtime can run anywhere we do.

This naming is a bit unfortunate but it's what has been used since .NET Framework 4.0 so IMO it's too late to change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants