public static async Task <GetResponse <string> > GetExecutablePath(string projectPath, CancellationToken cancel, Action <string>?log) { // Hacky way to locate executable, but running a build and extracting the path its logs spit out // Tried using Buildalyzer, but it has a lot of bad side effects like clearing build outputs when // locating information like this. using var proc = ProcessWrapper.Create( new System.Diagnostics.ProcessStartInfo("dotnet", GetBuildString($"\"{projectPath}\"")), cancel: cancel); log?.Invoke($"({proc.StartInfo.WorkingDirectory}): {proc.StartInfo.FileName} {proc.StartInfo.Arguments}"); List <string> outs = new(); using var outp = proc.Output.Subscribe(o => outs.Add(o)); List <string> errs = new(); using var errp = proc.Error.Subscribe(o => errs.Add(o)); var result = await proc.Run(); if (errs.Count > 0) { throw new ArgumentException($"{string.Join("\n", errs)}"); } if (!TryGetExecutablePathFromOutput(outs, out var path)) { log?.Invoke($"Could not locate target executable: {string.Join(Environment.NewLine, outs)}"); return(GetResponse <string> .Fail("Could not locate target executable.")); } return(GetResponse <string> .Succeed(path)); }
public Task RunSteamCmdUpdaterAsync(CancellationToken cancellationToken) { if (!File.Exists(_settings.SteamCmdPath)) { throw new NotSupportedException( $"There is no executable for steamcmd on given path {_settings.SteamCmdPath}"); } return(Task.Factory.StartNew(() => { if (!Directory.Exists(_settings.ServerInstallDir)) { Directory.CreateDirectory(_settings.ServerInstallDir); } var steamCmdArgs = $"+login anonymous +force_install_dir \"{_settings.ServerInstallDir}\" +app_update {ConanExilesServerSteamAppId} +quit"; _process = ProcessWrapper.Create(_settings.SteamCmdPath) .WithArgs(steamCmdArgs) .Start(); _process.OutputDataReceived += (e, args) => Console.WriteLine(args.Data); _process.ErrorDataReceived += (e, args) => Console.Error.WriteLine(args.Data); _process.Wait(); }, cancellationToken)); }
public static async Task <Version> DotNetSdkVersion(CancellationToken cancel) { using var proc = ProcessWrapper.Create( new System.Diagnostics.ProcessStartInfo("dotnet", "--version"), cancel: cancel); List <string> outs = new List <string>(); using var outp = proc.Output.Subscribe(o => outs.Add(o)); List <string> errs = new List <string>(); using var errp = proc.Error.Subscribe(o => errs.Add(o)); var result = await proc.Run(); if (errs.Count > 0) { throw new ArgumentException($"{string.Join("\n", errs)}"); } if (outs.Count != 1) { throw new ArgumentException($"Unexpected messages:\n{string.Join("\n", outs)}"); } if (!Version.TryParse(outs[0], out var v)) { throw new ArgumentException($"Could not parse dotnet SDK version: {outs[0]}"); } return(v); }
public static async Task <IEnumerable <(string Package, string Requested, string Resolved, string Latest)> > NugetListingQuery(string projectPath, bool outdated, bool includePrerelease, CancellationToken cancel) { // Run restore first { using var restore = ProcessWrapper.Create( new ProcessStartInfo("dotnet", $"restore \"{projectPath}\""), cancel: cancel); await restore.Run(); } bool on = false; List <string> lines = new(); List <string> errors = new(); using var process = ProcessWrapper.Create( new ProcessStartInfo("dotnet", $"list \"{projectPath}\" package{(outdated ? " --outdated" : null)}{(includePrerelease ? " --include-prerelease" : null)}"), cancel: cancel); using var outSub = process.Output.Subscribe(s => { if (s.Contains("Top-level Package")) { on = true; return; } if (!on) { return; } lines.Add(s); }); using var errSub = process.Error.Subscribe(s => errors.Add(s)); var result = await process.Run(); if (errors.Count > 0) { throw new ArgumentException($"Error while retrieving nuget listings: \n{string.Join("\n", errors)}"); } var ret = new List <(string Package, string Requested, string Resolved, string Latest)>(); foreach (var line in lines) { if (!TryParseLibraryLine( line, out var package, out var requested, out var resolved, out var latest)) { continue; } ret.Add((package, requested, resolved, latest)); } return(ret); }
public override void Dispose() { base.Dispose(); Task.Run(async() => { using var process = ProcessWrapper.Create( new ProcessStartInfo("dotnet", $"build-server shutdown")); using var output = process.Output.Subscribe(x => Log.Logger.Information(x)); using var error = process.Error.Subscribe(x => Log.Logger.Information(x)); var ret = await process.Run(); return(ret); }).Wait(); }
public IProcessWrapper Create( ProcessStartInfo startInfo, CancellationToken?cancel = null, bool hideWindow = true, bool hookOntoOutput = true, bool killWithParent = true) { return(ProcessWrapper.Create( startInfo, cancel, hideWindow: hideWindow, hookOntoOutput: hookOntoOutput, killWithParent: killWithParent)); }
public async Task Run(RunSynthesisPatcher settings, CancellationToken cancel) { var repoPath = Path.GetDirectoryName(PathToSolution); if (Repository.IsValid(repoPath)) { using var repo = new Repository(repoPath); _output.OnNext($"Sha {repo.Head.Tip.Sha}"); } var runnability = await Synthesis.Bethesda.Execution.CLI.Commands.CheckRunnability( PathToProject, directExe : false, release : settings.GameRelease, dataFolder : settings.DataFolderPath, loadOrderPath : settings.LoadOrderFilePath, cancel : cancel); if (runnability.Failed) { throw new CliUnsuccessfulRunException((int)Codes.NotRunnable, runnability.Reason); } var internalSettings = new RunSynthesisMutagenPatcher() { DataFolderPath = settings.DataFolderPath, ExtraDataFolder = Path.Combine(PathToExtraDataBaseFolder, Name), GameRelease = settings.GameRelease, LoadOrderFilePath = settings.LoadOrderFilePath, OutputPath = settings.OutputPath, SourcePath = settings.SourcePath }; var args = Parser.Default.FormatCommandLine(internalSettings); using var process = ProcessWrapper.Create( new ProcessStartInfo("dotnet", $"run --project \"{PathToProject}\" --runtime win-x64 --no-build {args}"), cancel: cancel); _output.OnNext("Running"); _output.OnNext($"({process.StartInfo.WorkingDirectory}): {process.StartInfo.FileName} {process.StartInfo.Arguments}"); using var outputSub = process.Output.Subscribe(_output); using var errSub = process.Error.Subscribe(_error); var result = await process.Run().ConfigureAwait(false); if (result != 0) { throw new CliUnsuccessfulRunException(result, "Error running solution patcher"); } }
public void Run() { if (!File.Exists(_settings.ServerExePath)) { throw new NotSupportedException( $"There is no executable for the server on given path {_settings.ServerExePath}"); } _process = ProcessWrapper .Create(_settings.ServerExePath) .WithArgs("-server", "-log") .Start(); _process.OutputDataReceived += (e, args) => Console.WriteLine(args.Data); _process.ErrorDataReceived += (e, args) => Console.Error.WriteLine(args.Data); _process.Wait(); }
public static async Task <GetResponse <string> > GetExecutablePath(string projectPath, CancellationToken cancel) { // Hacky way to locate executable, but running a build and extracting the path its logs spit out // Tried using Buildalyzer, but it has a lot of bad side effects like clearing build outputs when // locating information like this. using var proc = ProcessWrapper.Create( new System.Diagnostics.ProcessStartInfo("dotnet", GetBuildString($"\"{projectPath}\"")), cancel: cancel); List <string> outs = new List <string>(); using var outp = proc.Output.Subscribe(o => outs.Add(o)); List <string> errs = new List <string>(); using var errp = proc.Error.Subscribe(o => errs.Add(o)); var result = await proc.Run(); if (errs.Count > 0) { throw new ArgumentException($"{string.Join("\n", errs)}"); } int index = outs.IndexOf("Build succeeded."); if (index == -1 || index < 2) { return(GetResponse <string> .Fail("Could not locate target executable.")); } var line = outs[index - 2]; const string delimiter = " -> "; index = line.IndexOf(delimiter); if (index == -1) { return(GetResponse <string> .Fail("Could not locate target executable.")); } return(GetResponse <string> .Succeed(line.Substring(index + delimiter.Length).Trim())); }