From b7249a99a5bbae0a77f959ea695ca7977655ce10 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Mon, 12 Aug 2019 20:00:42 +1000 Subject: [PATCH] Extract shell command helpers --- BizHawk.Client.EmuHawk/AVOut/FFmpegWriter.cs | 19 ++++---- BizHawk.Common/OSTailoredCode.cs | 50 ++++++++++++++------ 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/BizHawk.Client.EmuHawk/AVOut/FFmpegWriter.cs b/BizHawk.Client.EmuHawk/AVOut/FFmpegWriter.cs index 999c1deb7f..178b086e8e 100644 --- a/BizHawk.Client.EmuHawk/AVOut/FFmpegWriter.cs +++ b/BizHawk.Client.EmuHawk/AVOut/FFmpegWriter.cs @@ -85,17 +85,14 @@ namespace BizHawk.Client.EmuHawk { try { - _ffmpeg = new Process(); - _ffmpeg.StartInfo.FileName = OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows - ? Path.Combine(PathManager.GetDllDirectory(), "ffmpeg.exe") - : "ffmpeg"; - _ffmpeg.StartInfo.Arguments = $"-y -f nut -i - {_token.Commandline} \"{_baseName}{(_segment == 0 ? string.Empty : $"_{_segment}")}{_ext}\""; - _ffmpeg.StartInfo.CreateNoWindow = true; - - // ffmpeg sends informative display to stderr, and nothing to stdout - _ffmpeg.StartInfo.RedirectStandardError = true; - _ffmpeg.StartInfo.RedirectStandardInput = true; - _ffmpeg.StartInfo.UseShellExecute = false; + _ffmpeg = OSTailoredCode.ConstructSubshell( + OSTailoredCode.CurrentOS == OSTailoredCode.DistinctOS.Windows + ? Path.Combine(PathManager.GetDllDirectory(), "ffmpeg.exe") + : "ffmpeg", + $"-y -f nut -i - {_token.Commandline} \"{_baseName}{(_segment == 0 ? string.Empty : $"_{_segment}")}{_ext}\"", + checkStdout: false, + checkStderr: true // ffmpeg sends informative display to stderr, and nothing to stdout + ); _commandline = $"ffmpeg {_ffmpeg.StartInfo.Arguments}"; diff --git a/BizHawk.Common/OSTailoredCode.cs b/BizHawk.Common/OSTailoredCode.cs index fa7c882556..e11aeecc8b 100644 --- a/BizHawk.Common/OSTailoredCode.cs +++ b/BizHawk.Common/OSTailoredCode.cs @@ -33,21 +33,7 @@ namespace BizHawk.Common public static ILinkedLibManager LinkedLibManager => lazy.Value; - private static bool currentIsMacOS() - { - var proc = new Process { - StartInfo = new ProcessStartInfo { - Arguments = "-s", - CreateNoWindow = true, - FileName = "uname", - RedirectStandardOutput = true, - UseShellExecute = false - } - }; - proc.Start(); - if (proc.StandardOutput.EndOfStream) throw new Exception("Can't determine OS (uname wrote nothing to stdout)!"); - return proc.StandardOutput.ReadLine() == "Darwin"; - } + private static bool currentIsMacOS() => SimpleSubshell("uname", "-s", "Can't determine OS") == "Darwin"; private OSTailoredCode() {} @@ -125,5 +111,39 @@ namespace BizHawk.Common macOS, Windows } + + /// POSIX $0 + /// POSIX $* (space-delimited) + /// stdout is discarded if false + /// stderr is discarded if false + /// OS is implicit and needs to be checked at callsite, returned has not been started + public static Process ConstructSubshell(string cmd, string args, bool checkStdout = true, bool checkStderr = false) => + new Process { + StartInfo = new ProcessStartInfo { + Arguments = args, + CreateNoWindow = true, + FileName = cmd, + RedirectStandardError = checkStderr, + RedirectStandardOutput = checkStdout, + UseShellExecute = false + } + }; + + /// POSIX $0 + /// POSIX $* (space-delimited) + /// used in exception + /// first line of stdout + /// thrown if stdout is empty + /// OS is implicit and needs to be checked at callsite + public static string SimpleSubshell(string cmd, string args, string noOutputMsg) + { + using (var proc = ConstructSubshell(cmd, args)) + { + proc.Start(); + var stdout = proc.StandardOutput; + if (stdout.EndOfStream) throw new Exception($"{noOutputMsg} ({cmd} wrote nothing to stdout)"); + return stdout.ReadLine(); + } + } } } \ No newline at end of file