diff --git a/src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs b/src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs index c3a0bda0b0a..773aed1af7b 100644 --- a/src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs +++ b/src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs @@ -23,6 +23,7 @@ using BackendNativeMethods = Microsoft.Build.BackEnd.NativeMethods; using System.Threading.Tasks; +using Microsoft.Build.Utilities; namespace Microsoft.Build.BackEnd { @@ -470,14 +471,21 @@ private int LaunchNode(string msbuildLocation, string commandLineArgs) // Null out the process handles so that the parent process does not wait for the child process // to exit before it can exit. uint creationFlags = 0; - startInfo.dwFlags = BackendNativeMethods.STARTFUSESTDHANDLES; + if (Traits.Instance.EscapeHatches.EnsureStdOutForChildNodesIsPrimaryStdout) + { + creationFlags = BackendNativeMethods.NORMALPRIORITYCLASS; + } if (String.IsNullOrEmpty(Environment.GetEnvironmentVariable("MSBUILDNODEWINDOW"))) { - startInfo.hStdError = BackendNativeMethods.InvalidHandle; - startInfo.hStdInput = BackendNativeMethods.InvalidHandle; - startInfo.hStdOutput = BackendNativeMethods.InvalidHandle; - creationFlags = creationFlags | BackendNativeMethods.CREATENOWINDOW; + if (!Traits.Instance.EscapeHatches.EnsureStdOutForChildNodesIsPrimaryStdout) + { + startInfo.hStdError = BackendNativeMethods.InvalidHandle; + startInfo.hStdInput = BackendNativeMethods.InvalidHandle; + startInfo.hStdOutput = BackendNativeMethods.InvalidHandle; + startInfo.dwFlags = BackendNativeMethods.STARTFUSESTDHANDLES; + creationFlags = creationFlags | BackendNativeMethods.CREATENOWINDOW; + } } else { @@ -497,12 +505,6 @@ private int LaunchNode(string msbuildLocation, string commandLineArgs) // Run the child process with the same host as the currently-running process. exeName = GetCurrentHost(); commandLineArgs = "\"" + msbuildLocation + "\" " + commandLineArgs; - - if (NativeMethodsShared.IsWindows) - { - // Repeat the executable name _again_ because Core MSBuild expects it - commandLineArgs = exeName + " " + commandLineArgs; - } #endif if (!NativeMethodsShared.IsWindows) @@ -511,7 +513,10 @@ private int LaunchNode(string msbuildLocation, string commandLineArgs) ProcessStartInfo processStartInfo = new ProcessStartInfo(); processStartInfo.FileName = exeName; processStartInfo.Arguments = commandLineArgs; - processStartInfo.CreateNoWindow = (creationFlags | BackendNativeMethods.CREATENOWINDOW) == BackendNativeMethods.CREATENOWINDOW; + if (!Traits.Instance.EscapeHatches.EnsureStdOutForChildNodesIsPrimaryStdout) + { + processStartInfo.CreateNoWindow = (creationFlags | BackendNativeMethods.CREATENOWINDOW) == BackendNativeMethods.CREATENOWINDOW; + } processStartInfo.UseShellExecute = false; Process process; @@ -537,6 +542,14 @@ private int LaunchNode(string msbuildLocation, string commandLineArgs) } else { +#if RUNTIME_TYPE_NETCORE + if (NativeMethodsShared.IsWindows) + { + // Repeat the executable name in the args to suit CreateProcess + commandLineArgs = exeName + " " + commandLineArgs; + } +#endif + BackendNativeMethods.PROCESS_INFORMATION processInfo = new BackendNativeMethods.PROCESS_INFORMATION(); bool result = BackendNativeMethods.CreateProcess diff --git a/src/Shared/Traits.cs b/src/Shared/Traits.cs index 56e86f8b5e5..82cc2e10027 100644 --- a/src/Shared/Traits.cs +++ b/src/Shared/Traits.cs @@ -127,6 +127,12 @@ internal class EscapeHatches /// public readonly bool UseAutoRunWhenLaunchingProcessUnderCmd = Environment.GetEnvironmentVariable("MSBUILDUSERAUTORUNINCMD") == "1"; + /// + /// Workaround for https://github.com/Microsoft/vstest/issues/1503. + /// + public readonly bool EnsureStdOutForChildNodesIsPrimaryStdout = Environment.GetEnvironmentVariable("MSBUILDENSURESTDOUTFORTASKPROCESSES") == "1"; + + private static bool? ParseNullableBoolFromEnvironmentVariable(string environmentVariable) { var value = Environment.GetEnvironmentVariable(environmentVariable);