You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
5.0 KiB

#if NETFX
using Apewer;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace Apewer.Internals
{
/// <summary>控制台调用。</summary>
internal sealed class ConsoleInvoker
{
private string _filename = "";
private string _arguments = "";
private bool _running = false;
private Process _process = null;
private Exception _exception = null;
private StringBuilder _result = new StringBuilder();
private List<string> _history = new List<string>();
private Action _finished = null;
private Action<string> _received = null;
private ConsoleInvoker() { }
/// <summary></summary>
public bool Running { get { return _running; } }
/// <summary></summary>
public Action<string> Received { get { return _received; } }
/// <summary></summary>
public Action Finished { get { return _finished; } }
/// <summary></summary>
public Exception Exception { get { return _exception; } }
/// <summary></summary>
public Process Process { get { return _process; } }
/// <summary></summary>
public string FileName { get { return _filename ?? ""; } }
/// <summary></summary>
public string Arguments { get { return _arguments ?? ""; } }
/// <summary></summary>
public string Result { get { return _result.ToString(); } }
/// <summary></summary>
public void Abort()
{
PrivateStop();
_running = false;
}
private void ProcessExited(object sender, EventArgs e)
{
PrivateStop();
if (_finished != null) _finished();
_running = false;
}
private void ProcessReceived(object sender, DataReceivedEventArgs e)
{
var data = e.Data ?? "";
_result.Append(data);
_result.Append("\r\n");
_history.Add(data);
if (_received != null) _received(data);
}
private void PrivateStop()
{
if (_process == null) return;
_process.Close();
_process.Dispose();
_process = null;
}
private void PrivateRun(bool argSynchronizing)
{
_running = true;
_process = new Process();
_process.StartInfo.FileName = _filename;
_process.StartInfo.Arguments = _arguments;
_process.StartInfo.UseShellExecute = false; // 必须禁用操作系统外壳程序。
_process.StartInfo.CreateNoWindow = true;
_process.StartInfo.RedirectStandardOutput = true;
if (argSynchronizing) PrivateSynchronizingRun();
else PrivateAsynchronizingRun();
}
private void PrivateSynchronizingRun()
{
try
{
_process.Start();
var output = _process.StandardOutput.ReadToEnd();
if (output != null) _result.Append(output);
_process.WaitForExit();
_process.Close();
}
catch (Exception argException)
{
_exception = argException;
}
_process.Dispose();
_process = null;
_running = false;
}
private void PrivateAsynchronizingRun()
{
try
{
_process.EnableRaisingEvents = true;
_process.Exited += ProcessExited;
// 异步获取命令行内容。
_process.Start();
_process.BeginOutputReadLine();
// 为异步获取订阅事件。
_process.OutputDataReceived += new DataReceivedEventHandler(ProcessReceived);
}
catch (Exception argException)
{
_exception = argException;
_running = false;
}
}
/// <summary>运行进程并等待返回结果。</summary>
public static ConsoleInvoker Run(string filename, string arguments)
{
var instance = new ConsoleInvoker();
instance._filename = filename ?? "";
instance._arguments = arguments ?? "";
instance.PrivateRun(true);
return instance;
}
/// <summary>运行进程,可指定事件回调。当回调均为 NULL 时将等待返回结果。</summary>
public static ConsoleInvoker Run(string filename, string arguments, Action<string> received, Action finished)
{
var synchronizing = (received == null && finished == null) ? true : false;
var instance = new ConsoleInvoker();
instance._filename = filename ?? "";
instance._arguments = arguments ?? "";
instance._received = received;
instance._finished = finished;
instance.PrivateRun(synchronizing);
return instance;
}
}
}
#endif