private void InstallSharedRuntime(string script, string installDir, string architecture, string version, string channel) { var sharedRuntimePath = Path.Combine(installDir, "shared", "Microsoft.NETCore.App", version); if (!Directory.Exists(sharedRuntimePath)) { var args = ArgumentEscaper.EscapeAndConcatenate(new string[] { "-Channel", channel, "-Runtime", "dotnet", "-Version", version, "-Architecture", architecture, "-InstallDir", installDir }); var psi = new ProcessStartInfo { FileName = script, Arguments = args }; var process = Process.Start(psi); process.WaitForExit(); } else { Reporter.Output($".NET Core runtime {version} is already installed. Skipping installation."); } }
/// <summary> /// Runs the specified command-line app. /// </summary> /// <param name="path">The path of the command-line app.</param> /// <param name="settings">The settings to use when running the app.</param> public static int RunApp(string path, AppRunnerSettings settings) { if (path == null) throw new ArgumentNullException(nameof(path)); if (settings == null) throw new ArgumentNullException(nameof(settings)); var args = ArgumentEscaper.EscapeAndConcatenate((settings.Arguments ?? Enumerable.Empty<string>()).Where(x => x != null)); var exitCode = 0; try { Command.Run(name: path, args: args, workingDirectory: settings.WorkingDirectory, noEcho: settings.NoEcho); } catch (NonZeroExitCodeException exception) { exitCode = exception.ExitCode; } var isExitCodeSuccess = settings.IsExitCodeSuccess ?? (x => x == 0); if (!isExitCodeSuccess(exitCode)) throw new ApplicationException($"The process failed with exit code {exitCode}."); return exitCode; }
protected override int Execute() { var args = new List <string> { "msbuild", Path.Combine(Context.KoreBuildDir, "KoreBuild.proj"), "-t:InstallToolsets", }; if (_upgradeOpt.HasValue()) { args.Add("-p:UpgradeVSInstallation=true"); } if (_quietOpt.HasValue()) { args.Add("-p:QuietVSInstallation=true"); } if (_productOpt.HasValue()) { args.Add($"-p:VSProductVersionType={_productOpt.Value()}"); } if (Reporter.IsVerbose) { args.Add("-v:n"); } Reporter.Verbose($"Starting msbuild with arguments: {ArgumentEscaper.EscapeAndConcatenate(args)}"); return(RunDotnet(args, Context.RepoPath)); }
protected override string GenerateCommandLineCommands() { var cmd = 0; var arguments = string.Empty; if (Arguments != null) { arguments = ArgumentEscaper.EscapeAndConcatenate(Arguments.Select(i => i.ItemSpec)); cmd++; } if (!string.IsNullOrEmpty(Command)) { arguments = Command; cmd++; } if (cmd > 1) { Log.LogError("Arguments and Command cannot both be used."); return(null); } return(arguments); }
public string?ExecuteWithOutputCapture(string application, IEnumerable <string> arguments, string?workingFolder) { var stopwatch = System.Diagnostics.Stopwatch.StartNew(); try { using (var process = new Process()) { process.StartInfo = new ProcessStartInfo { FileName = application, Arguments = ArgumentEscaper.EscapeAndConcatenate(arguments), WorkingDirectory = workingFolder, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true }; process.Start(); process.EnableRaisingEvents = true; Task <string>?output = null; Task <string>?error = null; output = Task.Run(() => process.StandardOutput.ReadToEndAsync()); error = Task.Run(() => process.StandardError.ReadToEndAsync()); process.WaitForExit(); return((process.ExitCode == 0) ? output.GetAwaiter().GetResult() : null); } } finally { LogInfoPerformance($"ExecuteWithOutputCapture() '{Path.Combine(workingFolder ?? Directory.GetCurrentDirectory(), application)} {string.Join(" ", arguments)}'", stopwatch.Elapsed); } }
private string GetVisualStudioArgs(VsInstallation vs, string vsJsonFilePath) { var args = new List <string>(); if (vs != null) { if (UpgradeVSInstallation) { args.Add("upgrade"); } else { args.Add("modify"); } args.Add("--installPath"); args.Add($"{vs.InstallationPath}"); } args.Add("--in"); args.Add($"{vsJsonFilePath}"); args.Add("--wait"); args.Add("--norestart"); if (QuietVSInstallation) { args.Add("--quiet"); } return(ArgumentEscaper.EscapeAndConcatenate(args)); }
protected virtual Task <int> OnExecuteAsync(CommandLineApplication app) { var args = CreateArgs(); Console.WriteLine("Result = pvc " + ArgumentEscaper.EscapeAndConcatenate(args)); return(Task.FromResult(0)); }
protected string GetGitBranch(string workingDirectory, bool showWarningOnFailure = true) { // read the gitSha using 'git' directly var process = new Process { StartInfo = new ProcessStartInfo("git", ArgumentEscaper.EscapeAndConcatenate(new[] { "rev-parse", "--abbrev-ref", "HEAD" })) { RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, WorkingDirectory = workingDirectory } }; string gitBranch = null; try { process.Start(); gitBranch = process.StandardOutput.ReadToEnd().Trim(); process.WaitForExit(); if (process.ExitCode != 0) { if (showWarningOnFailure) { LogWarn($"unable to get git branch 'git rev-parse --abbrev-ref HEAD' failed with exit code = {process.ExitCode}"); } gitBranch = null; } } catch { if (showWarningOnFailure) { LogWarn("git is not installed; skipping git branch detection"); } } return(gitBranch); }
public void Start() { if (_process != null) { throw new InvalidOperationException("Already started"); } _process = new Process { EnableRaisingEvents = true, StartInfo = new ProcessStartInfo { UseShellExecute = false, FileName = _spec.Executable, WorkingDirectory = _spec.WorkingDirectory, Arguments = ArgumentEscaper.EscapeAndConcatenate(_spec.Arguments), RedirectStandardOutput = true, RedirectStandardError = true, Environment = { ["DOTNET_SKIP_FIRST_TIME_EXPERIENCE"] = "true" } } }; _process.OutputDataReceived += OnData; _process.ErrorDataReceived += OnData; _process.Exited += OnExit; _process.Start(); _process.BeginErrorReadLine(); _process.BeginOutputReadLine(); _logger.WriteLine($"{DateTime.Now}: process start: '{_process.StartInfo.FileName} {_process.StartInfo.Arguments}'"); }
} // = { "ls", "-a", "-l" } private void OnExecute() { var timer = Stopwatch.StartNew(); if (RemainingArguments != null && RemainingArguments.Length > 0) { var process = new Process { StartInfo = { FileName = RemainingArguments[0], Arguments = ArgumentEscaper.EscapeAndConcatenate(RemainingArguments.Skip(1)), } }; process.Start(); process.WaitForExit(); } timer.Stop(); if (Milliseconds) { Console.WriteLine($"Time = {timer.Elapsed.TotalMilliseconds} ms"); } else { Console.WriteLine($"Time = {timer.Elapsed.TotalSeconds}s"); } }
protected int RunDotnet(IEnumerable <string> arguments, string workingDir) { var args = ArgumentEscaper.EscapeAndConcatenate(arguments); // use the dotnet.exe file used to start this process var dotnet = DotNetMuxer.MuxerPath; // if it could not be found, fallback to detecting DOTNET_HOME or PATH dotnet = string.IsNullOrEmpty(dotnet) || !Path.IsPathRooted(dotnet) ? Context.GetDotNetExecutable() : dotnet; var psi = new ProcessStartInfo { FileName = dotnet, Arguments = args, WorkingDirectory = workingDir, }; Reporter.Verbose($"Executing '{psi.FileName} {psi.Arguments}'"); var process = Process.Start(psi); process.WaitForExit(); return(process.ExitCode); }
//--- Methods --- public bool Execute( string application, IEnumerable <string> arguments, string?workingFolder, bool showOutput, Func <string, string?>?processOutputLine = null ) => Execute(application, ArgumentEscaper.EscapeAndConcatenate(arguments), workingFolder, showOutput, processOutputLine);
private void InstallCLI(string script, string installDir, string architecture, string version) { var sdkPath = Path.Combine(installDir, "sdk", version, "dotnet.dll"); if (!File.Exists(sdkPath)) { Reporter.Verbose($"Installing dotnet {version} to {installDir}"); var args = ArgumentEscaper.EscapeAndConcatenate(new string[] { "-Version", version, "-Architecture", architecture, "-InstallDir", installDir, // workaround for https://github.com/dotnet/cli/issues/9143 // disable the CDN, which has non-deterministic behavior when multiple builds of the same SDK version exist "-NoCdn", }); var psi = new ProcessStartInfo { FileName = script, Arguments = args }; var process = Process.Start(psi); process.WaitForExit(); } else { Reporter.Output($".NET Core SDK {version} is already installed. Skipping installation."); } }
protected virtual int OnExecute(CommandLineApplication app) { var args = CreateArgs(); Console.WriteLine("Result = git " + ArgumentEscaper.EscapeAndConcatenate(args)); return(0); }
public async Task Invoke(PackageInProject currentPackage, NuGetVersion newVersion, PackageSource packageSource, NuGetSources allSources) { if (currentPackage == null) { throw new ArgumentNullException(nameof(currentPackage)); } if (packageSource == null) { throw new ArgumentNullException(nameof(packageSource)); } if (allSources == null) { throw new ArgumentNullException(nameof(allSources)); } var projectPath = currentPackage.Path.Info.DirectoryName; var projectFileNameCommandLine = ArgumentEscaper.EscapeAndConcatenate(new string[] { currentPackage.Path.Info.Name }); var sourceUrl = UriEscapedForArgument(packageSource.SourceUri); var sources = allSources.CommandLine("-s"); var restoreCommand = $"restore {projectFileNameCommandLine} {sources}"; await _externalProcess.Run(projectPath, "dotnet", restoreCommand, true); if (currentPackage.Path.PackageReferenceType == PackageReferenceType.ProjectFileOldStyle) { var removeCommand = $"remove {projectFileNameCommandLine} package {currentPackage.Id}"; await _externalProcess.Run(projectPath, "dotnet", removeCommand, true); } var addCommand = $"add {projectFileNameCommandLine} package {currentPackage.Id} -v {newVersion} -s {sourceUrl}"; await _externalProcess.Run(projectPath, "dotnet", addCommand, true); }
static string GetVerboseCommandLine(string[] commandLineArguments) { string[] verboseOption = new[] { BaseCommand.VerboseLongOption }; IEnumerable <string> arguments; // If there are additional arguments specified in the original command line (--) // we have to put the --verbose option before them (before the --). // Also, we have to check if the --verbose option is already set, but only before // the additional arguments (if they exist). int indexOfAdditionalArguments = Array.FindIndex(commandLineArguments, argument => argument == "--"); if (indexOfAdditionalArguments >= 0) { // We have additional arguments (--). arguments = commandLineArguments.Take(indexOfAdditionalArguments).Contains(BaseCommand.VerboseLongOption) ? commandLineArguments : commandLineArguments.Take(indexOfAdditionalArguments) .Concat(verboseOption) .Concat(commandLineArguments.Skip(indexOfAdditionalArguments)); } else { // We do not have additional arguments (--). arguments = commandLineArguments.Contains(BaseCommand.VerboseLongOption) ? commandLineArguments : commandLineArguments.Concat(verboseOption); } return(ArgumentEscaper.EscapeAndConcatenate(arguments)); }
public IEnumerable <PackageVerifierIssue> Validate(PackageAnalysisContext context) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { throw new InvalidOperationException("Package sign verification is only supported on Windows machines"); } var args = new[] { "verify", "-NonInteractive", "-All", context.PackageFileInfo.FullName, }; var psi = new ProcessStartInfo { FileName = _nuGetExePath, Arguments = ArgumentEscaper.EscapeAndConcatenate(args), RedirectStandardOutput = true, }; var process = Process.Start(psi); process.WaitForExit(60 * 1000); if (process.ExitCode != 0) { var issueText = process.StandardOutput.ReadToEnd(); yield return(PackageIssueFactory.PackageSignVerificationFailed(context.Metadata.Id, issueText)); } }
public string Resolve(string project, string configuration) { var finder = new MsBuildProjectFinder(_workingDirectory); var projectFile = finder.FindMsBuildProject(project); _reporter.Verbose(Resources.FormatMessage_Project_File_Path(projectFile)); configuration = !string.IsNullOrEmpty(configuration) ? configuration : DefaultConfig; var outputFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); try { var args = new[] { "msbuild", projectFile, "/nologo", "/t:_ExtractUserSecretsMetadata", // defined in SecretManager.targets "/p:_UserSecretsMetadataFile=" + outputFile, "/p:Configuration=" + configuration, "/p:CustomAfterMicrosoftCommonTargets=" + _targetsFile, "/p:CustomAfterMicrosoftCommonCrossTargetingTargets=" + _targetsFile, }; var psi = new ProcessStartInfo { FileName = DotNetMuxer.MuxerPathOrDefault(), Arguments = ArgumentEscaper.EscapeAndConcatenate(args), RedirectStandardOutput = true, RedirectStandardError = true }; #if DEBUG _reporter.Verbose($"Invoking '{psi.FileName} {psi.Arguments}'"); #endif var process = Process.Start(psi); process.WaitForExit(); if (process.ExitCode != 0) { _reporter.Verbose(process.StandardOutput.ReadToEnd()); _reporter.Verbose(process.StandardError.ReadToEnd()); throw new InvalidOperationException(Resources.FormatError_ProjectFailedToLoad(projectFile)); } var id = File.ReadAllText(outputFile)?.Trim(); if (string.IsNullOrEmpty(id)) { throw new InvalidOperationException(Resources.FormatError_ProjectMissingId(projectFile)); } return(id); } finally { TryDelete(outputFile); } }
protected override int Execute() { var installDir = Context.GetDotNetInstallDir(); Reporter.Verbose($"Installing tools to '{installDir}'"); if (DotNetInstallDir != null && DotNetInstallDir != installDir) { Reporter.Verbose($"installDir = {installDir}"); Reporter.Verbose($"DOTNET_INSTALL_DIR = {DotNetInstallDir}"); Reporter.Verbose("The environment variable DOTNET_INSTALL_DIR is deprecated. The recommended alternative is DOTNET_HOME."); } var dotnet = Context.GetDotNetExecutable(); var dotnetOnPath = GetCommandFromPath("dotnet"); // TODO: decide case sensitivity and handly symbolic links if (dotnetOnPath != null && (dotnetOnPath != dotnet)) { Reporter.Warn($"dotnet found on the system PATH is '{dotnetOnPath}' but KoreBuild will use '{dotnet}'"); } var pathPrefix = Directory.GetParent(dotnet); if (PathENV.StartsWith($"{pathPrefix}{Path.PathSeparator}", StringComparison.OrdinalIgnoreCase)) { Reporter.Output($"Adding {pathPrefix} to PATH"); Environment.SetEnvironmentVariable("PATH", $"{pathPrefix};{PathENV}"); } if (KoreBuildSkipRuntimeInstall == "1") { Reporter.Output("Skipping runtime installation because KOREBUILD_SKIP_RUNTIME_INSTALL = 1"); return(0); } var scriptExtension = Context.IsWindows() ? "ps1" : "sh"; var scriptPath = Path.Combine(Context.KoreBuildDir, "dotnet-install." + scriptExtension); if (!Context.IsWindows()) { var args = ArgumentEscaper.EscapeAndConcatenate(new string[] { "+x", scriptPath }); var psi = new ProcessStartInfo { FileName = "chmod", Arguments = args }; var process = Process.Start(psi); process.WaitForExit(); } var architecture = Context.GetArchitecture(); InstallCLI(scriptPath, installDir, architecture, Context.SDKVersion); return(0); }
private static string UriEscapedForArgument(Uri uri) { if (uri == null) { return(string.Empty); } return(ArgumentEscaper.EscapeAndConcatenate(new string[] { uri.ToString() })); }
private bool LinkExecutable(string name, ToolManifest.Command command) { // TODO keep track of created files for the uninstaller to also remove var targetPath = GetToolExecutable(name); if (File.Exists(targetPath)) { Log.Verbose($"File already exists: {targetPath}"); Log.Error($"A tool with a command named {name} has already been installed"); return(false); } Log.Verbose($"Creating tool executable in '{targetPath}'"); if (command.Portable) { var exe = Path.Combine(_assetInfo.Id.ToLowerInvariant(), _assetInfo.Version, command.Exe); Directory.CreateDirectory(_env.BinRoot); File.WriteAllText(targetPath, $@"#!/usr/bin/env bash set -e # resolve $SOURCE until the file is no longer a symlink SOURCE=""${{BASH_SOURCE[0]}}"" while [ -h ""$SOURCE"" ]; do DIR=""$( cd -P ""$( dirname ""$SOURCE"" )"" && pwd )"" SOURCE=""$(readlink ""$SOURCE"")"" [[ ""$SOURCE"" != /* ]] && SOURCE=""$DIR/$SOURCE"" done DIR=""$( cd -P ""$( dirname ""$SOURCE"" )"" && pwd )"" ""$DIR/../dotnet"" ""$DIR/../tools/{exe}"" ""$@"" "); var psi = new ProcessStartInfo { FileName = "chmod", Arguments = ArgumentEscaper.EscapeAndConcatenate(new[] { "+x", targetPath }), UseShellExecute = false, }; Log.Trace($"Executing {psi.FileName} {psi.Arguments}"); var chmod = Process.Start(psi); chmod.WaitForExit(); if (chmod.ExitCode != 0) { Log.Warn($"Failed to make '{targetPath}' executable. Please run 'chmod +x {targetPath}'"); } } else { throw new NotImplementedException("Non-portable tools not yet supported"); } return(true); }
public static void Main(string[] args) { SilkUtility.PrintLogo(); if (ArgumentEscaper.EscapeAndConcatenate(args).Length == 0) { SilkUtility.PrintHelp(); return; } CommandLineApplication.Execute <Silk>(args); }
static void Main(string[] args) { hFrida.PrintLogo(); if (ArgumentEscaper.EscapeAndConcatenate(args).Length == 0) { hFrida.PrintHelp(); return; } CommandLineApplication.Execute <Program>(args); }
private static void UpdateJumpList(IEnumerable <string> args) { var arguments = ArgumentEscaper.EscapeAndConcatenate(args); JumpList.AddToRecentCategory(new JumpTask { Title = arguments, Arguments = arguments }); }
public void Start() { if (_output != null) { _output.WriteLine($"Starting: {_process.StartInfo.FileName} {ArgumentEscaper.EscapeAndConcatenate(_process.StartInfo.ArgumentList)}"); } _process.Start(); _process.BeginOutputReadLine(); _process.BeginErrorReadLine(); _outputReceived.Wait(TimeSpan.FromSeconds(5)); }
public void BuildOfGlobalCliToolIncludesShims() { var app = _fixture.CreateTestApp("RepoWithGlobalTool"); var build = app.ExecuteBuild(_output, "/p:BuildNumber=0001"); Assert.Equal(0, build); var artifactsDir = Path.Combine(app.WorkingDirectory, "artifacts", "build"); var pkg = Path.Combine(artifactsDir, "GlobalConsoleTool.1.0.0.nupkg"); using (var reader = new PackageArchiveReader(pkg)) { var files = reader.GetFiles(); foreach (var file in files) { _output.WriteLine("pkg: " + file); } var winx86 = Assert.Single(files, f => f.StartsWith("tools/netcoreapp3.0/any/shims/win-x86/")); Assert.Equal("GlobalConsoleTool.exe", Path.GetFileName(winx86)); var winx64 = Assert.Single(files, f => f.StartsWith("tools/netcoreapp3.0/any/shims/win-x64/")); Assert.Equal("GlobalConsoleTool.exe", Path.GetFileName(winx64)); } var toolsDir = Path.Combine(app.WorkingDirectory, "artifacts", "tools"); var installPsi = new ProcessStartInfo { FileName = DotNetMuxer.MuxerPathOrDefault(), Arguments = ArgumentEscaper.EscapeAndConcatenate(new[] { "tool", "install", "--tool-path", toolsDir, "GlobalConsoleTool", "--add-source", artifactsDir }), }; var install = app.Run(_output, installPsi); Assert.Equal(0, install); var ext = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : string.Empty; var run = app.Run(_output, new ProcessStartInfo { FileName = Path.Combine(toolsDir, "GlobalConsoleTool" + ext), }); Assert.Equal(0, run); }
private static async Task <bool> IsInsideGitWorkTreeAsync(DirectoryInfo outputDirectory) { var gitDiff = new ProcessStartInfo("git") { Arguments = ArgumentEscaper.EscapeAndConcatenate(new[] { "rev-parse", "--is-inside-work-tree" }), WorkingDirectory = outputDirectory.FullName }; using var stdout = new StringWriter(); int exitCode = await gitDiff.GetExitCodeAsync(stdout, stdErr : TextWriter.Null); return(exitCode == 0); }
private void StartProcess(string directory) { const string exeName = "ワガママハイスペック.exe"; this._process = Process.Start( "wine", ArgumentEscaper.EscapeAndConcatenate(new[] { JoinPathInWindows(directory, exeName), "-forcelog=clear" })); var logFilePath = Path.Combine(ToUnixPath(directory), "savedata", "krkr.console.log"); // プロセス開始から 5 秒間はログファイルにアクセスさせない var allowedToAccessAt = DateTime.UtcNow.AddTicks(5 * TimeSpan.TicksPerSecond); var logObservable = Observable.Create <string>(async(observer, cancellationToken) => { var now = DateTime.UtcNow; if (now < allowedToAccessAt) { await Task.Delay(allowedToAccessAt - now, cancellationToken).ConfigureAwait(false); } using (var reader = new LogFileReader(logFilePath)) { reader.SeekToLastLine(); while (true) { while (reader.Read() is string log) { observer.OnNext(log); } await Task.Delay(500, cancellationToken).ConfigureAwait(false); } } }) .Merge( Observable.FromEventPattern( x => this._process.Exited += x, x => { if (this._process != null) { this._process.Exited -= x; } } ) .SelectMany(_ => s_processExitedObservable) ); this._logStream = Observable.Create <string>(observer => (this._process.HasExited ? s_processExitedObservable : logObservable).Subscribe(observer)); }
public Task <CommandResult> ExecuteAsync(bool throwOnFailure = false) { var tcs = new TaskCompletionSource <CommandResult>(); var exeName = Path.GetFileNameWithoutExtension(ExecutablePath); var formattedArgs = ArgumentEscaper.EscapeAndConcatenate(Arguments); var process = new Process() { StartInfo = new ProcessStartInfo() { FileName = ExecutablePath, Arguments = formattedArgs, WorkingDirectory = WorkingDirectory, RedirectStandardError = true, RedirectStandardOutput = true, } }; process.EnableRaisingEvents = true; var stdout = new StringBuilder(); var stderr = new StringBuilder(); process.ErrorDataReceived += (sender, a) => ProcessDataReceived(a, stderr, _standardErrorHandler); process.OutputDataReceived += (sender, a) => ProcessDataReceived(a, stdout, _standardOutputHandler); process.Exited += (sender, a) => { _logger.LogDebug("'{Command} {Arguments}' exited with code {ExitCode}", exeName, formattedArgs, process.ExitCode); if (process.ExitCode != 0 && throwOnFailure) { tcs.TrySetException(new CommandLineException($"Command '{exeName} {formattedArgs}' failed with exit code {process.ExitCode}!")); } else { tcs.TrySetResult(new CommandResult(process.ExitCode, stdout.ToString(), stderr.ToString())); } }; _logger.LogInformation("Running '{Command} {Arguments}'", exeName, formattedArgs); process.Start(); process.BeginErrorReadLine(); process.BeginOutputReadLine(); return(tcs.Task); void ProcessDataReceived(DataReceivedEventArgs args, StringBuilder buffer, Action <string> handler) { buffer.AppendLine(args.Data); handler?.Invoke(args.Data); _logger.LogDebug(args.Data); } }
public override bool Execute() { if (string.IsNullOrEmpty(RuleFile) || !File.Exists(RuleFile)) { Log.LogError($"RuleFile '{RuleFile}' does not exist"); return(false); } if (ArtifactDirectory == null || ArtifactDirectory.Length == 0) { Log.LogError($"At least one ArtifactDirectory must exist."); return(false); } var taskAssemblyFolder = Path.GetDirectoryName(GetType().GetTypeInfo().Assembly.Location); var toolPath = Path.Combine(taskAssemblyFolder, "..", "..", ConsoleAppExe); if (!File.Exists(toolPath)) { toolPath = Path.Combine(taskAssemblyFolder, ConsoleAppExe); } var dotnetMuxer = DotNetMuxer.MuxerPathOrDefault(); var arguments = new List <string> { toolPath, "--rule-file", RuleFile, }; foreach (var rule in ExcludedRules ?? Enumerable.Empty <string>()) { arguments.Add("--excluded-rule"); arguments.Add(rule); } arguments.AddRange(ArtifactDirectory); var psi = new ProcessStartInfo { FileName = dotnetMuxer, Arguments = ArgumentEscaper.EscapeAndConcatenate(arguments), }; Log.LogCommandLine($"Executing '{psi.FileName} {psi.Arguments}'"); var process = Process.Start(psi); process.WaitForExit(); return(process.ExitCode == 0); }