public void ExecuteFor(IEnumerable <RemoteRepo> repositories) { string Template(RemoteRepo r) { var args = _arguments; args = args .Replace("$repo-name", r.Name) .Replace("$proj-key", r.ProjectKey) .Replace("$http-url", r.HttpUrl) .Replace("$ssh-url", r.SshUrl) .Replace("$browser-url", r.Links.Self.FirstOrDefault()?.Href); return(args); } repositories.SafelyForEach( r => { var workingDirPath = _useCurrentDirectory ? Directory.GetCurrentDirectory() : Path.Join(Directory.GetCurrentDirectory(), r.Name); Cli.Wrap(_program) .WithArguments(Template(r)) .WithWorkingDirectory(workingDirPath) .WithStandardOutputPipe(PipeTarget.ToDelegate(_console.WriteLine)) .WithStandardErrorPipe(PipeTarget.ToDelegate(_console.Error.WriteLine)) .WithValidation(CommandResultValidation.None) .ExecuteAsync(_cancellationToken).Task.Wait(_cancellationToken); }, _cancellationToken, summarizeErrors: true); }
private static async Task Execute(string args, LogLevel logLevel, CancellationToken cancellationToken) { Logger.WriteLine($"{DotNetExe.FullPath} {args}", LogLevel.Normal); var stdErrBuffer = new StringBuilder(); var stdOut = PipeTarget.ToDelegate(l => Logger.WriteLine(l, logLevel)); var stdErr = PipeTarget.ToStringBuilder(stdErrBuffer); var result = await Cli.Wrap(DotNetExe.FullPath) .WithArguments(args) .WithStandardErrorPipe(stdOut) .WithStandardErrorPipe(stdErr) .WithValidation(CommandResultValidation.None) .ExecuteAsync(cancellationToken) .ConfigureAwait(false); var error = stdErrBuffer.ToString().Trim(); if (!string.IsNullOrEmpty(error)) { throw new Exception(error); } if (result.ExitCode > 0) { throw new Exception($"The dotnet tool unexpectidly exited without any error output with code: {result.ExitCode}"); } }
public async Task <string> ConvertKarToOgg(string inputFile) { var outputFilename = Path.Combine(_settings.SongCacheDir, Path.GetFileNameWithoutExtension(inputFile)) + _settings.ConvertedSongFormatExtension; if (File.Exists(outputFilename)) { return(outputFilename); } using var memStream = new MemoryStream(1024000); var guidStr = Guid.NewGuid().ToString("D"); var timidity = Cli.Wrap(_settings.TimidityPath) .WithArguments($"-Ow -W- --preserve-silence \"{inputFile}\" -o \"{guidStr}.wav\""); var lame = Cli.Wrap(_settings.LamePath) .WithArguments($"{guidStr}.wav \"{outputFilename}\"") .WithStandardErrorPipe(PipeTarget.ToDelegate(Log)); await timidity.ExecuteAsync(); await lame.ExecuteAsync(); File.Delete($"{guidStr}.wav"); return(outputFilename); }
static async Task Compile(string projectFile, string outputDir) { Regex errorRegex = new Regex(@"^[\w\d.\\-]+\(\d+,\d+\):"); string suffix = $" [{projectFile}]"; var command = Cli.Wrap(await Tester.FindMSBuild()) .WithArguments($"/nologo /v:minimal /restore /p:OutputPath=\"{outputDir}\" \"{projectFile}\"") .WithValidation(CommandResultValidation.None) .WithStandardOutputPipe(PipeTarget.ToDelegate(PrintLine)); Console.WriteLine($"\"{command.TargetFilePath}\" {command.Arguments}"); var result = await command.ExecuteAsync().ConfigureAwait(false); if (result.ExitCode != 0) { throw new CompilationFailedException($"Compilation of {Path.GetFileName(projectFile)} failed"); } void PrintLine(string line) { if (line.EndsWith(suffix, StringComparison.OrdinalIgnoreCase)) { line = line.Substring(0, line.Length - suffix.Length); } Match m = errorRegex.Match(line); if (m.Success) { // Make path absolute so that it gets hyperlinked line = Path.GetDirectoryName(projectFile) + Path.DirectorySeparatorChar + line; } Console.WriteLine(line); } }
private async Task <HashSet <string> > ListFileAsync() { var set = new HashSet <string>(_stringComparer); var result = await Cli.Wrap("git") .WithArguments("ls-files") .WithWorkingDirectory(_workingDirectory) .WithValidation(CommandResultValidation.None) .WithStandardOutputPipe(PipeTarget.ToDelegate(line => { line = _fileSystem.Path.Normalize(line); if (line.Contains(Bin) || line.Contains(Obj)) { set.Add(Path.Combine(_workingDirectory, line)); } })) .ExecuteAsync(); if (result.ExitCode != 0) { set.Clear(); } return(set); }
internal static async Task ExecuteInternal(Action <ArgumentsBuilder> configure, CancellationToken cancellationToken) { ThrowIfNull(ToolPath, nameof(SdkManager)); var stdErrBuffer = new StringBuilder(); await Cli.Wrap(ToolPath) .WithArguments(configure) .WithValidation(CommandResultValidation.None) .WithStandardErrorPipe(PipeTarget.ToStringBuilder(stdErrBuffer)) .WithStandardOutputPipe(PipeTarget.ToDelegate(l => Logger.WriteLine(l, LogLevel.Detailed))) .WithStandardInputPipe(PipeSource.FromString("y")) .ExecuteAsync(cancellationToken); var stdErr = stdErrBuffer.ToString().Trim(); if (!string.IsNullOrEmpty(stdErr)) { if (stdErr.Split('\n').Select(x => x.Trim()).All(x => x.StartsWith("Warning:"))) { Logger.WriteWarning(stdErr); } else { throw new Exception(stdErr); } } }
internal static async Task <string> ExecuteInternal(Action <ArgumentsBuilder> configure, CancellationToken cancellationToken) { var toolPath = ToolPath; ThrowIfNull(toolPath, nameof(Emulator)); var builder = new ArgumentsBuilder(); configure(builder); var args = builder.Build(); Logger.WriteLine($"{toolPath} {args}", LogLevel.Normal); var stdErrBuffer = new StringBuilder(); var stdOutBuffer = new StringBuilder(); var stdOut = PipeTarget.Merge(PipeTarget.ToStringBuilder(stdOutBuffer), PipeTarget.ToDelegate(l => Logger.WriteLine(l, LogLevel.Verbose))); await Cli.Wrap(toolPath) .WithArguments(args) .WithStandardErrorPipe(PipeTarget.ToStringBuilder(stdErrBuffer)) .WithStandardOutputPipe(stdOut) .ExecuteAsync(cancellationToken); var stdErr = stdErrBuffer.ToString().Trim(); if (!string.IsNullOrEmpty(stdErr)) { throw new Exception(stdErr); } return(stdOutBuffer.ToString().Trim()); }
public static async Task <bool> InstallPackage(string packageName, CancellationToken cancellationToken) { Console.WriteLine($"npm install -g {packageName}"); var isMac = EnvironmentHelper.IsRunningOnMac; var errorLines = new List <string>(); var stdOut = PipeTarget.ToDelegate(l => Console.WriteLine(l)); var stdErr = PipeTarget.ToDelegate(l => { if (string.IsNullOrEmpty(l) || (isMac && l.Contains("did not detect a Windows system"))) { return; } errorLines.Add(l); }); await Cli.Wrap("npm") .WithArguments($"install -g {packageName}") .WithValidation(CommandResultValidation.None) .WithStandardOutputPipe(stdOut) .WithStandardErrorPipe(stdErr) .ExecuteAsync(cancellationToken); if (cancellationToken.IsCancellationRequested) { return(false); } if (errorLines.Any()) { return(true); } throw new Exception(string.Join(Environment.NewLine, errorLines)); }
public static async Task <bool> InstallPackage(string packageName, CancellationToken cancellationToken) { Console.WriteLine($"npm install -g {packageName}"); var stdErrBuffer = new StringBuilder(); var stdOut = PipeTarget.ToDelegate(l => Console.WriteLine(l)); await Cli.Wrap("npm") .WithArguments($"install -g {packageName}") .WithStandardOutputPipe(stdOut) .WithStandardErrorPipe(PipeTarget.ToStringBuilder(stdErrBuffer)) .ExecuteAsync(cancellationToken); if (cancellationToken.IsCancellationRequested) { return(false); } var errorOutput = stdErrBuffer.ToString().Trim(); if (string.IsNullOrEmpty(errorOutput)) { return(true); } throw new Exception(errorOutput); }
public async Task DeleteAsync() { await BashCommand($@"kind delete cluster --name ""{this.name}""") .WithStandardOutputPipe(PipeTarget.ToDelegate(line => Console.WriteLine(line))) .WithStandardErrorPipe(PipeTarget.ToDelegate(line => Console.WriteLine(line))) .ExecuteAsync(); }
internal static async Task ExecuteInternal(Action <ArgumentsBuilder> configure, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return; } var builder = new ArgumentsBuilder(); configure(builder); var args = builder.Build(); Logger.WriteLine($"{ToolPath} {args}", LogLevel.Normal); var stdOutBuffer = new StringBuilder(); var stdOut = PipeTarget.Merge(PipeTarget.ToStringBuilder(stdOutBuffer), PipeTarget.ToDelegate(l => Logger.WriteLine(l, LogLevel.Verbose))); var stdError = PipeTarget.ToDelegate(l => { if (string.IsNullOrEmpty(l)) { return; } // Suppress errors Logger.WriteWarning(l); }); var result = await Cli.Wrap(ToolPath) .WithArguments(args) .WithValidation(CommandResultValidation.None) .WithStandardErrorPipe(stdError) .WithStandardOutputPipe(stdOut) .ExecuteAsync(cancellationToken); }
public Task ProcessAsync(IReadOnlyList <string> inputFilePaths, string outputFilePath, string format, bool transcode, IEnumerable <string> additionalArgs = null, IProgress <double> progress = null, CancellationToken cancellationToken = default(CancellationToken)) { var args = new List <string>(); // Set input files foreach (var inputFilePath in inputFilePaths) { args.Add($"-i \"{inputFilePath}\""); } // Set output format args.Add($"-f {format}"); // Skip transcoding if it's not required if (!transcode) { args.Add("-c copy"); } // Optimize mp4 transcoding if (transcode && string.Equals(format, "mp4", StringComparison.OrdinalIgnoreCase)) { args.Add("-preset ultrafast"); } // Set max threads args.Add($"-threads {Environment.ProcessorCount}"); // Disable stdin so that the process will not hang waiting for user input args.Add("-nostdin"); // Trim streams to shortest args.Add("-shortest"); if (additionalArgs != null) { args.AddRange(additionalArgs); } // Overwrite files args.Add("-y"); // Set output file args.Add($"\"{outputFilePath}\""); // Set up progress router var progressRouter = new FfmpegProgressRouter(progress); // Run CLI return(Cli.Wrap(_ffmpegFilePath) .WithWorkingDirectory(Directory.GetCurrentDirectory()) .WithArguments(args.JoinToString(" ")) .WithStandardErrorPipe(PipeTarget.ToDelegate((line) => progressRouter.ProcessLine(line))) // handle stderr to parse and route progress .WithValidation(CommandResultValidation.None) // disable stderr validation because ffmpeg writes progress there .ExecuteAsync(cancellationToken)); }
public static Task <IDisposable> Run(string baseWorkingDirectory) { var completed = false; var tcs = new TaskCompletionSource <IDisposable>(); var cancellationSource = new CancellationTokenSource(); var logDirectory = Path.Combine(baseWorkingDirectory, "logs"); if (!Directory.Exists(logDirectory)) { Directory.CreateDirectory(logDirectory); } void HandleConsoleLine(string line) { if (line.Contains("listener started on 0.0.0.0:4723")) { Logger.WriteLine(line, LogLevel.Minimal, defaultLog); if (!completed) { tcs.SetResult(new AppiumTask(cancellationSource)); } completed = true; } else if (line.Contains("make sure there is no other instance of this server running already") || line.Contains("listen EADDRINUSE: address already in use 0.0.0.0:4723")) { Logger.WriteWarning(line, defaultLog); if (!completed) { tcs.SetResult(new AppiumTask(cancellationSource)); } completed = true; } else { Logger.WriteLine(line, LogLevel.Verbose, defaultLog); } } var stdOut = PipeTarget.ToDelegate(HandleConsoleLine); var stdErr = PipeTarget.Merge( PipeTarget.ToFile(Path.Combine(logDirectory, "appium-error.log")), PipeTarget.ToDelegate(HandleConsoleLine)); Logger.WriteLine("Starting Appium...", LogLevel.Minimal); var toolPath = EnvironmentHelper.GetToolPath("appium"); var cmd = Cli.Wrap(toolPath) .WithStandardOutputPipe(stdOut) .WithStandardErrorPipe(stdErr) .WithValidation(CommandResultValidation.None) .ExecuteAsync(cancellationSource.Token); return(tcs.Task); }
public async Task <IKubernetes> GetClientAsync() { string path = string.Empty; await BashCommand($@"kind get kubeconfig-path --name ""{this.name}""") .WithStandardOutputPipe(PipeTarget.ToDelegate(line => path = line)) .WithStandardErrorPipe(PipeTarget.ToDelegate(line => Console.WriteLine(line))) .ExecuteAsync(); return(new Kubernetes(KubernetesClientConfiguration.BuildConfigFromConfigFile(path))); }
public static Command AddTestOutputPipe(this Command command, ITestOutputHelper testOutputHelper) { return(command .WithStandardOutputPipe( PipeTarget.Merge( command.StandardOutputPipe, PipeTarget.ToDelegate(testOutputHelper.WriteLine))) .WithStandardErrorPipe( PipeTarget.Merge( command.StandardErrorPipe, PipeTarget.ToDelegate(testOutputHelper.WriteLine)))); }
/// <summary> /// Executes the command as an observable event stream. /// </summary> public static IObservable <CommandEvent> Observe( this Command command, Encoding standardOutputEncoding, Encoding standardErrorEncoding, CancellationToken cancellationToken = default) => Observable.Create <CommandEvent>(observer => { var stdOutPipe = PipeTarget.Merge( command.StandardOutputPipe, PipeTarget.ToDelegate( s => observer.OnNext(new StandardOutputCommandEvent(s)), standardOutputEncoding) ); var stdErrPipe = PipeTarget.Merge( command.StandardErrorPipe, PipeTarget.ToDelegate( s => observer.OnNext(new StandardErrorCommandEvent(s)), standardErrorEncoding) ); var commandPiped = command .WithStandardOutputPipe(stdOutPipe) .WithStandardErrorPipe(stdErrPipe); var commandTask = commandPiped.ExecuteAsync(cancellationToken); observer.OnNext(new StartedCommandEvent(commandTask.ProcessId)); // Don't pass cancellation token to continuation because we need it to always trigger // regardless of how the task completed. _ = commandTask .Task .ContinueWith(t => { // Canceled tasks don't have exception if (t.IsCanceled) { observer.OnError(new OperationCanceledException("Command execution has been canceled.")); } else if (t.Exception == null) { observer.OnNext(new ExitedCommandEvent(t.Result.ExitCode)); observer.OnCompleted(); } else { observer.OnError(t.Exception); } }, TaskContinuationOptions.None); return(Disposable.Null); });
private static async Task <string> ExecuteInternal(Action <ArgumentsBuilder> configure, CancellationToken cancellationToken, PipeSource stdInput = null) { var toolPath = ToolPath; ThrowIfNull(toolPath, nameof(AvdManager)); var builder = new ArgumentsBuilder(); configure(builder); var args = builder.Build(); Logger.WriteLine($"{toolPath} {args}", LogLevel.Normal); var errorBuffer = new List <string>(); var stdOutBuffer = new StringBuilder(); var stdOut = PipeTarget.Merge(PipeTarget.ToStringBuilder(stdOutBuffer), PipeTarget.ToDelegate(l => Logger.WriteLine(l, LogLevel.Verbose))); var stdErr = PipeTarget.ToDelegate(l => { if (string.IsNullOrEmpty(l)) { return; } else if (l.Contains("Warning: ")) { Logger.WriteWarning(l); } else { errorBuffer.Add(l); } }); var cmd = Cli.Wrap(toolPath) .WithArguments(args) .WithValidation(CommandResultValidation.None) .WithStandardErrorPipe(stdErr) .WithStandardOutputPipe(stdOut); if (stdInput != null) { cmd = cmd.WithStandardInputPipe(stdInput); } await cmd.ExecuteAsync(cancellationToken); if (errorBuffer.Any()) { throw new Exception(string.Join(Environment.NewLine, errorBuffer)); } return(stdOutBuffer.ToString().Trim()); }
public static async Task Build(string projectPath, string baseWorkingDirectory, IDictionary <string, string> props, CancellationToken cancellationToken, string target = null) { if (string.IsNullOrEmpty(ToolPath)) { throw new Exception("No installation of Visual Studio could be found. Could not locate msbuild."); } if (!props.ContainsKey("Configuration")) { props.Add("Configuration", "Release"); } if (!props.ContainsKey("Verbosity")) { props.Add("Verbosity", "Minimal"); } var stdErrBuffer = new StringBuilder(); var result = await Cli.Wrap(ToolPath) .WithArguments(b => { b.Add(projectPath); b.Add("/r"); if (!string.IsNullOrEmpty(target)) { b.Add($"/t:{target}"); } foreach ((var key, var value) in props) { b.Add($"/p:{key}={value}"); } var logoutput = Path.Combine(baseWorkingDirectory, "logs", $"{Path.GetFileNameWithoutExtension(projectPath)}.binlog"); b.Add($"/bl:{logoutput}"); }) .WithStandardOutputPipe(PipeTarget.ToDelegate(l => Logger.WriteLine(l, LogLevel.Normal))) .WithStandardErrorPipe(PipeTarget.ToStringBuilder(stdErrBuffer)) .WithValidation(CommandResultValidation.None) .ExecuteAsync(cancellationToken) .ConfigureAwait(false); var error = stdErrBuffer.ToString().Trim(); if (!string.IsNullOrEmpty(error)) { throw new Exception(error); } }
private async Task <Either <BaseError, PtsAndDuration> > Handle( RequestParameters parameters, CancellationToken cancellationToken) { Option <FileInfo> maybeLastSegment = GetLastSegment(parameters.ChannelNumber); foreach (FileInfo segment in maybeLastSegment) { string[] argumentList = { "-v", "0", "-show_entries", "packet=pts,duration", "-of", "compact=p=0:nk=1", // "-read_intervals", "999999", // read_intervals causes inconsistent behavior on windows segment.FullName }; string lastLine = string.Empty; Action <string> replaceLine = s => { if (!string.IsNullOrWhiteSpace(s)) { lastLine = s.Trim(); } }; CommandResult probe = await Cli.Wrap(parameters.FFprobePath) .WithArguments(argumentList) .WithValidation(CommandResultValidation.None) .WithStandardOutputPipe(PipeTarget.ToDelegate(replaceLine)) .ExecuteAsync(cancellationToken); if (probe.ExitCode != 0) { return(BaseError.New($"FFprobe at {parameters.FFprobePath} exited with code {probe.ExitCode}")); } try { return(PtsAndDuration.From(lastLine)); } catch (Exception ex) { _client.Notify(ex); await SaveTroubleshootingData(parameters.ChannelNumber, lastLine); } } return(BaseError.New($"Failed to determine last pts duration for channel {parameters.ChannelNumber}")); }
private async Task <CommandResult> RunAsyncInner( IEnumerable <string> args, string workingDir, IDictionary <string, string?> additionalEnv, Action <string>?onStandardOutput = null, Action <string>?onStandardError = null, EventLogFile?eventLogFile = null, CancellationToken cancellationToken = default) { var stdOutBuffer = new StringBuilder(); var stdOutPipe = PipeTarget.ToStringBuilder(stdOutBuffer); if (onStandardOutput != null) { stdOutPipe = PipeTarget.Merge(stdOutPipe, PipeTarget.ToDelegate(onStandardOutput)); } var stdErrBuffer = new StringBuilder(); var stdErrPipe = PipeTarget.ToStringBuilder(stdErrBuffer); if (onStandardError != null) { stdErrPipe = PipeTarget.Merge(stdErrPipe, PipeTarget.ToDelegate(onStandardError)); } var pulumiCmd = Cli.Wrap("pulumi") .WithArguments(PulumiArgs(args, eventLogFile), escape: true) .WithWorkingDirectory(workingDir) .WithEnvironmentVariables(PulumiEnvironment(additionalEnv, debugCommands: eventLogFile != null)) .WithStandardOutputPipe(stdOutPipe) .WithStandardErrorPipe(stdErrPipe) .WithValidation(CommandResultValidation.None); // we check non-0 exit code ourselves var pulumiCmdResult = await pulumiCmd.ExecuteAsync(cancellationToken); var result = new CommandResult( pulumiCmdResult.ExitCode, standardOutput: stdOutBuffer.ToString(), standardError: stdErrBuffer.ToString()); if (pulumiCmdResult.ExitCode != 0) { throw CommandException.CreateFromResult(result); } else { return(result); } }
static async Task RunTest(string outputDir, string fileToTest) { var command = Cli.Wrap(nunit) .WithWorkingDirectory(outputDir) .WithArguments($"\"{fileToTest}\"") .WithValidation(CommandResultValidation.None) .WithStandardOutputPipe(PipeTarget.ToDelegate(Console.WriteLine)); Console.WriteLine($"\"{command.TargetFilePath}\" {command.Arguments}"); var result = await command.ExecuteAsync().ConfigureAwait(false); if (result.ExitCode != 0) { throw new TestRunFailedException($"Test execution of {Path.GetFileName(fileToTest)} failed"); } }
private async Task <TestStep> ExecuteStep(string executable, string arguments, string workingPath = null) { Logger.Info($"Executing: {executable} {arguments}"); var result = await Cli.Wrap(executable) .WithWorkingDirectory(workingPath ?? WorkingPath) .WithArguments(arguments) .WithStandardOutputPipe(PipeTarget.ToDelegate(text => Logger.Info($"> {text}"))) .WithStandardErrorPipe(PipeTarget.ToDelegate(text => Logger.Error($"> {text}"))) .ExecuteAsync(); Logger.Info($"Command run time: {result.RunTime.ToString()}"); return(new TestStep { Name = $"{executable} {arguments}", Duration = result.RunTime }); }
private async Task RunSetUidAsync(string newUID) { var arguments = ""; if (ckFormatTag.IsChecked.Value) { arguments += "-f "; } arguments += newUID; Main.LogAppend($"nfc-mfsetuid {arguments}"); var cmd = Cli.Wrap(@"nfctools\\nfc-mfsetuid.exe").WithArguments(arguments) .WithStandardOutputPipe(PipeTarget.ToDelegate(Main.LogAppend)) .WithStandardErrorPipe(PipeTarget.ToDelegate(Main.ErrorAppend)); var result = await cmd.ExecuteAsync(Main.ProcessCTS.Token); }
/// <summary> /// Executes the command as an asynchronous (pull-based) event stream. /// Use <code>await foreach</code> to listen to the stream and handle command events. /// </summary> public static async IAsyncEnumerable <CommandEvent> ListenAsync( this Command command, Encoding standardOutputEncoding, Encoding standardErrorEncoding, [EnumeratorCancellation] CancellationToken cancellationToken = default) { using var channel = new Channel <CommandEvent>(); var stdOutPipe = PipeTarget.Merge( command.StandardOutputPipe, PipeTarget.ToDelegate( s => channel.PublishAsync(new StandardOutputCommandEvent(s), cancellationToken), standardOutputEncoding) ); var stdErrPipe = PipeTarget.Merge( command.StandardErrorPipe, PipeTarget.ToDelegate( s => channel.PublishAsync(new StandardErrorCommandEvent(s), cancellationToken), standardErrorEncoding) ); var commandPiped = command .WithStandardOutputPipe(stdOutPipe) .WithStandardErrorPipe(stdErrPipe); var commandTask = commandPiped.ExecuteAsync(cancellationToken); yield return(new StartedCommandEvent(commandTask.ProcessId)); // Don't pass cancellation token to continuation because we need it to always trigger // regardless of how the task completed. _ = commandTask .Task .ContinueWith(_ => channel.Close(), TaskContinuationOptions.None); await foreach (var cmdEvent in channel.ReceiveAsync(cancellationToken).ConfigureAwait(false)) { yield return(cmdEvent); } var exitCode = await commandTask.Select(r => r.ExitCode).ConfigureAwait(false); yield return(new ExitedCommandEvent(exitCode)); }
private static async Task ExecuteInternal(Action <ArgumentsBuilder> configure, CancellationToken cancellationToken) { ThrowIfNull(ToolPath, nameof(SdkManager)); var stdErrBuffer = new StringBuilder(); await Cli.Wrap(ToolPath) .WithArguments(configure) .WithStandardErrorPipe(PipeTarget.ToStringBuilder(stdErrBuffer)) .WithStandardOutputPipe(PipeTarget.ToDelegate(l => Logger.WriteLine(l, LogLevel.Detailed))) .WithStandardInputPipe(PipeSource.FromString("y")) .ExecuteAsync(cancellationToken); var stdErr = stdErrBuffer.ToString().Trim(); if (!string.IsNullOrEmpty(stdErr)) { throw new Exception(stdErr); } }
public async Task RunNfcMfclassicAsync(TagAction act, bool bWriteBlock0, bool useKeyA, bool haltOnError, TagType tagType) { try { StopScanTag(); ValidateActions(false); ShowAbortButton(); var sourceDump = t.TMPFILESOURCEPATH_MFD; //"dumps\\" + t.TMPFILESOURCE_MFD; var targetDump = "dumps\\" + t.TMPFILE_TARGETMFD; char writeMode = bWriteBlock0 == true ? 'W' : 'w'; char useKey = useKeyA == true ? 'A' : 'B'; char cHaltOnError = haltOnError == true ? useKey = char.ToLower(useKey) : char.ToUpper(useKey); if (tagType == TagType.UnlockedGen1) { writeMode = 'W'; } else if (tagType == TagType.DirectCUIDgen2) { writeMode = 'C'; } ProcessCTS = new CancellationTokenSource(); var arguments = $"{writeMode} {cHaltOnError} u \"{sourceDump}\" \"{targetDump}\""; LogAppend($"nfc-mfclassic {arguments}"); var cmd = Cli.Wrap("nfctools\\nfc-mfclassic.exe").WithArguments(arguments).WithValidation(CommandResultValidation.None) .WithStandardOutputPipe(PipeTarget.ToDelegate(LogAppend)) .WithStandardErrorPipe(PipeTarget.ToDelegate(ErrorAppend)); var result = await cmd.ExecuteAsync(ProcessCTS.Token); } catch (OperationCanceledException) { } catch (Exception) { throw; } finally { //ProcessCTS.Dispose(); ValidateActions(true); ShowAbortButton(false); } }
internal static async Task <string> ExecuteInternal(Action <ArgumentsBuilder> configure, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(null); } var toolPath = ToolPath; var builder = new ArgumentsBuilder(); configure(builder); var args = builder.Build(); Logger.WriteLine($"{toolPath} {args}", LogLevel.Normal); var stdErrBuffer = new StringBuilder(); var stdOutBuffer = new StringBuilder(); var stdOut = PipeTarget.Merge(PipeTarget.ToStringBuilder(stdOutBuffer), PipeTarget.ToDelegate(l => Logger.WriteLine(l, LogLevel.Verbose))); var result = await Cli.Wrap(toolPath) .WithArguments(args) .WithValidation(CommandResultValidation.None) .WithStandardErrorPipe(PipeTarget.ToStringBuilder(stdErrBuffer)) .WithStandardOutputPipe(stdOut) .ExecuteAsync(cancellationToken); var stdErr = stdErrBuffer.ToString().Trim(); if (!string.IsNullOrEmpty(stdErr)) { if (stdErr.Split('\n').Select(x => x.Trim()).All(x => x.StartsWith("Warning:", StringComparison.InvariantCultureIgnoreCase))) { Logger.WriteWarning(stdErr); } else { throw new Exception(stdErr); } } return(stdOutBuffer.ToString().Trim()); }
public async Task <IActionResult> Go( IFormFile image, [FromServices] IWebHostEnvironment env) { if (image == null) { return(BadRequest()); } using var stream = image.OpenReadStream(); var imageExt = System.IO.Path.GetExtension(image.FileName).ToUpper(); if (imageExt != ".JPG" || imageExt != ".JPEG") { } string filename = Guid.NewGuid() + System.IO.Path.GetExtension(image.FileName); using (var fileStream = System.IO.File.Create(filename)) { await stream.CopyToAsync(fileStream); } var tag = "*[ULTALPR_SDK INFO]: result: "; string result = null; var temp = ""; Action <string> cliHandle = line => { temp += "\r\n" + line; if (line?.StartsWith(tag) != true) { return; } line = line.Replace(tag, string.Empty); result = line; }; var licenseTokenFile = System.IO.Path.Combine(env.ContentRootPath, "license.key"); var licenseTokenFileExists = System.IO.File.Exists(licenseTokenFile); var cmd = Cli.Wrap(System.IO.Path.Combine(env.ContentRootPath, @"Runtime/recognizer")) .WithArguments(args => { var argBuilder = args .Add(@"--image " + System.IO.Path.Combine(env.ContentRootPath, filename), false) .Add(@"--assets " + System.IO.Path.Combine(env.ContentRootPath, @"Models"), false); if (licenseTokenFileExists) { argBuilder.Add(@"--tokenfile " + licenseTokenFile, false); } }) .WithWorkingDirectory(env.ContentRootPath) .WithStandardOutputPipe(PipeTarget.ToDelegate(cliHandle)) .WithStandardErrorPipe(PipeTarget.ToDelegate(cliHandle)) .WithValidation(CommandResultValidation.None); await cmd.ExecuteAsync(); System.IO.File.Delete(filename); if (string.IsNullOrWhiteSpace((result))) { return(NotFound()); } return(Content(Convert(result), "application/json")); }
private async Task _PlayAsync(string deviceUniqueId, CancellationTokenSource cancellationTokenSource, int attempts = 0) { Device device = await FindDeviceAsync(deviceUniqueId); if (device == null) { await Task.FromException(new NullReferenceException("Couldn't get device with uniqueId " + deviceUniqueId)).ConfigureAwait(false); } else { int deviceInstanceId = SnapSettings.DetermineInstanceId(deviceUniqueId, device.Index); DeviceSettings deviceSettings = SnapSettings.GetDeviceSettings(deviceUniqueId); if (deviceInstanceId != -1) { // update device's last seen: deviceSettings.LastSeen = DateTime.Now; SnapSettings.SaveDeviceSettings(deviceUniqueId, deviceSettings); StringBuilder stdError = new StringBuilder(); string lastLine = ""; Action <string> stdOut = (line) => { lastLine = line; // we only care about the last line from the output - in case there's an error (snapclient should probably be sending these to stderr though) }; string resampleArg = ""; string hostIdArg = ""; CommandTask <CommandResult> task = null; if (deviceSettings.UseSnapClientNet == false) { // Launch native client: if (string.IsNullOrEmpty(deviceSettings.ResampleFormat) == false) { resampleArg = $"--sampleformat {deviceSettings.ResampleFormat}:0"; } if (string.IsNullOrWhiteSpace(deviceSettings.HostId) == false) { hostIdArg = $"--hostID \"{deviceSettings.HostId}\""; } string command = $"-h {SnapSettings.Server} -p {SnapSettings.PlayerPort} -s {device.Index} -i {deviceInstanceId} --sharingmode={deviceSettings.ShareMode.ToString().ToLower()} {resampleArg} {hostIdArg}"; Logger.Debug("Snapclient command: {0}", command); task = Cli.Wrap(_SnapClient()) .WithArguments(command) .WithStandardOutputPipe(PipeTarget.ToDelegate(stdOut)) .ExecuteAsync(cancellationTokenSource.Token); } else { // launch experimental .NET port of snapclient: string command = $"-h {SnapSettings.Server} -p {SnapSettings.PlayerPort} -s {device.Index} -i {deviceInstanceId}"; Logger.Debug("SnapClient.Net command: {0}", command); task = Cli.Wrap(_SnapClientDotNet()) .WithArguments(command) .WithStandardOutputPipe(PipeTarget.ToDelegate(stdOut)) .ExecuteAsync(cancellationTokenSource.Token); } Logger.Debug("Snapclient PID: {0}", task.ProcessId); ChildProcessTracker.AddProcess(Process.GetProcessById(task.ProcessId)); // this utility helps us make sure the player process doesn't keep going if our process is killed / crashes try { await task; } catch (CliWrap.Exceptions.CommandExecutionException e) { OnSnapClientErrored?.Invoke(); // add type to ShowNotification (level?), show notification with type and print log at type level Snapcast.Instance.ShowNotification("Snapclient error", _BuildErrorMessage(device, lastLine)); // todo: parse WASAPI error code here and provide human friendly output Logger.Error("Snapclient exited with non-zero exit code. Exception:"); Logger.Error(e.Message); DevicePlayStateChanged?.Invoke(deviceUniqueId, EState.Stopped); m_ActivePlayers.Remove(deviceUniqueId); // settings might have changed while we were playing - refetch them DeviceSettings nDeviceSettings = SnapSettings.GetDeviceSettings(deviceUniqueId); if (nDeviceSettings.AutoRestartOnFailure == true && (attempts <= nDeviceSettings.RestartAttempts || nDeviceSettings.RestartAttempts == 0)) { m_ActivePlayers.Add(deviceUniqueId, cancellationTokenSource); DevicePlayStateChanged?.Invoke(deviceUniqueId, EState.Playing); await _PlayAsync(deviceUniqueId, cancellationTokenSource, attempts + 1).ConfigureAwait(false); } } } } DevicePlayStateChanged?.Invoke(deviceUniqueId, EState.Stopped); m_ActivePlayers.Remove(deviceUniqueId); }