Use KillTree from Common

This commit is contained in:
John Luo 2016-03-16 18:02:59 -07:00
parent 73d50bbac3
commit 4df44c8501
6 changed files with 13 additions and 122 deletions

1
.gitignore vendored
View File

@ -28,4 +28,5 @@ project.lock.json
.testPublish/
.build/
/.vs/
testWorkDir/

View File

@ -5,14 +5,12 @@ using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.PlatformAbstractions;
using Microsoft.Extensions.Internal;
namespace Microsoft.DotNet.Watcher.Core.Internal
{
public class ProcessWatcher : IProcessWatcher
{
private static readonly TimeSpan _processKillTimeout = TimeSpan.FromSeconds(30);
private Process _runningProcess;
public int Start(string executable, string arguments, string workingDir)
@ -43,7 +41,7 @@ namespace Microsoft.DotNet.Watcher.Core.Internal
{
if (_runningProcess != null)
{
_runningProcess.KillTree(_processKillTimeout);
_runningProcess.KillTree();
}
});

View File

@ -1,113 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using Microsoft.Extensions.PlatformAbstractions;
namespace Microsoft.DotNet.Watcher.Core.Internal
{
public static class ProcessExtensions
{
private static readonly bool _isWindows = PlatformServices.Default.Runtime.OperatingSystemPlatform == Platform.Windows;
public static void KillTree(this Process process, TimeSpan timeout)
{
string stdout;
if (_isWindows)
{
RunProcessAndWaitForExit(
"taskkill",
$"/T /F /PID {process.Id}",
timeout,
out stdout);
}
else
{
var children = GetAllChildIdsUnix(process, timeout);
foreach (var childId in children)
{
KillProcessUnix(childId, timeout);
}
KillProcessUnix(process.Id, timeout);
}
}
private static IEnumerable<int> GetAllChildIdsUnix(Process process, TimeSpan timeout)
{
var children = new HashSet<int>();
GetAllChildIdsUnix(process.Id, children, timeout);
return children;
}
private static void GetAllChildIdsUnix(int parentId, ISet<int> children, TimeSpan timeout)
{
string stdout;
var exitCode = RunProcessAndWaitForExit(
"pgrep",
$"-P {parentId}",
timeout,
out stdout);
if (exitCode == 0 && !string.IsNullOrEmpty(stdout))
{
using (var reader = new StringReader(stdout))
{
while (true)
{
var text = reader.ReadLine();
if (text == null)
{
return;
}
int id;
if (int.TryParse(text, out id))
{
children.Add(id);
// Recursively get the children
GetAllChildIdsUnix(id, children, timeout);
}
}
}
}
}
private static void KillProcessUnix(int processId, TimeSpan timeout)
{
string stdout;
RunProcessAndWaitForExit(
"kill",
$"-TERM {processId}",
timeout,
out stdout);
}
private static int RunProcessAndWaitForExit(string fileName, string arguments, TimeSpan timeout, out string stdout)
{
var startInfo = new ProcessStartInfo
{
FileName = fileName,
Arguments = arguments,
RedirectStandardOutput = true,
UseShellExecute = false
};
var process = Process.Start(startInfo);
stdout = null;
if (process.WaitForExit((int)timeout.TotalMilliseconds))
{
stdout = process.StandardOutput.ReadToEnd();
}
else
{
process.Kill();
}
return process.ExitCode;
}
}
}

View File

@ -19,7 +19,10 @@
"Microsoft.Extensions.Logging.Abstractions": "1.0.0-*",
"Microsoft.Extensions.FileSystemGlobbing": "1.0.0-*",
"Microsoft.NETCore.Platforms": "1.0.1-*",
"System.Diagnostics.Process": "4.1.0-*"
"Microsoft.Extensions.ProcessHelper.Sources": {
"type": "build",
"version": "1.0.0-*"
}
},
"frameworks": {
"dnxcore50": {

View File

@ -4,14 +4,12 @@
using System;
using System.Diagnostics;
using System.IO;
using Microsoft.DotNet.Watcher.Core.Internal;
using Microsoft.Extensions.Internal;
namespace Microsoft.DotNet.Watcher.FunctionalTests
{
public class DotNetWatchScenario : IDisposable
{
private static readonly TimeSpan _processKillTimeout = TimeSpan.FromSeconds(30);
protected const string DotnetWatch = "dotnet-watch";
protected static readonly string _repositoryRoot = FindRepoRoot();
@ -38,7 +36,7 @@ namespace Microsoft.DotNet.Watcher.FunctionalTests
{
if (!WatcherProcess.HasExited)
{
WatcherProcess.KillTree(_processKillTimeout);
WatcherProcess.KillTree();
}
WatcherProcess.Dispose();
}

View File

@ -6,6 +6,10 @@
"dependencies": {
"dotnet-test-xunit": "1.0.0-dev-*",
"Microsoft.Extensions.DependencyInjection": "1.0.0-*",
"Microsoft.Extensions.ProcessHelper.Sources": {
"type": "build",
"version": "1.0.0-*"
},
"Microsoft.DotNet.Watcher.Core": "1.0.0-*",
"Microsoft.NETCore.Platforms": "1.0.1-*",
"Newtonsoft.Json": "8.0.2",