mirror of
https://github.com/Stone-Red-Code/YesNt-Interpreter.git
synced 2026-09-04 00:56:31 +02:00
Add system statements ('exc')
This commit is contained in:
@@ -64,6 +64,9 @@ dotnet_naming_style.pascal_case.required_suffix =
|
|||||||
dotnet_naming_style.pascal_case.word_separator =
|
dotnet_naming_style.pascal_case.word_separator =
|
||||||
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||||
|
|
||||||
|
# S1172: Unused method parameters should be removed
|
||||||
|
dotnet_diagnostic.S1172.severity = none
|
||||||
|
|
||||||
[*.{cs,vb}]
|
[*.{cs,vb}]
|
||||||
#### Naming styles ####
|
#### Naming styles ####
|
||||||
|
|
||||||
|
|||||||
+15
-1
@@ -12,26 +12,40 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||||||
.editorconfig = .editorconfig
|
.editorconfig = .editorconfig
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YesNt.Interpreter.Tests", "YesNt.Interpreter.Tests\YesNt.Interpreter.Tests.csproj", "{2F95DCA7-3E43-4F2E-8FB2-067F0EC962B1}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YesNt.Interpreter.Tests", "YesNt.Interpreter.Tests\YesNt.Interpreter.Tests.csproj", "{2F95DCA7-3E43-4F2E-8FB2-067F0EC962B1}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|x64 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{33BDA036-A37E-475E-AACF-8ED96E31BA1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{33BDA036-A37E-475E-AACF-8ED96E31BA1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{33BDA036-A37E-475E-AACF-8ED96E31BA1A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{33BDA036-A37E-475E-AACF-8ED96E31BA1A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{33BDA036-A37E-475E-AACF-8ED96E31BA1A}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{33BDA036-A37E-475E-AACF-8ED96E31BA1A}.Debug|x64.Build.0 = Debug|x64
|
||||||
{33BDA036-A37E-475E-AACF-8ED96E31BA1A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{33BDA036-A37E-475E-AACF-8ED96E31BA1A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{33BDA036-A37E-475E-AACF-8ED96E31BA1A}.Release|Any CPU.Build.0 = Release|Any CPU
|
{33BDA036-A37E-475E-AACF-8ED96E31BA1A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{33BDA036-A37E-475E-AACF-8ED96E31BA1A}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{33BDA036-A37E-475E-AACF-8ED96E31BA1A}.Release|x64.Build.0 = Release|x64
|
||||||
{E40573DB-912A-4871-BB65-3EE6E7D72E79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{E40573DB-912A-4871-BB65-3EE6E7D72E79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{E40573DB-912A-4871-BB65-3EE6E7D72E79}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{E40573DB-912A-4871-BB65-3EE6E7D72E79}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{E40573DB-912A-4871-BB65-3EE6E7D72E79}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{E40573DB-912A-4871-BB65-3EE6E7D72E79}.Debug|x64.Build.0 = Debug|x64
|
||||||
{E40573DB-912A-4871-BB65-3EE6E7D72E79}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{E40573DB-912A-4871-BB65-3EE6E7D72E79}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{E40573DB-912A-4871-BB65-3EE6E7D72E79}.Release|Any CPU.Build.0 = Release|Any CPU
|
{E40573DB-912A-4871-BB65-3EE6E7D72E79}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{E40573DB-912A-4871-BB65-3EE6E7D72E79}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{E40573DB-912A-4871-BB65-3EE6E7D72E79}.Release|x64.Build.0 = Release|x64
|
||||||
{2F95DCA7-3E43-4F2E-8FB2-067F0EC962B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{2F95DCA7-3E43-4F2E-8FB2-067F0EC962B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{2F95DCA7-3E43-4F2E-8FB2-067F0EC962B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{2F95DCA7-3E43-4F2E-8FB2-067F0EC962B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{2F95DCA7-3E43-4F2E-8FB2-067F0EC962B1}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{2F95DCA7-3E43-4F2E-8FB2-067F0EC962B1}.Debug|x64.Build.0 = Debug|x64
|
||||||
{2F95DCA7-3E43-4F2E-8FB2-067F0EC962B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{2F95DCA7-3E43-4F2E-8FB2-067F0EC962B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{2F95DCA7-3E43-4F2E-8FB2-067F0EC962B1}.Release|Any CPU.Build.0 = Release|Any CPU
|
{2F95DCA7-3E43-4F2E-8FB2-067F0EC962B1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{2F95DCA7-3E43-4F2E-8FB2-067F0EC962B1}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{2F95DCA7-3E43-4F2E-8FB2-067F0EC962B1}.Release|x64.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"YesNt.CodeEditor": {
|
||||||
|
"commandName": "Project"
|
||||||
|
},
|
||||||
|
"WSL": {
|
||||||
|
"commandName": "WSL2",
|
||||||
|
"environmentVariables": {},
|
||||||
|
"distributionName": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net5.0</TargetFramework>
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
|
|
||||||
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using YesNt.Interpreter.Attributes;
|
||||||
|
using YesNt.Interpreter.Enums;
|
||||||
|
using YesNt.Interpreter.Runtime;
|
||||||
|
using YesNt.Interpreter.Utilities;
|
||||||
|
|
||||||
|
namespace YesNt.Interpreter.Statements
|
||||||
|
{
|
||||||
|
internal class SystemStatements : StatementRuntimeInformation
|
||||||
|
{
|
||||||
|
[Statement("exc", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta, Priority = Priority.Low, Seperator = "|")]
|
||||||
|
public void ExecuteProgramWithArgs(string input)
|
||||||
|
{
|
||||||
|
string[] parts = input.FromSaveString().Split('|');
|
||||||
|
parts[0] = parts[0].Trim();
|
||||||
|
|
||||||
|
string[] functionArgumets = parts[1].Split(',');
|
||||||
|
|
||||||
|
foreach (string argumanet in functionArgumets)
|
||||||
|
{
|
||||||
|
RuntimeInfo.InParametersStack.Push(argumanet.Trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
StartProcess(parts[0], string.Join(string.Empty, RuntimeInfo.InParametersStack.Reverse()));
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException)
|
||||||
|
{
|
||||||
|
RuntimeInfo.Exit($"Cannot find file \"{parts[0]}\".", false);
|
||||||
|
}
|
||||||
|
catch (Win32Exception ex)
|
||||||
|
{
|
||||||
|
RuntimeInfo.Exit($"Failed to start \"{parts[0]}\". {ex.Message}", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//HACK: Clear line to avoid execution from other "exc" statement
|
||||||
|
RuntimeInfo.CurrentLine = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Statement("exc", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta, Priority = Priority.VeryLow)]
|
||||||
|
public void ExecuteProgram(string input)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
StartProcess(input, string.Join(string.Empty, RuntimeInfo.InParametersStack.Reverse()));
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException)
|
||||||
|
{
|
||||||
|
RuntimeInfo.Exit($"Cannot find file \"{input}\".", false);
|
||||||
|
}
|
||||||
|
catch (Win32Exception ex)
|
||||||
|
{
|
||||||
|
RuntimeInfo.Exit($"Failed to start \"{input}\". {ex.Message}", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartProcess(string name, string args)
|
||||||
|
{
|
||||||
|
FixedProcess process = new FixedProcess
|
||||||
|
{
|
||||||
|
StartInfo = new ProcessStartInfo()
|
||||||
|
{
|
||||||
|
FileName = name,
|
||||||
|
Arguments = args,
|
||||||
|
RedirectStandardOutput = true,
|
||||||
|
RedirectStandardError = true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
process.OutputDataReceived += Process_OutputDataReceived;
|
||||||
|
process.ErrorDataReceived += Process_ErrorDataReceived;
|
||||||
|
|
||||||
|
process.Start();
|
||||||
|
process.BeginOutputReadLine();
|
||||||
|
process.BeginErrorReadLine();
|
||||||
|
process.WaitForExit();
|
||||||
|
|
||||||
|
RuntimeInfo.InParametersStack.Clear();
|
||||||
|
RuntimeInfo.OutParametersStack.Clear();
|
||||||
|
RuntimeInfo.OutParametersStack.Push(process.ExitCode.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Process_ErrorDataReceived(object sender, Utilities.DataReceivedEventArgs e)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(e.Data))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RuntimeInfo.OutParametersStack.Push(e.Data);
|
||||||
|
Console.Write("Error: " + e.Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Process_OutputDataReceived(object sender, Utilities.DataReceivedEventArgs e)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(e.Data))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RuntimeInfo.OutParametersStack.Push(e.Data);
|
||||||
|
Console.Write(e.Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,316 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace YesNt.Interpreter.Utilities
|
||||||
|
{
|
||||||
|
internal delegate void UserCallBack(string data);
|
||||||
|
|
||||||
|
public delegate void DataReceivedEventHandler(object sender, DataReceivedEventArgs e);
|
||||||
|
|
||||||
|
public class FixedProcess : Process
|
||||||
|
{
|
||||||
|
internal AsyncStreamReader output;
|
||||||
|
internal AsyncStreamReader error;
|
||||||
|
|
||||||
|
public new event DataReceivedEventHandler OutputDataReceived;
|
||||||
|
|
||||||
|
public new event DataReceivedEventHandler ErrorDataReceived;
|
||||||
|
|
||||||
|
public new void BeginOutputReadLine()
|
||||||
|
{
|
||||||
|
Stream baseStream = StandardOutput.BaseStream;
|
||||||
|
output = new AsyncStreamReader(this, baseStream, new UserCallBack(FixedOutputReadNotifyUser), StandardOutput.CurrentEncoding);
|
||||||
|
output.BeginReadLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
public new void BeginErrorReadLine()
|
||||||
|
{
|
||||||
|
Stream baseStream = StandardError.BaseStream;
|
||||||
|
error = new AsyncStreamReader(this, baseStream, new UserCallBack(FixedErrorReadNotifyUser), StandardError.CurrentEncoding);
|
||||||
|
error.BeginReadLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void FixedOutputReadNotifyUser(string data)
|
||||||
|
{
|
||||||
|
DataReceivedEventHandler outputDataReceived = OutputDataReceived;
|
||||||
|
if (outputDataReceived != null)
|
||||||
|
{
|
||||||
|
DataReceivedEventArgs dataReceivedEventArgs = new DataReceivedEventArgs(data);
|
||||||
|
if (SynchronizingObject != null && SynchronizingObject.InvokeRequired)
|
||||||
|
{
|
||||||
|
SynchronizingObject.Invoke(outputDataReceived, new object[]
|
||||||
|
{
|
||||||
|
this,
|
||||||
|
dataReceivedEventArgs
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
outputDataReceived(this, dataReceivedEventArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void FixedErrorReadNotifyUser(string data)
|
||||||
|
{
|
||||||
|
DataReceivedEventHandler errorDataReceived = ErrorDataReceived;
|
||||||
|
if (errorDataReceived != null)
|
||||||
|
{
|
||||||
|
DataReceivedEventArgs dataReceivedEventArgs = new DataReceivedEventArgs(data);
|
||||||
|
if (SynchronizingObject != null && SynchronizingObject.InvokeRequired)
|
||||||
|
{
|
||||||
|
SynchronizingObject.Invoke(errorDataReceived, new object[]
|
||||||
|
{
|
||||||
|
this,
|
||||||
|
dataReceivedEventArgs
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
errorDataReceived(this, dataReceivedEventArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class AsyncStreamReader : IDisposable
|
||||||
|
{
|
||||||
|
internal const int DefaultBufferSize = 1024;
|
||||||
|
private Stream stream;
|
||||||
|
private Encoding encoding;
|
||||||
|
private Decoder decoder;
|
||||||
|
private byte[] byteBuffer;
|
||||||
|
private char[] charBuffer;
|
||||||
|
private UserCallBack userCallBack;
|
||||||
|
private bool cancelOperation;
|
||||||
|
private ManualResetEvent eofEvent;
|
||||||
|
private readonly Queue messageQueue;
|
||||||
|
private StringBuilder sb;
|
||||||
|
private bool bLastCarriageReturn;
|
||||||
|
public virtual Encoding CurrentEncoding => encoding;
|
||||||
|
public virtual Stream BaseStream => stream;
|
||||||
|
|
||||||
|
internal AsyncStreamReader(Process process, Stream stream, UserCallBack callback, Encoding encoding) : this(process, stream, callback, encoding, 1024)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal AsyncStreamReader(Process process, Stream stream, UserCallBack callback, Encoding encoding, int bufferSize)
|
||||||
|
{
|
||||||
|
Init(process, stream, callback, encoding, bufferSize);
|
||||||
|
messageQueue = new Queue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Init(Process process, Stream stream, UserCallBack callback, Encoding encoding, int bufferSize)
|
||||||
|
{
|
||||||
|
this.stream = stream;
|
||||||
|
this.encoding = encoding;
|
||||||
|
userCallBack = callback;
|
||||||
|
decoder = encoding.GetDecoder();
|
||||||
|
if (bufferSize < 128)
|
||||||
|
{
|
||||||
|
bufferSize = 128;
|
||||||
|
}
|
||||||
|
byteBuffer = new byte[bufferSize];
|
||||||
|
int _maxCharsPerBuffer = encoding.GetMaxCharCount(bufferSize);
|
||||||
|
charBuffer = new char[_maxCharsPerBuffer];
|
||||||
|
cancelOperation = false;
|
||||||
|
eofEvent = new ManualResetEvent(false);
|
||||||
|
sb = null;
|
||||||
|
bLastCarriageReturn = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Close()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && stream != null)
|
||||||
|
{
|
||||||
|
stream.Close();
|
||||||
|
}
|
||||||
|
if (stream != null)
|
||||||
|
{
|
||||||
|
stream = null;
|
||||||
|
encoding = null;
|
||||||
|
decoder = null;
|
||||||
|
byteBuffer = null;
|
||||||
|
charBuffer = null;
|
||||||
|
}
|
||||||
|
if (eofEvent != null)
|
||||||
|
{
|
||||||
|
eofEvent.Close();
|
||||||
|
eofEvent = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void BeginReadLine()
|
||||||
|
{
|
||||||
|
if (cancelOperation)
|
||||||
|
{
|
||||||
|
cancelOperation = false;
|
||||||
|
}
|
||||||
|
if (sb == null)
|
||||||
|
{
|
||||||
|
sb = new StringBuilder(1024);
|
||||||
|
stream.BeginRead(byteBuffer, 0, byteBuffer.Length, new AsyncCallback(ReadBuffer), null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FlushMessageQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void CancelOperation()
|
||||||
|
{
|
||||||
|
cancelOperation = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReadBuffer(IAsyncResult ar)
|
||||||
|
{
|
||||||
|
int num;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
num = stream.EndRead(ar);
|
||||||
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
num = 0;
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
num = 0;
|
||||||
|
}
|
||||||
|
if (num == 0)
|
||||||
|
{
|
||||||
|
lock (messageQueue)
|
||||||
|
{
|
||||||
|
if (sb.Length != 0)
|
||||||
|
{
|
||||||
|
messageQueue.Enqueue(sb.ToString());
|
||||||
|
sb.Length = 0;
|
||||||
|
}
|
||||||
|
messageQueue.Enqueue(null);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FlushMessageQueue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
eofEvent.Set();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int chars = decoder.GetChars(byteBuffer, 0, num, charBuffer, 0);
|
||||||
|
sb.Append(charBuffer, 0, chars);
|
||||||
|
GetLinesFromStringBuilder();
|
||||||
|
stream.BeginRead(byteBuffer, 0, byteBuffer.Length, new AsyncCallback(ReadBuffer), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetLinesFromStringBuilder()
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
int num = 0;
|
||||||
|
int length = sb.Length;
|
||||||
|
if (bLastCarriageReturn && length > 0 && sb[0] == '\n')
|
||||||
|
{
|
||||||
|
i = 1;
|
||||||
|
num = 1;
|
||||||
|
bLastCarriageReturn = false;
|
||||||
|
}
|
||||||
|
while (i < length)
|
||||||
|
{
|
||||||
|
char c = sb[i];
|
||||||
|
if (c == '\r' || c == '\n')
|
||||||
|
{
|
||||||
|
if (c == '\r' && i + 1 < length && sb[i + 1] == '\n')
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
string obj = sb.ToString(num, i + 1 - num);
|
||||||
|
|
||||||
|
num = i + 1;
|
||||||
|
|
||||||
|
lock (messageQueue)
|
||||||
|
{
|
||||||
|
messageQueue.Enqueue(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush Fix: Send Whatever is left in the buffer
|
||||||
|
string endOfBuffer = sb.ToString(num, length - num);
|
||||||
|
lock (messageQueue)
|
||||||
|
{
|
||||||
|
messageQueue.Enqueue(endOfBuffer);
|
||||||
|
num = length;
|
||||||
|
}
|
||||||
|
// End Flush Fix
|
||||||
|
|
||||||
|
if (sb[length - 1] == '\r')
|
||||||
|
{
|
||||||
|
bLastCarriageReturn = true;
|
||||||
|
}
|
||||||
|
if (num < length)
|
||||||
|
{
|
||||||
|
sb.Remove(0, num);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.Length = 0;
|
||||||
|
}
|
||||||
|
FlushMessageQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FlushMessageQueue()
|
||||||
|
{
|
||||||
|
while (messageQueue.Count > 0)
|
||||||
|
{
|
||||||
|
lock (messageQueue)
|
||||||
|
{
|
||||||
|
if (messageQueue.Count > 0)
|
||||||
|
{
|
||||||
|
string data = (string)messageQueue.Dequeue();
|
||||||
|
if (!cancelOperation)
|
||||||
|
{
|
||||||
|
userCallBack(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void WaitUtilEOF()
|
||||||
|
{
|
||||||
|
if (eofEvent != null)
|
||||||
|
{
|
||||||
|
eofEvent.WaitOne();
|
||||||
|
eofEvent.Close();
|
||||||
|
eofEvent = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DataReceivedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
internal string _data;
|
||||||
|
|
||||||
|
/// <summary>Gets the line of characters that was written to a redirected <see cref="T:System.Diagnostics.Process" /> output stream.</summary>
|
||||||
|
/// <returns>The line that was written by an associated <see cref="T:System.Diagnostics.Process" /> to its redirected <see cref="P:System.Diagnostics.Process.StandardOutput" /> or <see cref="P:System.Diagnostics.Process.StandardError" /> stream.</returns>
|
||||||
|
/// <filterpriority>2</filterpriority>
|
||||||
|
public string Data => _data;
|
||||||
|
|
||||||
|
internal DataReceivedEventArgs(string data)
|
||||||
|
{
|
||||||
|
_data = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
<ApplicationIcon />
|
<ApplicationIcon />
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<StartupObject />
|
<StartupObject />
|
||||||
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Reference in New Issue
Block a user