/* * On OS X we do not launch command directly but we launch an AppleScript that creates (or reuses) a Terminal window * and then launches the command inside that window. The script returns the process of the command or an error. */ private static LaunchResult LaunchInTerminalOSX(string directory, string runtimePath, string[] runtimeArgs, string program, string[] programArgs, Dictionary <string, string> environmentVariables) { // first fix the PATH so that 'runtimePath' can be found if installed with 'brew' Utilities.FixPathOnOSX(); var activate_terminal = false; // see bug 17519 var scriptPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TerminalHelper.scpt"); var runtimeName = Path.GetFileName(runtimePath); var arguments = string.Format("{0} -t {1} -w {2} -r {3} -rn {4} -p {5}", Quote(scriptPath), Quote(TERMINAL_TITLE), Quote(directory), Quote(runtimePath), Quote(runtimeName), Quote(program)); if (runtimeArgs != null) { foreach (var r in runtimeArgs) { arguments += string.Format(" -ra {0}", Quote(r)); } } if (programArgs != null) { foreach (var a in programArgs) { arguments += string.Format(" -pa {0}", Quote(a)); } } if (environmentVariables != null) { foreach (var entry in environmentVariables) { arguments += string.Format(" -e \"{0}={1}\"", entry.Key, entry.Value); } } if (activate_terminal) { arguments += " -a"; } var scriptProcess = new Process(); scriptProcess.StartInfo.CreateNoWindow = true; scriptProcess.StartInfo.UseShellExecute = false; scriptProcess.StartInfo.FileName = OSASCRIPT; scriptProcess.StartInfo.Arguments = arguments; scriptProcess.StartInfo.RedirectStandardOutput = true; scriptProcess.StartInfo.RedirectStandardError = true; var result = new LaunchResult(); try { scriptProcess.Start(); var stdout = scriptProcess.StandardOutput.ReadToEnd(); var stderr = scriptProcess.StandardError.ReadToEnd(); if (stdout.Length > 0) { int pid; var lines = Regex.Split(stdout, "\r\n|\r|\n"); if (lines.Length > 0) { if (Int32.TryParse(lines[0], out pid)) { if (pid > 0) // we got a real process ID { result.SetProcess(null, pid); } } else { // could not parse, assume the reason is in stdout result.SetError(stdout); } } } else { // we got nothing on stdout; assume that stderr contains an error message result.SetError(stderr); } } catch (Exception e) { result.SetError(e.Message); } return(result); }