ClipboardProcessRunner.cs 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. using System.Diagnostics;
  2. namespace Terminal.Gui.App;
  3. /// <summary>
  4. /// Helper class for console drivers to invoke shell commands to interact with the clipboard. Used primarily by
  5. /// UnixDriver, but also used in Unit tests which is why it is in IDriver.cs.
  6. /// </summary>
  7. internal static class ClipboardProcessRunner
  8. {
  9. public static (int exitCode, string result) Bash (
  10. string commandLine,
  11. string inputText = "",
  12. bool waitForOutput = false
  13. )
  14. {
  15. var arguments = $"-c \"{commandLine}\"";
  16. (int exitCode, string result) = Process ("bash", arguments, inputText, waitForOutput);
  17. return (exitCode, result.TrimEnd ());
  18. }
  19. public static bool FileExists (this string value) { return !string.IsNullOrEmpty (value) && !value.Contains ("not found"); }
  20. public static (int exitCode, string result) Process (
  21. string cmd,
  22. string arguments,
  23. string? input = null,
  24. bool waitForOutput = true
  25. )
  26. {
  27. var output = string.Empty;
  28. using var process = new Process ();
  29. process.StartInfo = new()
  30. {
  31. FileName = cmd,
  32. Arguments = arguments,
  33. RedirectStandardOutput = true,
  34. RedirectStandardError = true,
  35. RedirectStandardInput = true,
  36. UseShellExecute = false,
  37. CreateNoWindow = true
  38. };
  39. process.Start ();
  40. if (!string.IsNullOrEmpty (input))
  41. {
  42. process.StandardInput.Write (input);
  43. process.StandardInput.Close ();
  44. }
  45. if (!process.WaitForExit (5000))
  46. {
  47. var timeoutError =
  48. $@"Process timed out. Command line: {process.StartInfo.FileName} {process.StartInfo.Arguments}.";
  49. throw new TimeoutException (timeoutError);
  50. }
  51. if (waitForOutput && process.StandardOutput.Peek () != -1)
  52. {
  53. output = process.StandardOutput.ReadToEnd ();
  54. }
  55. if (process.ExitCode > 0)
  56. {
  57. output = $@"Process failed to run. Command line: {cmd} {arguments}.
  58. Output: {output}
  59. Error: {process.StandardError.ReadToEnd ()}";
  60. }
  61. return (process.ExitCode, output);
  62. }
  63. }