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
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
|
|
|