Skip to content

Commit

Permalink
现在,LeafExtension可以申请分配ICommandExecutor了,这个版本有个严重bug:在LeafUI结束后,无规律出现N…
Browse files Browse the repository at this point in the history
…ull异常,导致秋之盒完全崩溃
  • Loading branch information
zsh2401 committed Jun 3, 2019
1 parent 2863af5 commit 59a40e5
Show file tree
Hide file tree
Showing 17 changed files with 287 additions and 67 deletions.
4 changes: 4 additions & 0 deletions AutumnBox.Basic.Shared/AutumnBox.Basic.Shared.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@
<Compile Include="$(MSBuildThisFileDirectory)Calling\CommandingObject.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Calling\CommandStation.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Calling\Fastboot\FastbootCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Calling\HestExecutor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Calling\ICommandExecutor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Calling\ICommandResult.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Calling\IProcessBasedCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Calling\IProcessBasedCommandResult.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Calling\ProcessBasedCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Calling\ProcessExtension.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Calling\BasicCommandExecutor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Calling\ProcessHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\CommandExecutedEventArgs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\CommandExecutingEventArgs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\ICommandStationObject.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\INotifyOutput.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\IReceiveOutputByTo.cs" />
Expand Down
10 changes: 10 additions & 0 deletions AutumnBox.Basic.Shared/Calling/CommandExecutorExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace AutumnBox.Basic.Calling
{
public static class CommandExecutorExtension
{
}
}
99 changes: 99 additions & 0 deletions AutumnBox.Basic.Shared/Calling/HestExecutor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Management;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using AutumnBox.Basic.Data;

namespace AutumnBox.Basic.Calling
{
public class HestExecutor : ICommandExecutor
{
private class HestExecutorResult : ICommandResult
{
public int ExitCode { get; set; } = 0;

public Output Output { get; set; } = null;
}
public event EventHandler Disposed;
public event EventHandler<CommandExecutingEventArgs> CommandExecuting;
public event EventHandler<CommandExecutedEventArgs> CommandExecuted;
public event EventHandler<OutputReceivedEventArgs> OutputReceived;
private Process currentProcess;
private readonly OutputBuilder outputBuilder = new OutputBuilder();
private ProcessStartInfo GetStartInfo(string fileName, string args)
{
return new ProcessStartInfo()
{
FileName = fileName,
Arguments = args,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardError = true,
RedirectStandardOutput = true
};
}
private readonly object _executingLock = new object();

public ICommandResult Execute(string fileName, string args)
{
lock (_executingLock)
{
if (isDisposed) throw new ObjectDisposedException(nameof(HestExecutor));
//输出构造器
outputBuilder.Clear();
//记录开始时间
DateTime start = DateTime.Now;
//开始进程
currentProcess = Process.Start(GetStartInfo(fileName, args));

//监听
currentProcess.OutputDataReceived += (s, e) =>
{
outputBuilder.AppendOut(e.Data);
OutputReceived?.Invoke(this, new OutputReceivedEventArgs(e, false));
};
currentProcess.ErrorDataReceived += (s, e) =>
{
outputBuilder.AppendError(e.Data);
OutputReceived?.Invoke(this, new OutputReceivedEventArgs(e, true));
};
currentProcess.BeginOutputReadLine();
currentProcess.BeginErrorReadLine();

//触发事件
CommandExecuting?.Invoke(this, new CommandExecutingEventArgs(fileName, args));

//等待进程结束
currentProcess.WaitForExit();
currentProcess.CancelErrorRead();
currentProcess.CancelOutputRead();

//记录结束时间
DateTime end = DateTime.Now;
//构造结果对象
var result = new HestExecutorResult() { ExitCode = currentProcess.ExitCode, Output = outputBuilder.Result };
//触发结束事件
CommandExecuted?.Invoke(this, new CommandExecutedEventArgs(fileName, args, result, end - start));
//返回结果
return result;
};
}

private bool isDisposed = false;

public void Dispose()
{
isDisposed = true;
CancelCurrent();
}

public void CancelCurrent()
{
currentProcess?.KillByTaskKill();
}
}
}
42 changes: 42 additions & 0 deletions AutumnBox.Basic.Shared/Calling/ICommandExecutor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using AutumnBox.Basic.Data;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace AutumnBox.Basic.Calling
{
/// <summary>
/// 标准的CommandExecutor命令执行器
/// </summary>
public interface ICommandExecutor : IDisposable
{
/// <summary>
/// 当CommandExecutor被析构时触发
/// </summary>
event EventHandler Disposed;
/// <summary>
/// 当一条命令开始执行时触发
/// </summary>
event EventHandler<CommandExecutingEventArgs> CommandExecuting;
/// <summary>
/// 当一条命令完成时触发
/// </summary>
event EventHandler<CommandExecutedEventArgs> CommandExecuted;
/// <summary>
/// 接收到输出时触发的事件
/// </summary>
event EventHandler<OutputReceivedEventArgs> OutputReceived;
/// <summary>
/// 执行命令
/// </summary>
/// <param name="fileName"></param>
/// <param name="args"></param>
/// <returns></returns>
ICommandResult Execute(string fileName, string args);
/// <summary>
/// 取消执行当前执行的命令
/// </summary>
void CancelCurrent();
}
}
28 changes: 28 additions & 0 deletions AutumnBox.Basic.Shared/Data/CommandExecutedEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using AutumnBox.Basic.Calling;
using System;
using System.Collections.Generic;
using System.Text;

namespace AutumnBox.Basic.Data
{
public class CommandExecutedEventArgs : EventArgs
{
TimeSpan UsedTime { get; }
ICommandResult Result { get; }
public string FileName { get; }
public string Args { get; }
public TimeSpan Span { get; }

public CommandExecutedEventArgs(string fileName, string args, ICommandResult result, TimeSpan span)
{
if (string.IsNullOrEmpty(fileName))
{
throw new ArgumentException("message", nameof(fileName));
}

FileName = fileName;
Args = args;
Span = span;
}
}
}
17 changes: 17 additions & 0 deletions AutumnBox.Basic.Shared/Data/CommandExecutingEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace AutumnBox.Basic.Data
{
public class CommandExecutingEventArgs : EventArgs
{
public string FileName { get; }
public string[] Args { get; }
public CommandExecutingEventArgs(string fileName, params string[] args)
{
FileName = fileName;
Args = args;
}
}
}
13 changes: 12 additions & 1 deletion AutumnBox.Basic.Shared/Data/OutputReceivedEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,22 @@ public class OutputReceivedEventArgs : EventArgs
/// </summary>
/// <param name="sourceEventArgs"></param>
/// <param name="isError"></param>
public OutputReceivedEventArgs(DataReceivedEventArgs sourceEventArgs, bool isError = false) {
public OutputReceivedEventArgs(DataReceivedEventArgs sourceEventArgs, bool isError = false)
{
IsError = isError;
SourceArgs = sourceEventArgs;
Text = sourceEventArgs.Data;
}
/// <summary>
/// 构建
/// </summary>
/// <param name="text"></param>
/// <param name="isError"></param>
public OutputReceivedEventArgs(string text, bool isError = false)
{
Text = text;
IsError = isError;
}
}
internal class CaoNa_I_Miss_You { }
}
22 changes: 12 additions & 10 deletions AutumnBox.CoreModules/Extensions/NoMatter/EHoldMyHand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*************************************************/
using AutumnBox.Basic.Calling;
using AutumnBox.Basic.Device;
using AutumnBox.Basic.ManagedAdb;
using AutumnBox.CoreModules.Extensions.Poweron.Dpm;
using AutumnBox.Logging;
using AutumnBox.OpenFramework.Content;
Expand All @@ -30,21 +31,22 @@ namespace AutumnBox.CoreModules.Extensions.Hidden
internal class EHoldMyHand : LeafExtensionBase
{
[LMain]
public void Main(IDevice device, ILeafUI ui, IClassTextManager text, IEmbeddedFileManager emb, ITemporaryFloder tmp)
public void Main(ILeafUI ui, ICommandExecutor executor)
{
using (ui)
{
ui.Title = "TEST";
ui.Show();
////storageManager = OpenApiFactory.Get<IStorageManager>(this, "123");
//ui.WriteLine(text["fuck"]);
//ui.WriteLine(this.GetType().Namespace);
//ui.ShowMessage("wow");
//ui.WriteOutput(ui.DoYN("wwww", "yes", "no"));
//ui.WriteOutput(ui.DoChoice("www"));
//ui.WriteOutput(ui.SelectFrom(null, "a", "b", "c", "d"));
var dpmpro = new DpmPro(new CommandExecutor(), emb, tmp, new UsbDevice("aaabbb", DeviceState.Poweron));
dpmpro.Extract();
ui.Closing += (s, e) =>
{
executor.Dispose();
return true;
};
ui.WriteLine("wtf");
//executor.OutputReceived += (s, e) => ui.WriteOutput(e.Text);
var result = executor.Execute("cmd.exe","/c ping baidu.com");
//ui.WriteOutput("===");
//ui.WriteOutput(result.Output);
ui.Finish();
}
}
Expand Down
6 changes: 3 additions & 3 deletions AutumnBox.CoreModules/Extensions/NoMatter/ELeafUIDemo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace AutumnBox.CoreModules.Extensions.NoMatter
{
[ExtName("Leaf UI Demo", "zh-cn:LeafUI官方演示")]
[ExtRequiredDeviceStates(LeafConstants.NoMatter)]
[ExtText("testkey","默认值,defaultvalue","zh-cn:中文值")]//本模块专用文本!
[ExtText("testkey", "默认值,defaultvalue", "zh-cn:中文值")]//本模块专用文本!
[ExtDeveloperMode]
public class ELeafUIDemo : LeafExtensionBase
{
Expand Down Expand Up @@ -43,14 +43,14 @@ public void Main(ILeafUI ui, Context context, IClassTextManager textManager)
//将LeafUI的标题设置为本模块的名称
ui.Title = this.GetName();
//绑定LeafUI关闭事件,并非必要的操作
ui.CloseButtonClicked += (s, e) =>
ui.Closing += (s, e) =>
{
/*
* 当用户点击停止按钮时发生
* 请在此处销毁你调用的资源
* 如果你不想你的模块被中途停止,请返回false
*/
e.CanBeClosed = false;
return true;
};

/*完成初始化,调用展示方法后,UI将可见*/
Expand Down
7 changes: 4 additions & 3 deletions AutumnBox.GUI/View/Windows/LeafWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ private void TBOutput_TextChanged(object sender, TextChangedEventArgs e)
{
(sender as TextBox).ScrollToEnd();
}
//~LeafWindow() {
// Trace.WriteLine("Leaf window ~");
//}
~LeafWindow()
{
Trace.WriteLine("Leaf window ~");
}
}
}
Loading

0 comments on commit 59a40e5

Please sign in to comment.