public async Task <int> ExecuteWithProcessX() { var counter = 0; var(_, stdOutStream, stdErrStream) = ProcessX.GetDualAsyncEnumerable(FilePath, arguments: Args); var consumeStdOutTask = Task.Run(async() => { await foreach (var _ in stdOutStream) { counter++; } }); var consumeStdErrorTask = Task.Run(async() => { await foreach (var _ in stdErrStream) { counter++; } }); await Task.WhenAll(consumeStdOutTask, consumeStdErrorTask); return(counter); }
/// <summary> /// // TODO [C.Groothoff]: summary. /// </summary> /// <param name="wrapperFunction">Just use <see cref="MethodBase.GetCurrentMethod()"/> as value.</param> /// <param name="beforeArguments">Runtime relevant argument parts that should be placed before the <see cref="ProcessFunctionSpecifiedInformation.ProcessArguments"/> part.</param> /// <param name="afterArguments">Runtime relevant argument parts that should be placed after the <see cref="ProcessFunctionSpecifiedInformation.ProcessArguments"/> part.</param> /// <param name="cancellationToken">Token to cancel the process call.</param> /// <returns>The result of the executed process.</returns> protected async Task <string[]> EvaluateWrapperFunction(MethodBase wrapperFunction, string beforeArguments = null, string afterArguments = null, CancellationToken cancellationToken = default) { // Check if the given function is from the class self. Others are not allowed. var derivedType = GetType(); if (wrapperFunction.DeclaringType != derivedType) { throw new InvalidOperationException( $"The function '{nameof(EvaluateWrapperFunction)}' should only called with functions from the class itself!" + $"The class '{derivedType.FullName}' has no function named '{wrapperFunction.Name}'."); } // Check if the given function also contains the needed attribute. var wrapperArguments = (ProcessFunctionSpecifiedInformation)wrapperFunction .GetCustomAttributes(typeof(ProcessFunctionSpecifiedInformation), true) .FirstOrDefault() ?? throw new InvalidOperationException( $"Missing the '{nameof(ProcessFunctionSpecifiedInformation)}' attribute on the given function!"); var processParts = new List <string> { ProcessName }; processParts.AddIfNotNull(beforeArguments); processParts.Add(wrapperArguments.ProcessArguments); processParts.AddIfNotNull(afterArguments); var wholeProcessCall = string.Join(' ', processParts); Log.Verbose("'{WholeCommand}' is the evaluated process call for the function '{WrapperFunctionName}'", wholeProcessCall, wrapperFunction.GetType().FullName); return(await ProcessX.StartAsync(wholeProcessCall).ToTask(cancellationToken)); }
/// <summary> /// Checks if the given process can be started. /// If that's not the case, the program isn't installed or added to the paths. /// </summary> /// <param name="processName">The process name to check!</param> /// <returns></returns> public async Task <bool> IsProcessStartAble(string processName) { if (processName.Contains(" ")) { throw new ArgumentException( $"Spaces means arguments, found some in '{processName}'! We just want the process name!"); } try { var timeoutToken = CreateTimeoutToken(); var processCall = $"{processName} --version"; // TODO [C.Groothoff]: Reusabler way of the "--version" implementation. _ = await ProcessX.StartAsync(processCall).ToTask(timeoutToken); return(true); } catch (OperationCanceledException) { Log.Warning("Starting process '{ProcessName}' was canceled by timeout!", processName); } catch (Exception ex) { Log.Warning("Starting '{ProcessName}' failed. Reason: '{ExceptionReason}!'", processName, ex.Message.Replace(Environment.NewLine, string.Empty)); } return(false); }
static async Task Main(string[] args) { using (var tcs = new CancellationTokenSource(TimeSpan.FromSeconds(1))) { await foreach (var item in ProcessX.StartAsync("dotnet --info").WithCancellation(tcs.Token)) { Console.WriteLine(item); } } }
public async Task <(string, string)> ExecuteWithProcessX() { var(_, stdOutStream, stdErrStream) = ProcessX.GetDualAsyncEnumerable(FilePath, arguments: Args); var stdOutTask = stdOutStream.ToTask(); var stdErrTask = stdErrStream.ToTask(); await Task.WhenAll(stdOutTask, stdErrTask); return(string.Join(Environment.NewLine, stdOutTask.Result), string.Join(Environment.NewLine, stdErrTask.Result)); }
public RedHttpServerContext(string url, string staticPath = null) { // Binding to all local IP addresses requires adding an HTTP URL ACL rule // This may prompt to "allow app to modify your device" ProcessX.AddHttpUrlAclIfNeeded(url); // Create the underlying RedHttpServer (see https://github.com/rosenbjerg/Red) this.webServer = new Red.RedHttpServer(8000, staticPath); // Create the IWebApi and ISubscriptionApi wrappers this.webApi = new RedHttpServerWebApi(webServer); this.subscriptionApi = new RedHttpServerSubscriptionApi(webServer, path: "/ws"); }
static async Task Main(string[] args) { var path = @"..\..\..\..\ReturnMessage\ReturnMessage.csproj"; await ProcessX.StartAsync($"dotnet run --project {path} -- str -m foo -c 10").WriteLineAllAsync(); //var bin = await ProcessX.StartReadBinaryAsync($"dotnet run --project {path} -- bin -s 999 -c 10 -w 10"); //// first argument is Process, if you want to know ProcessID, use StandardInput, use it. //var (_, stdOut, stdError) = ProcessX.GetDualAsyncEnumerable("dotnet --foo --bar"); //var consumeStdOut = Task.Run(async () => //{ // await foreach (var item in stdOut) // { // Console.WriteLine("STDOUT: " + item); // } //}); //var errorBuffered = new List<string>(); //var consumeStdError = Task.Run(async () => //{ // await foreach (var item in stdError) // { // Console.WriteLine("STDERROR: " + item); // errorBuffered.Add(item); // } //}); //try //{ // await Task.WhenAll(consumeStdOut, consumeStdError); //} //catch (ProcessErrorException ex) //{ // // stdout iterator throws exception when exitcode is not 0. // Console.WriteLine("ERROR, ExitCode: " + ex.ExitCode); // // ex.ErrorOutput is empty, if you want to use it, buffer yourself. // // Console.WriteLine(string.Join(Environment.NewLine, errorBuffered)); //} //Console.WriteLine(bin.Length); Console.WriteLine(IsInvalidExitCode(0)); AcceptableExitCodes = new[] { 1 }; Console.WriteLine(IsInvalidExitCode(0)); Console.WriteLine(IsInvalidExitCode(1)); AcceptableExitCodes = new[] { 0, 1 }; Console.WriteLine(IsInvalidExitCode(0)); Console.WriteLine(IsInvalidExitCode(1)); }
public async Task StartWorkerAsync(DFrameOptions options, int processCount, IServiceProvider provider, IFailSignal failSignal, CancellationToken cancellationToken) { this.failSignal = failSignal; var location = Assembly.GetEntryAssembly().Location; var cmd = $"dotnet \"{location}\" --worker-flag"; for (int i = 0; i < processCount; i++) { var startProcessTask = ProcessX.StartAsync(cmd); WriteAll(startProcessTask); } }
static void Main(string[] args) { const int port = 8000; var wwwPath = args.Length > 0 ? args[0] : "../../../www"; using (var embedIOContext = new EmbedIOContext($"http://+:{port}/", wwwPath)) { // When a client subscribes to "data-feed", create an instance of RunEvery that pushes // a new row over the channel every 1000ms embedIOContext.SubscriptionApi.OnSubscribe("data-feed", (vars, channel) => { return(new RunEvery(() => { var row = GetRow(); // You can specify whatever data type you wish to help your clients // understand what they are receiving, just using "data" in this example channel.Queue("data", row); }, 1000)); }); embedIOContext.Start(); ProcessX.OpenBrowser($"http://localhost:{port}/"); Console.ReadLine(); } }
public EmbedIOContext(string url, string staticPath = null) { // Binding to all local IP addresses requires adding an HTTP URL ACL rule // This may prompt to "allow app to modify your device" ProcessX.AddHttpUrlAclIfNeeded(url); // Create the underlying EmbedIOWebServer (see https://github.com/unosquare/embedio) this.webServer = new Unosquare.Labs.EmbedIO.WebServer(url); if (!string.IsNullOrEmpty(staticPath)) { logger.Debug($"EmbedIOContext():staticPath={staticPath}"); this.webServer.RegisterModule(new StaticFilesModule(staticPath, headers: new System.Collections.Generic.Dictionary <string, string> { ["Cache-Control"] = "no-cache, no-store, must-revalidate", ["Pragma"] = "no-cache", ["Expires"] = "0" })); } //Unosquare.Swan.Terminal.Settings.DisplayLoggingMessageType = Unosquare.Swan.LogMessageType.Trace; // Create the IWebApi and ISubscriptionApi wrappers this.webApi = new EmbedIOWebApi(webServer); this.subscriptionApi = new EmbedIOSubscriptionApi(webServer, path: "/ws"); }
/// <inheritdoc /> public async ValueTask ExecuteAsync(string filePath) { if (!File.Exists(filePath)) { throw new FileNotFoundException(this.resourceService.GetCultureString(nameof(Resources.ExecutableFileNotFound)), filePath); } var(_, stdOut, stdError) = ProcessX.GetDualAsyncEnumerable(fileName: filePath, null, Directory.GetParent(filePath).FullName); var stdOutTask = Task.Run(async() => { await foreach (var item in stdOut) { this.logger.ZLogInformation(item); } }); var stdErrorTask = Task.Run(async() => { await foreach (var item in stdError) { this.logger.ZLogError(item); } }); try { await Task.WhenAll(stdOutTask, stdErrorTask).ConfigureAwait(false); } catch (ProcessErrorException processErrorException) { this.logger.ZLogError( processErrorException, "[{0}] {1}", DateTimeOffset.Now.LocalDateTime.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.CurrentCulture), this.resourceService.GetCultureString(nameof(Resources.FailedStartExecutableFile))); throw; } }
// Using async Task Main() requires adding <LangVersion>latest</LangVersion> to .csproj file static async Task Main(string[] args) { const int port = 8000; var wwwPath = args.Length > 0 ? args[0] : "../../../www"; using (var embedIOContext = new Butterfly.Web.EmbedIO.EmbedIOContext($"http://+:{port}/", wwwPath)) { // Create a MemoryDatabase (no persistence, limited features) var database = new Butterfly.Db.Memory.MemoryDatabase(); await database.CreateFromSqlAsync(@"CREATE TABLE message ( id INT NOT NULL AUTO_INCREMENT, text VARCHAR(40) NOT NULL, PRIMARY KEY (id) );"); // Listen for API requests embedIOContext.WebApi.OnPost("/api/message/insert", async(req, res) => { var text = await req.ParseAsJsonAsync <dynamic>(); await database.InsertAndCommitAsync <long>("message", new { text }); }); // Listen for subscribe requests... // - The handler must return an IDisposable object (gets disposed when the channel is unsubscribed) // - The handler can push data to the client by calling channel.Queue() embedIOContext.SubscriptionApi.OnSubscribe("my-channel", (vars, channel) => { return(database.CreateAndStartDynamicViewAsync("message", dataEventTransaction => channel.Queue(dataEventTransaction))); }); embedIOContext.Start(); Console.WriteLine($"Opening http://localhost:{port}/ in a browser..."); ProcessX.OpenBrowser($"http://localhost:{port}/"); Console.ReadLine(); } }
async Task RunSolver(ISolver solver) { var testDir = Directory.EnumerateDirectories(CheckerRoot, solver.Name, SearchOption.AllDirectories).Single(); try { await foreach (var line in ProcessX.StartAsync( $"python3 generate.py -p {solver.Name}", workingDirectory: CheckerRoot).ConfigureAwait(false)) { Console.WriteLine(line); } } catch (ProcessErrorException e) when(e.ExitCode == 0) { } catch (ProcessErrorException e) { Console.WriteLine($"ProcessErrorException on {solver.Name}: {e.Message}"); throw; } catch (Exception e) { Console.WriteLine($"Exception on {solver.Name}: {e.Message}"); throw; } var inDir = Path.Combine(testDir, "in"); var outDir = Path.Combine(testDir, "out"); var gotDir = Path.Combine(testDir, "got"); Directory.CreateDirectory(gotDir); foreach (var inputFile in Directory.EnumerateFiles(inDir)) { var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(inputFile); using var rfs = new FileStream(inputFile, FileMode.Open, FileAccess.Read); using var wfs = new FileStream(Path.Combine(gotDir, fileNameWithoutExtension + ".got"), FileMode.Create, FileAccess.ReadWrite); var cr = new ConsoleReader(rfs, UTF8NoBom); var cw = new ConsoleWriter(wfs, UTF8NoBom); solver.Solve(cr, cw); cw.Flush(); try { var checkerPath = Path.Combine(testDir, "checker"); var command = string.Join(" ", checkerPath, Path.Combine(inDir, fileNameWithoutExtension + ".in"), Path.Combine(outDir, fileNameWithoutExtension + ".out"), Path.Combine(gotDir, fileNameWithoutExtension + ".got")); Console.WriteLine($"Run: {solver.Name} - {fileNameWithoutExtension}"); await foreach (var line in ProcessX.StartAsync(command, workingDirectory: CheckerRoot).ConfigureAwait(false)) { Console.WriteLine(line); } } catch (ProcessErrorException e) { Console.WriteLine($"ProcessErrorException on {solver.Name}-{fileNameWithoutExtension}: {e.Message}"); if (e.ExitCode != 0) { throw; } } catch (Exception e) { Console.WriteLine($"Exception on {solver.Name}-{fileNameWithoutExtension}: {e.Message}"); throw; } } }
/// <summary> /// 処理を開始します。 /// </summary> /// <param name="prevExitCode">前処理の終了コード</param> /// <returns>標準出力を返す非同期シーケンス</returns> public override ProcessAsyncEnumerable StartAsync(int prevExitCode) { AddPrevExitCode(StartInfo.EnvironmentVariables, prevExitCode); return(ProcessX.StartAsync(StartInfo)); }
/// <summary> /// 処理を開始します。 /// </summary> /// <param name="prevExitCode">前処理の終了コード</param> /// <returns>標準出力を返す非同期シーケンス</returns> public override ProcessAsyncEnumerable StartAsync(int prevExitCode) { IDictionary <string, string> variables = AddPrevExitCode(EnvironmentVariable, prevExitCode); return(ProcessX.StartAsync(CommandLine, WorkingDirectory, variables, Encoding)); }