2using System.Diagnostics;
5using System.Threading.Tasks;
83 : base(new
ScriptNode[] { FileName,
Arguments, WorkFolder, TimeoutMs, LogStandardOutput, KillOnTimeout },
131 if (!(
Arguments[0].AssociatedObjectValue is
string FileName) ||
132 !(
Arguments[1].AssociatedObjectValue is
string Arg) ||
133 !(
Arguments[2].AssociatedObjectValue is
string WorkFolder))
139 bool LogStandardOut =
false;
140 bool KillOnTimeout =
true;
149 TimeoutMs = 1000 * 60 * 5;
153 if (
Arguments[4].AssociatedObjectValue is
bool PLogStandardOut)
154 LogStandardOut = PLogStandardOut;
161 if (
Arguments[5].AssociatedObjectValue is
bool PKillOnTimout)
162 KillOnTimeout = PKillOnTimout;
167 ProcessStartInfo ProcessInformation =
new ProcessStartInfo()
171 UseShellExecute =
false,
172 RedirectStandardError =
true,
173 RedirectStandardOutput =
true,
174 WorkingDirectory = WorkFolder,
175 CreateNoWindow =
true,
176 WindowStyle = ProcessWindowStyle.Hidden,
180 Process P =
new Process();
181 TaskCompletionSource<IElement> ResultSource =
new TaskCompletionSource<IElement>();
185 P.Exited += (Sender, e) =>
187 ResultSource.TrySetResult(
new BooleanValue(P.ExitCode == 0));
192 P.Exited += async (Sender, e) =>
198 string ErrorText = await P.StandardError.ReadToEndAsync();
203 string s = await P.StandardOutput.ReadToEndAsync();
209 ResultSource.TrySetException(ex);
215 _ = Task.Delay(TimeoutMs).ContinueWith(Prev => ResultSource.TrySetException(
new TimeoutException(
"Process did not exit within the provided time.")));
217 using (CancellationTokenRegistration Registration =
Variables.
CancellationToken.Register(() => ResultSource.TrySetException(
new OperationCanceledException(
"Evaluation cancelled."))))
219 P.StartInfo = ProcessInformation;
220 P.EnableRaisingEvents =
true;
225 BufferedLogger OutputLogger =
new BufferedLogger(Message =>
Log.
Informational(Message));
226 BufferedLogger ErrorLogger =
new BufferedLogger(Message =>
Log.
Error(Message));
228 P.ErrorDataReceived += (Sender, e) => ErrorLogger.Push(e.Data);
229 P.OutputDataReceived += (Sender, e) => OutputLogger.Push(e.Data);
231 P.BeginOutputReadLine();
232 P.BeginErrorReadLine();
237 return await ResultSource.Task;
245 if (ResultSource.Task.Exception.InnerException is OperationCanceledException)
248 if (ResultSource.Task.Exception.InnerException is TimeoutException && KillOnTimeout)
265 private class BufferedLogger
267 private readonly
object @lock;
268 private readonly StringBuilder buffer;
269 private readonly Action<string> logger;
270 private CancellationTokenSource cts;
272 public BufferedLogger(Action<string> Logger)
274 this.@lock =
new object();
275 this.buffer =
new StringBuilder();
276 this.cts =
new CancellationTokenSource();
277 this.logger = Logger;
280 public void Push(
string Text)
284 this.buffer.AppendLine(Text);
286 CancellationTokenSource Prev = this.cts;
287 this.cts =
new CancellationTokenSource();
292 _ = this.FlushDelayed(this.cts.Token);
296 private async Task FlushDelayed(CancellationToken Token)
300 await Task.Delay(500, Token);
302 catch (TaskCanceledException)
316 Message = this.buffer.ToString();
317 if (
string.IsNullOrEmpty(Message.Trim()))
323 this.logger(Message);
Static class managing the application event log. Applications and services log events on this static ...
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
static void Error(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs an error event.
static void Informational(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs an informational event.
Script runtime exception.
Class managing a script expression.
static double ToDouble(object Object)
Converts an object to a double value.
Base class for multivariate funcions.
static readonly ArgumentType[] argumentTypes5Scalar
Five scalar parameters.
ScriptNode[] Arguments
Function arguments.
static readonly ArgumentType[] argumentTypes3Scalar
Three scalar parameters.
static readonly ArgumentType[] argumentTypes6Scalar
Six scalar parameters.
static readonly ArgumentType[] argumentTypes4Scalar
Four scalar parameters.
Base class for all nodes in a parsed script tree.
int Length
Length of expression covered by node.
Expression Expression
Expression of which the node is a part.
int Start
Start position in script expression.
ShellExecute(FileName,Arguments,WorkFolder[,TimeoutMs[,LogStandardOutput[,KillOnTimeout]]])
ShellExecute(ScriptNode FileName, ScriptNode Arguments, ScriptNode WorkFolder, ScriptNode TimeoutMs, ScriptNode LogStandardOutput, int Start, int Length, Expression Expression)
ShellExecute(ScriptNode FileName, ScriptNode Arguments, ScriptNode WorkFolder, int Start, int Length, Expression Expression)
ShellExecute(FileName,Arguments,WorkFolder)
override IElement Evaluate(IElement[] Arguments, Variables Variables)
Evaluates the function.
ShellExecute(ScriptNode FileName, ScriptNode Arguments, ScriptNode WorkFolder, ScriptNode TimeoutMs, int Start, int Length, Expression Expression)
ShellExecute(FileName,Arguments,WorkFolder,TimeoutMs)
ShellExecute(ScriptNode FileName, ScriptNode Arguments, ScriptNode WorkFolder, ScriptNode TimeoutMs, ScriptNode LogStandardOutput, ScriptNode KillOnTimeout, int Start, int Length, Expression Expression)
ShellExecute(FileName,Arguments,WorkFolder,TimeoutMs,LogStandardOutput,KillOnTimeout)
override bool IsAsynchronous
If the node (or its decendants) include asynchronous evaluation. Asynchronous nodes should be evaluat...
override string FunctionName
Name of the function
override string[] DefaultArgumentNames
Default Argument names
override async Task< IElement > EvaluateAsync(IElement[] Arguments, Variables Variables)
Evaluates the function.
CancellationToken CancellationToken
Cancellation token, that can be used to monitor for script abortion.
Basic interface for all types of elements.