2019-01-13 19:54:44 +00:00
|
|
|
using System;
|
2016-11-01 04:07:12 +00:00
|
|
|
using System.Diagnostics;
|
|
|
|
using System.IO;
|
2019-01-13 19:20:41 +00:00
|
|
|
using System.Threading;
|
2016-11-01 04:07:12 +00:00
|
|
|
using System.Threading.Tasks;
|
|
|
|
using MediaBrowser.Model.Diagnostics;
|
|
|
|
|
2017-08-16 06:43:41 +00:00
|
|
|
namespace Emby.Server.Implementations.Diagnostics
|
2016-11-01 04:07:12 +00:00
|
|
|
{
|
|
|
|
public class CommonProcess : IProcess
|
|
|
|
{
|
|
|
|
public event EventHandler Exited;
|
|
|
|
|
|
|
|
private readonly ProcessOptions _options;
|
|
|
|
private readonly Process _process;
|
|
|
|
|
|
|
|
public CommonProcess(ProcessOptions options)
|
|
|
|
{
|
|
|
|
_options = options;
|
|
|
|
|
|
|
|
var startInfo = new ProcessStartInfo
|
|
|
|
{
|
|
|
|
Arguments = options.Arguments,
|
|
|
|
FileName = options.FileName,
|
|
|
|
WorkingDirectory = options.WorkingDirectory,
|
|
|
|
UseShellExecute = options.UseShellExecute,
|
|
|
|
CreateNoWindow = options.CreateNoWindow,
|
|
|
|
RedirectStandardError = options.RedirectStandardError,
|
|
|
|
RedirectStandardInput = options.RedirectStandardInput,
|
|
|
|
RedirectStandardOutput = options.RedirectStandardOutput
|
|
|
|
};
|
|
|
|
|
|
|
|
startInfo.ErrorDialog = options.ErrorDialog;
|
|
|
|
|
|
|
|
if (options.IsHidden)
|
|
|
|
{
|
|
|
|
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
|
|
|
}
|
|
|
|
|
|
|
|
_process = new Process
|
|
|
|
{
|
|
|
|
StartInfo = startInfo
|
|
|
|
};
|
|
|
|
|
|
|
|
if (options.EnableRaisingEvents)
|
|
|
|
{
|
|
|
|
_process.EnableRaisingEvents = true;
|
|
|
|
_process.Exited += _process_Exited;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-12 17:26:21 +00:00
|
|
|
private bool _hasExited;
|
|
|
|
private bool HasExited
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
if (_hasExited)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
_hasExited = _process.HasExited;
|
|
|
|
}
|
|
|
|
catch (InvalidOperationException)
|
|
|
|
{
|
|
|
|
_hasExited = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return _hasExited;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-01 04:07:12 +00:00
|
|
|
private void _process_Exited(object sender, EventArgs e)
|
|
|
|
{
|
2018-09-12 17:26:21 +00:00
|
|
|
_hasExited = true;
|
2016-11-01 04:07:12 +00:00
|
|
|
if (Exited != null)
|
|
|
|
{
|
2016-11-01 05:56:05 +00:00
|
|
|
Exited(this, e);
|
2016-11-01 04:07:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-06 20:50:43 +00:00
|
|
|
public ProcessOptions StartInfo => _options;
|
2016-11-01 04:07:12 +00:00
|
|
|
|
2019-01-06 20:50:43 +00:00
|
|
|
public StreamWriter StandardInput => _process.StandardInput;
|
2016-11-01 04:07:12 +00:00
|
|
|
|
2019-01-06 20:50:43 +00:00
|
|
|
public StreamReader StandardError => _process.StandardError;
|
2016-11-01 04:07:12 +00:00
|
|
|
|
2019-01-06 20:50:43 +00:00
|
|
|
public StreamReader StandardOutput => _process.StandardOutput;
|
2016-11-01 04:07:12 +00:00
|
|
|
|
2019-01-06 20:50:43 +00:00
|
|
|
public int ExitCode => _process.ExitCode;
|
2016-11-01 04:07:12 +00:00
|
|
|
|
|
|
|
public void Start()
|
|
|
|
{
|
|
|
|
_process.Start();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Kill()
|
|
|
|
{
|
|
|
|
_process.Kill();
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool WaitForExit(int timeMs)
|
|
|
|
{
|
|
|
|
return _process.WaitForExit(timeMs);
|
|
|
|
}
|
2019-01-22 15:52:26 +00:00
|
|
|
|
2017-05-26 06:48:54 +00:00
|
|
|
public Task<bool> WaitForExitAsync(int timeMs)
|
|
|
|
{
|
2019-01-22 15:52:26 +00:00
|
|
|
//Note: For this function to work correctly, the option EnableRisingEvents needs to be set to true.
|
|
|
|
|
|
|
|
if (HasExited)
|
|
|
|
{
|
|
|
|
return Task.FromResult(true);
|
|
|
|
}
|
2018-09-12 17:26:21 +00:00
|
|
|
|
|
|
|
timeMs = Math.Max(0, timeMs);
|
|
|
|
|
|
|
|
var tcs = new TaskCompletionSource<bool>();
|
|
|
|
|
|
|
|
var cancellationToken = new CancellationTokenSource(timeMs).Token;
|
|
|
|
|
|
|
|
_process.Exited += (sender, args) => tcs.TrySetResult(true);
|
|
|
|
|
|
|
|
cancellationToken.Register(() => tcs.TrySetResult(HasExited));
|
|
|
|
|
|
|
|
return tcs.Task;
|
2017-05-26 06:48:54 +00:00
|
|
|
}
|
|
|
|
|
2016-11-01 04:07:12 +00:00
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
_process.Dispose();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|