Explorar el Código

trying to get WSL to work

Charlie Kindel hace 2 años
padre
commit
033d03f4a1

+ 68 - 76
Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs

@@ -6,6 +6,7 @@
 //
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Linq;
 using System.Runtime.InteropServices;
 using System.Threading.Tasks;
@@ -957,8 +958,8 @@ namespace Terminal.Gui {
 			if (new CursesClipboard ().IsSupported) {
 				return false;
 			}
-			var result = BashRunner.Run ("uname -a", runCurses: false);
-			if (result.Contains ("microsoft") && result.Contains ("WSL")) {
+			var (exitCode, result) = BashRunner.Run ("uname -a", runCurses: false);
+			if (exitCode == 0 && result.Contains ("microsoft") && result.Contains ("WSL")) {
 				return true;
 			}
 			return false;
@@ -1270,8 +1271,8 @@ namespace Terminal.Gui {
 		bool CheckSupport ()
 		{
 			try {
-				var result = BashRunner.Run ("which xclip", runCurses: false);
-				return result.FileExists ();
+				var (exitCode, result) = BashRunner.Run ("which xclip", runCurses: false);
+				return (exitCode == 0 && result.FileExists ());
 			} catch (Exception) {
 				// Permissions issue.
 				return false;
@@ -1283,11 +1284,14 @@ namespace Terminal.Gui {
 			var tempFileName = System.IO.Path.GetTempFileName ();
 			try {
 				// BashRunner.Run ($"xsel -o --clipboard > {tempFileName}");
-				BashRunner.Run ($"xclip -selection clipboard -o > {tempFileName}");
-				return System.IO.File.ReadAllText (tempFileName);
+				var (exitCode, result) = BashRunner.Run ($"xclip -selection clipboard -o > {tempFileName}");
+				if (exitCode == 0) {
+					return System.IO.File.ReadAllText (tempFileName);
+				}
 			} finally {
 				System.IO.File.Delete (tempFileName);
 			}
+			return string.Empty;
 		}
 
 		protected override void SetClipboardDataImpl (string text)
@@ -1306,69 +1310,51 @@ namespace Terminal.Gui {
 	}
 
 	static class BashRunner {
-		public static string Run (string commandLine, bool output = true, string inputText = "", bool runCurses = true)
+		public static (int exitCode, string result) Run (string commandLine, bool output = true, string inputText = "", bool runCurses = true)
 		{
 			var arguments = $"-c \"{commandLine}\"";
 
-			if (output) {
-				var errorBuilder = new System.Text.StringBuilder ();
-				var outputBuilder = new System.Text.StringBuilder ();
-
-				using (var process = new System.Diagnostics.Process {
-					StartInfo = new System.Diagnostics.ProcessStartInfo {
-						FileName = "bash",
-						Arguments = arguments,
-						RedirectStandardOutput = true,
-						RedirectStandardError = true,
-						UseShellExecute = false,
-						CreateNoWindow = false,
-					}
-				}) {
-					process.Start ();
-					process.OutputDataReceived += (sender, args) => { outputBuilder.AppendLine (args.Data); };
-					process.BeginOutputReadLine ();
-					process.ErrorDataReceived += (sender, args) => { errorBuilder.AppendLine (args.Data); };
-					process.BeginErrorReadLine ();
-					if (!process.DoubleWaitForExit ()) {
-						var timeoutError = $@"Process timed out. Command line: bash {arguments}.
-							Output: {outputBuilder}
-							Error: {errorBuilder}";
-						throw new Exception (timeoutError);
-					}
-					if (process.ExitCode == 0) {
-						if (runCurses && Application.Driver is CursesDriver) {
-							Curses.raw ();
-							Curses.noecho ();
-						}
-						return outputBuilder.ToString ();
-					}
+			var errorBuilder = new System.Text.StringBuilder ();
+			var outputBuilder = new System.Text.StringBuilder ();
 
-					var error = $@"Could not execute process. Command line: bash {arguments}.
-						Output: {outputBuilder}
-						Error: {errorBuilder}";
-					throw new Exception (error);
+			using (var process = new System.Diagnostics.Process {
+				StartInfo = new System.Diagnostics.ProcessStartInfo {
+					FileName = "bash",
+					Arguments = arguments,
+					RedirectStandardInput = true,
+					RedirectStandardOutput = true,
+					RedirectStandardError = true,
+					UseShellExecute = false,
+					CreateNoWindow = false,
 				}
-			} else {
-				using (var process = new System.Diagnostics.Process {
-					StartInfo = new System.Diagnostics.ProcessStartInfo {
-						FileName = "bash",
-						Arguments = arguments,
-						RedirectStandardInput = true,
-						RedirectStandardError = true,
-						UseShellExecute = false,
-						CreateNoWindow = false
-					}
-				}) {
-					process.Start ();
+			}) {
+				process.Start ();
+				if (output) {
 					process.StandardInput.Write (inputText);
-					process.StandardInput.Close ();
-					process.WaitForExit ();
+				}
+				process.StandardInput.Close ();
+				process.OutputDataReceived += (sender, args) => { outputBuilder.AppendLine (args.Data); };
+				process.BeginOutputReadLine ();
+				process.ErrorDataReceived += (sender, args) => { errorBuilder.AppendLine (args.Data); };
+				process.BeginErrorReadLine ();
+				if (!process.DoubleWaitForExit ()) {
+					var timeoutError = $@"Process timed out. Command line: {process.StartInfo.FileName} {arguments}.
+							Output: {outputBuilder}
+							Error: {errorBuilder}";
+					throw new TimeoutException (timeoutError);
+				}
+				if (process.ExitCode == 0) {
 					if (runCurses && Application.Driver is CursesDriver) {
 						Curses.raw ();
 						Curses.noecho ();
 					}
-					return inputText;
+					return (process.ExitCode, outputBuilder.ToString ().TrimEnd ());
 				}
+
+				var error = $@"Could not execute process. ExitCode: {process.ExitCode}, Command line: {process.StartInfo.FileName} {arguments}.
+						Output: {outputBuilder}
+						Error: {errorBuilder}";
+				return (process.ExitCode, error);
 			}
 		}
 
@@ -1413,11 +1399,11 @@ namespace Terminal.Gui {
 
 		bool CheckSupport ()
 		{
-			var result = BashRunner.Run ("which pbcopy");
+			var (exitCode, result) = BashRunner.Run ("which pbcopy");
 			if (!result.FileExists ()) {
 				return false;
 			}
-			result = BashRunner.Run ("which pbpaste");
+			(exitCode, result) = BashRunner.Run ("which pbpaste");
 			return result.FileExists ();
 		}
 
@@ -1469,43 +1455,44 @@ namespace Terminal.Gui {
 
 		public override bool IsSupported { get; }
 
+		private string powershellCommand = string.Empty;
+
 		bool CheckSupport ()
 		{
-			try {
-				var result = BashRunner.Run ("which powershell.exe");
-				return result.FileExists ();
-			} catch (System.Exception) {
-				return false;
-			}
+			if (string.IsNullOrEmpty (powershellCommand)) {
+				var (exitCode, result) = BashRunner.Run ("which pwsh");
+				if (exitCode > 0) {
+					(exitCode, result) = BashRunner.Run ("which powershell");
+				}
 
-			//var result = BashRunner.Run ("which powershell.exe");
-			//if (!result.FileExists ()) {
-			//	return false;
-			//}
-			//result = BashRunner.Run ("which clip.exe");
-			//return result.FileExists ();
+				if (exitCode == 0) {
+					powershellCommand = result;
+				}
+			}
+			return !string.IsNullOrEmpty (powershellCommand);
 		}
 
 		protected override string GetClipboardDataImpl ()
 		{
+			if (!IsSupported) return string.Empty;
 			using (var powershell = new System.Diagnostics.Process {
 				StartInfo = new System.Diagnostics.ProcessStartInfo {
 					RedirectStandardOutput = true,
-					FileName = "powershell.exe",
+					FileName = powershellCommand,
 					Arguments = "-noprofile -command \"Get-Clipboard\"",
 					UseShellExecute = false,
 					CreateNoWindow = true
 				}
 			}) {
 				powershell.Start ();
-				var result = powershell.StandardOutput.ReadToEnd ();
-				powershell.StandardOutput.Close ();
 				if (!powershell.DoubleWaitForExit ()) {
 					var timeoutError = $@"Process timed out. Command line: bash {powershell.StartInfo.Arguments}.
 							Output: {powershell.StandardOutput.ReadToEnd ()}
 							Error: {powershell.StandardError.ReadToEnd ()}";
 					throw new Exception (timeoutError);
 				}
+				var result = powershell.StandardOutput.ReadToEnd ();
+				powershell.StandardOutput.Close ();
 				if (Application.Driver is CursesDriver) {
 					Curses.raw ();
 					Curses.noecho ();
@@ -1519,9 +1506,14 @@ namespace Terminal.Gui {
 
 		protected override void SetClipboardDataImpl (string text)
 		{
+			if (!IsSupported) return;
+
 			using (var powershell = new System.Diagnostics.Process {
 				StartInfo = new System.Diagnostics.ProcessStartInfo {
-					FileName = "powershell.exe",
+					RedirectStandardOutput = true,
+					RedirectStandardError = true,
+					RedirectStandardInput = true,
+					FileName = powershellCommand,
 					Arguments = $"-noprofile -command \"Set-Clipboard -Value \\\"{text}\\\"\""
 				}
 			}) {

+ 25 - 16
Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs

@@ -26,7 +26,29 @@ namespace Terminal.Gui {
 		public override int Left => 0;
 		public override int Top => 0;
 		public override bool HeightAsBuffer { get; set; }
-		public override IClipboard Clipboard { get; }
+		private IClipboard clipboard = null;
+		public override IClipboard Clipboard {
+			get {
+				if (clipboard == null) {
+					if (usingFakeClipboard) {
+						clipboard = new FakeClipboard ();
+					} else {
+						if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) {
+							clipboard = new WindowsClipboard ();
+						} else if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) {
+							clipboard = new MacOSXClipboard ();
+						} else {
+							if (CursesDriver.Is_WSL_Platform ()) {
+								clipboard = new WSLClipboard ();
+							} else {
+								clipboard = new CursesClipboard ();
+							}
+						}
+					}
+				}
+				return clipboard;
+			}
+		}
 
 		// The format is rows, columns and 3 values on the last column: Rune, Attribute and Dirty Flag
 		int [,,] contents;
@@ -56,24 +78,11 @@ namespace Terminal.Gui {
 		//}
 
 		static bool sync = false;
+		static public bool usingFakeClipboard;
 
 		public FakeDriver (bool useFakeClipboard = true)
 		{
-			if (useFakeClipboard) {
-				Clipboard = new FakeClipboard ();
-			} else {
-				if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) {
-					Clipboard = new WindowsClipboard ();
-				} else if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) {
-					Clipboard = new MacOSXClipboard ();
-				} else {
-					if (CursesDriver.Is_WSL_Platform ()) {
-						Clipboard = new WSLClipboard ();
-					} else {
-						Clipboard = new CursesClipboard ();
-					}
-				}
-			}
+			usingFakeClipboard = useFakeClipboard;
 		}
 
 		bool needMove;

+ 63 - 163
UnitTests/ClipboardTests.cs

@@ -1,4 +1,5 @@
-using System.Diagnostics;
+using System;
+using System.Diagnostics;
 using System.Runtime.InteropServices;
 using Xunit;
 using Xunit.Abstractions;
@@ -68,111 +69,78 @@ namespace Terminal.Gui.ConsoleDrivers {
 			}
 		}
 
+		private static string RunClipboardProcess (string cmd, string args, string writeText = null)
+		{
+			string output = string.Empty;
+
+			using (Process process = new Process {
+				StartInfo = new ProcessStartInfo {
+					FileName = cmd,
+					Arguments = args,
+					RedirectStandardOutput = true,
+					RedirectStandardError = true,
+					RedirectStandardInput = true
+				}
+			}) {
+				process.Start ();
+				if (string.IsNullOrEmpty (writeText)) {
+					process.StandardInput.Write (writeText);
+					process.StandardInput.Close ();
+				}
+				process.WaitForExit ();
+
+				if (process.ExitCode > 0) {
+					var error = $@"RunClipboardProcess failed. Command line: {cmd} {args}.
+										Output: {process.StandardOutput.ReadToEnd ()}
+										Error: {process.StandardError.ReadToEnd ()}";
+					throw new InvalidOperationException (error);
+				}
+				output = process.StandardOutput.ReadToEnd ().TrimEnd ();
+				process.StandardOutput.Close ();
+			}
+			return output;
+		}
+
 		[Fact, AutoInitShutdown (useFakeClipboard: false)]
 		public void Contents_Gets_From_OS_Clipboard ()
 		{
 			var clipText = "This is a clipboard unit test to get clipboard from OS.";
-			var exit = false;
+			var failed = false;
 			var getClipText = "";
 
 			Application.Iteration += () => {
 				if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) {
-					// using (Process clipExe = new Process {
-					// 	StartInfo = new ProcessStartInfo {
-					// 		RedirectStandardInput = true,
-					// 		FileName = "clip"
-					// 	}
-					// }) {
-					// 	clipExe.Start ();
-					// 	clipExe.StandardInput.Write (clipText);
-					// 	clipExe.StandardInput.Close ();
-					// 	var result = clipExe.WaitForExit (500);
-					// 	if (result) {
-					// 		clipExe.WaitForExit ();
-					// 	}
-					// }
-
-					using (Process pwsh = new Process {
-						StartInfo = new ProcessStartInfo {
-							FileName = "powershell",
-							Arguments = $"-command \"Set-Clipboard -Value \\\"{clipText}\\\"\""
-						}
-					}) {
-						pwsh.Start ();
-						pwsh.WaitForExit ();
-					}
+					RunClipboardProcess ("pwsh", $"-command \"Set-Clipboard -Value \\\"{clipText}\\\"\"");
 					getClipText = Clipboard.Contents.ToString ();
 
 				} else if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) {
-					using (Process copy = new Process {
-						StartInfo = new ProcessStartInfo {
-							RedirectStandardInput = true,
-							FileName = "pbcopy"
-						}
-					}) {
-						copy.Start ();
-						copy.StandardInput.Write (clipText);
-						copy.StandardInput.Close ();
-						copy.WaitForExit ();
-					}
+					RunClipboardProcess ("pbcopy", string.Empty, clipText);
 					getClipText = Clipboard.Contents.ToString ();
 
 				} else if (RuntimeInformation.IsOSPlatform (OSPlatform.Linux)) {
 					if (Is_WSL_Platform ()) {
 						try {
-							using (Process bash = new Process {
-								StartInfo = new ProcessStartInfo {
-									FileName = "powershell.exe",
-									Arguments = $"-noprofile -command \"Set-Clipboard -Value \\\"{clipText}\\\"\""
-								}
-							}) {
-								bash.Start ();
-								bash.WaitForExit ();
-							}
-
-							//using (Process clipExe = new Process {
-							//	StartInfo = new ProcessStartInfo {
-							//		RedirectStandardInput = true,
-							//		FileName = "clip.exe"
-							//	}
-							//}) {
-							//	clipExe.Start ();
-							//	clipExe.StandardInput.Write (clipText);
-							//	clipExe.StandardInput.Close ();
-							//	clipExe.WaitForExit ();
-							//	//var result = clipExe.WaitForExit (500);
-							//	//if (result) {
-							//	//	clipExe.WaitForExit ();
-							//	//}
-							//}
+							RunClipboardProcess ("pwsh", $"-noprofile -command \"Set-Clipboard -Value \\\"{clipText}\\\"\"");
 						} catch {
-							exit = true;
+							failed = true;
 						}
-						if (!exit) {
+						if (!failed) {
 							getClipText = Clipboard.Contents.ToString ();
 						}
 						Application.RequestStop ();
 						return;
 					}
-					if (exit = xclipExists () == false) {
+
+					if (failed = xclipExists () == false) {
 						// xclip doesn't exist then exit.
 						Application.RequestStop ();
 						return;
 					}
 
-					using (Process bash = new Process {
-						StartInfo = new ProcessStartInfo {
-							FileName = "bash",
-							Arguments = $"-c \"xclip -sel clip -i\"",
-							RedirectStandardInput = true,
-						}
-					}) {
-						bash.Start ();
-						bash.StandardInput.Write (clipText);
-						bash.StandardInput.Close ();
-						bash.WaitForExit ();
-					}
-					if (!exit) {
+					// If we get here, powershell didn't work and xclip exists...
+					RunClipboardProcess ("bash", $"-c \"xclip -sel clip -i\"", clipText);
+
+					if (!failed) {
 						getClipText = Clipboard.Contents.ToString ();
 					}
 				}
@@ -182,83 +150,44 @@ namespace Terminal.Gui.ConsoleDrivers {
 
 			Application.Run ();
 
-			if (!exit) {
+			if (!failed) {
 				Assert.Equal (clipText, getClipText);
 			}
 		}
 
+
 		[Fact, AutoInitShutdown (useFakeClipboard: false)]
 		public void Contents_Sets_The_OS_Clipboard ()
 		{
 			var clipText = "This is a clipboard unit test to set the OS clipboard.";
 			var clipReadText = "";
-			var exit = false;
+			var failed = false;
 
 			Application.Iteration += () => {
 				Clipboard.Contents = clipText;
 
 				if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) {
-					using (Process pwsh = new Process {
-						StartInfo = new ProcessStartInfo {
-							RedirectStandardOutput = true,
-							FileName = "powershell.exe",
-							Arguments = "-noprofile -command \"Get-Clipboard\""
-						}
-					}) {
-						pwsh.Start ();
-						clipReadText = pwsh.StandardOutput.ReadToEnd ().TrimEnd ();
-						pwsh.StandardOutput.Close ();
-						pwsh.WaitForExit ();
-					}
+					clipReadText = RunClipboardProcess ("pwsh", "-noprofile -command \"Get-Clipboard\"");
+
 				} else if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) {
-					using (Process paste = new Process {
-						StartInfo = new ProcessStartInfo {
-							RedirectStandardOutput = true,
-							FileName = "pbpaste"
-						}
-					}) {
-						paste.Start ();
-						clipReadText = paste.StandardOutput.ReadToEnd ();
-						paste.StandardOutput.Close ();
-						paste.WaitForExit ();
-					}
+					clipReadText = RunClipboardProcess ("pbpaste", "");
+
 				} else if (RuntimeInformation.IsOSPlatform (OSPlatform.Linux)) {
 					if (Is_WSL_Platform ()) {
 						try {
-							using (Process bash = new Process {
-								StartInfo = new ProcessStartInfo {
-									RedirectStandardOutput = true,
-									FileName = "powershell.exe",
-									Arguments = "-noprofile -command \"Get-Clipboard\""
-								}
-							}) {
-								bash.Start ();
-								clipReadText = bash.StandardOutput.ReadToEnd ();
-								bash.StandardOutput.Close ();
-								bash.WaitForExit ();
-							}
+							clipReadText = RunClipboardProcess ("/opt/microsoft/powershell/7/pwsh", "-noprofile -command \"Get-Clipboard\"");
 						} catch {
-							exit = true;
+							failed = true;
 						}
 						Application.RequestStop ();
 					}
-					if (exit = xclipExists () == false) {
+					if (failed = xclipExists () == false) {
 						// xclip doesn't exist then exit.
 						Application.RequestStop ();
+						return;
 					}
 
-					using (Process bash = new Process {
-						StartInfo = new ProcessStartInfo {
-							RedirectStandardOutput = true,
-							FileName = "bash",
-							Arguments = $"-c \"xclip -sel clip -o\""
-						}
-					}) {
-						bash.Start ();
-						clipReadText = bash.StandardOutput.ReadToEnd ();
-						bash.StandardOutput.Close ();
-						bash.WaitForExit ();
-					}
+					clipReadText = RunClipboardProcess ("bash", $"-c \"xclip -sel clip -o\"");
 				}
 
 				Application.RequestStop ();
@@ -266,7 +195,7 @@ namespace Terminal.Gui.ConsoleDrivers {
 
 			Application.Run ();
 
-			if (!exit) {
+			if (!failed) {
 				Assert.Equal (clipText, clipReadText);
 			}
 
@@ -274,44 +203,15 @@ namespace Terminal.Gui.ConsoleDrivers {
 
 		bool Is_WSL_Platform ()
 		{
-			using (Process bash = new Process {
-				StartInfo = new ProcessStartInfo {
-					FileName = "bash",
-					Arguments = $"-c \"uname -a\"",
-					RedirectStandardOutput = true,
-				}
-			}) {
-				bash.Start ();
-				var result = bash.StandardOutput.ReadToEnd ();
-				var isWSL = false;
-				if (result.Contains ("microsoft") && result.Contains ("WSL")) {
-					isWSL = true;
-				}
-				bash.StandardOutput.Close ();
-				bash.WaitForExit ();
-				return isWSL;
-			}
+			var result = RunClipboardProcess ("bash", $"-c \"uname -a\"");
+			return result.Contains ("microsoft") && result.Contains ("WSL");
 		}
 
 		bool xclipExists ()
 		{
 			try {
-				using (Process bash = new Process {
-					StartInfo = new ProcessStartInfo {
-						FileName = "bash",
-						Arguments = $"-c \"which xclip\"",
-						RedirectStandardOutput = true,
-					}
-				}) {
-					bash.Start ();
-					bool exist = bash.StandardOutput.ReadToEnd ().TrimEnd () != "";
-					bash.StandardOutput.Close ();
-					bash.WaitForExit ();
-					if (exist) {
-						return true;
-					}
-				}
-				return false;
+				var result = RunClipboardProcess ("bash", $"-c \"which xclip\"");
+				return result.TrimEnd () != "";
 			} catch (System.Exception) {
 				return false;
 			}

+ 11 - 0
UnitTests/DialogTests.cs

@@ -513,5 +513,16 @@ namespace Terminal.Gui.Views {
 			TestHelpers.AssertDriverContentsWithFrameAre ($"{topRow}\n{buttonRow}\n{bottomRow}", output);
 			Application.End (runstate);
 		}
+
+		[Fact]
+		[AutoInitShutdown]
+		public void FileDialog_FileSystemWatcher ()
+		{
+			for (int i = 0; i < 256; i++) {
+				var fd = new FileDialog ();
+				fd.Ready += () => Application.RequestStop ();
+				Application.Run (fd);
+			}
+		}
 	}
 }

+ 0 - 10
UnitTests/ToplevelTests.cs

@@ -651,15 +651,5 @@ namespace Terminal.Gui.Core {
 			Assert.Equal (Key.Q | Key.CtrlMask, Application.QuitKey);
 		}
 
-		[Fact]
-		[AutoInitShutdown]
-		public void FileDialog_FileSystemWatcher ()
-		{
-			for (int i = 0; i < 256; i++) {
-				var fd = new FileDialog ();
-				fd.Ready += () => Application.RequestStop ();
-				Application.Run (fd);
-			}
-		}
 	}
 }