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