private void KillToolProcessOnTimeout(Process proc, bool isBeingCancelled) { if (!proc.HasExited) { if (!isBeingCancelled) { ErrorUtilities.VerifyThrow(this.Timeout != -1, "A time-out value must have been specified or the task must be cancelled."); this.LogShared.LogWarningWithCodeFromResources("Shared.KillingProcess", new object[] { this.Timeout }); } else { this.LogShared.LogWarningWithCodeFromResources("Shared.KillingProcessByCancellation", new object[0]); } try { NativeMethodsShared.KillTree(proc.Id); } catch (InvalidOperationException) { } int milliseconds = 0x1388; string environmentVariable = Environment.GetEnvironmentVariable("MSBUILDTOOLTASKCANCELPROCESSWAITTIMEOUT"); if (environmentVariable != null) { int result = 0; if (int.TryParse(environmentVariable, out result) && (result >= 0)) { milliseconds = result; } } proc.WaitForExit(milliseconds); } }
public static void KillTree(this Process process, int timeout) { if (NativeMethodsShared.IsWindows) { try { // issue the kill command NativeMethodsShared.KillTree(process.Id); } catch (InvalidOperationException) { // The process already exited, which is fine, // just continue. } } else { var children = new HashSet <int>(); GetAllChildIdsUnix(process.Id, children); foreach (var childId in children) { KillProcessUnix(childId); } KillProcessUnix(process.Id); } // wait until the process finishes exiting/getting killed. // We don't want to wait forever here because the task is already supposed to be dieing, we just want to give it long enough // to try and flush what it can and stop. If it cannot do that in a reasonable time frame then we will just ignore it. process.WaitForExit(timeout); }