Mono:如何在新的控制台/终端窗口上运行bash命令?

时间:2017-09-20 13:42:33

标签: c# linux bash terminal mono

如何在新的控制台/终端窗口中使用Mono(System.Diagnostics.Process)运行bash命令?它在Windows上运行正常,在Windows上打开一个新的控制台窗口来运行该命令。在Linux和macOS上,该命令在我用来打开应用程序的同一个终端窗口上运行。我已经尝试了所有CreateNoWindow / UseShellExecute组合,但它们都没有为我工作。

编辑:这里是代码:

                    var startInfo = new ProcessStartInfo();
                switch (ThermoCS.PlatformCheck.RunningPlatform())
                {
                    case ThermoCS.PlatformCheck.Platform.Windows:
                        startInfo.WorkingDirectory = Environment.CurrentDirectory;
                        startInfo.FileName = Environment.CurrentDirectory + "\\ThermoCS\\" + item.Key + ".exe";
                        if (item.Key.Contains("1"))
                        {
                            startInfo.Arguments = Model;
                        }
                        else
                        {
                            startInfo.Arguments = Model + " " + MixRule;
                        }
                        break;
                    case ThermoCS.PlatformCheck.Platform.Linux:
                        startInfo.WorkingDirectory = Environment.CurrentDirectory;
                        var ldc = "LD_LIBRARY_PATH=" + Environment.CurrentDirectory + "/ThermoCS/; export LD_LIBRARY_PATH";
                        //startInfo.UseShellExecute = false;
                        startInfo.WindowStyle = ProcessWindowStyle.Normal;
                        startInfo.FileName = "/bin/bash";
                        if (item.Key.Contains("1"))
                        {
                            startInfo.Arguments = "-c \" " + ldc + " && chmod +x ThermoCS/" + item.Key + " && ./ThermoCS/" + item.Key + " " + Model + " \"";
                        }
                        else
                        {
                            startInfo.Arguments = "-c \" " + ldc + " && chmod +x ThermoCS/" + item.Key + " && ./ThermoCS/" + item.Key + " " + Model + " " + MixRule + " \"";
                        }
                        break;
                    case ThermoCS.PlatformCheck.Platform.Mac:
                        var basedir = Directory.GetParent(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)).Parent.FullName;
                        var ldcosx = "export DYLD_LIBRARY_PATH=" + basedir + "/Contents/MonoBundle/ThermoCS/";
                        startInfo.WorkingDirectory = basedir;
                        //startInfo.UseShellExecute = false;
                        startInfo.WindowStyle = ProcessWindowStyle.Normal;
                        startInfo.FileName = "/bin/bash";
                        if (item.Key.Contains("1"))
                        {
                            startInfo.Arguments = "-c \" " + ldcosx + " && chmod +x Contents/MonoBundle/ThermoCS/" + item.Key + " && ./Contents/MonoBundle/ThermoCS/" + item.Key + " " + Model + " \"";
                        }
                        else
                        {
                            startInfo.Arguments = "-c \" " + ldcosx + " && chmod +x Contents/MonoBundle/ThermoCS/" + item.Key + " && ./Contents/MonoBundle/ThermoCS/" + item.Key + " " + Model + " " + MixRule + " \"";
                        }
                        break;
                }
                Process proc = Process.Start(startInfo);

正如我上面所描述的那样,命令运行得很好。问题是在Linux和macOS上,它在拥有当前运行的应用程序的同一终端窗口上执行。我希望它能在新的终端窗口上运行。

提前致谢!

2 个答案:

答案 0 :(得分:0)

我自己找到了解决方案。它涉及将命令保存在脚本文件中,使其可执行并在Linux上调用 xterm 或在macOS上调用 Terminal.app

var startInfo = new ProcessStartInfo();
switch (ThermoCS.PlatformCheck.RunningPlatform())
{
    case ThermoCS.PlatformCheck.Platform.Windows:
        startInfo.WorkingDirectory = Environment.CurrentDirectory;
        startInfo.FileName = Environment.CurrentDirectory + "\\ThermoCS\\" + item.Key + ".exe";
        if (item.Key.Contains("1"))
        {
            startInfo.Arguments = Model;
        }
        else
        {
            startInfo.Arguments = Model + " " + MixRule;
        }
        break;
    case ThermoCS.PlatformCheck.Platform.Linux:
        startInfo.WorkingDirectory = Environment.CurrentDirectory;
        var ldc = "LD_LIBRARY_PATH=" + Environment.CurrentDirectory + "/ThermoCS/; export LD_LIBRARY_PATH";
        var scriptl = new StringBuilder();
        scriptl.AppendLine("#!/bin/bash");
        scriptl.AppendLine("cd '" + Environment.CurrentDirectory + "'");
        scriptl.AppendLine(ldc);
        scriptl.AppendLine("chmod +x ThermoCS/" + item.Key);
        if (item.Key.Contains("1"))
        {
            scriptl.AppendLine("./ThermoCS/" + item.Key + " " + Model);
        }
        else
        {
            scriptl.AppendLine("./ThermoCS/" + item.Key + " " + Model + " " + MixRule);
        }
        var filepathl = Path.GetTempFileName();
        File.WriteAllText(filepathl, scriptl.ToString());
        Process.Start("/bin/bash", "-c \" chmod +x " + filepathl + " \"");
        startInfo.WindowStyle = ProcessWindowStyle.Normal;
        startInfo.FileName = "xterm";
        startInfo.Arguments = "-e '" + filepathl + "'";
        break;
    case ThermoCS.PlatformCheck.Platform.Mac:
        var basedir = Directory.GetParent(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)).Parent.FullName;
        var ldcosx = "export DYLD_LIBRARY_PATH=" + basedir + "/Contents/MonoBundle/ThermoCS/";
        var script = new StringBuilder();
        script.AppendLine("#!/bin/bash");
        script.AppendLine("cd '" + basedir + "'");
        script.AppendLine(ldcosx);
        script.AppendLine("chmod +x Contents/MonoBundle/ThermoCS/" + item.Key);
        if (item.Key.Contains("1"))
        {
            script.AppendLine("./Contents/MonoBundle/ThermoCS/" + item.Key + " " + Model);
        }
        else
        {
            script.AppendLine("./Contents/MonoBundle/ThermoCS/" + item.Key + " " + Model + " " + MixRule);
        }
        var filepath = Path.GetTempFileName();
        File.WriteAllText(filepath, script.ToString());
        Process.Start("/bin/bash", "-c \" chmod +x " + filepath + " \"");
        startInfo.WindowStyle = ProcessWindowStyle.Normal;
        startInfo.FileName = "open";
        startInfo.Arguments = "-a Terminal.app " + filepath;
        break;
}
Process proc = Process.Start(startInfo);

答案 1 :(得分:0)

我做的是我写了一个简单的bash脚本,放在我的Debug / Release / Whatever文件夹(C#程序的可执行文件的文件夹)中。让我们将bash脚本称为first.sh

在此bash文件夹中,我将从另一个目录中调用另一个bash,即我最初希望运行的bash。让我们将此bash脚本称为second.sh

在我的C#代码中,我将这样调用first.sh:

 string command = string.Format("{0}", "./first.sh");
        Process proc = new System.Diagnostics.Process();
        proc.StartInfo.FileName = "gnome-terminal";
        proc.StartInfo.UseShellExecute = true;
        proc.StartInfo.RedirectStandardInput = false;
        proc.StartInfo.RedirectStandardOutput = false;
        proc.StartInfo.Arguments = " -e  \" " + command + " \"";

        proc.Start();

我的first.sh将更改为我的second.sh所在的目录:

#!/bin/sh
# This is a comment!
echo hello world        # This is just a test to see if it is being called
cd ~
cd home/scripts
(exec "./second")

这整个过程将物理上打开一个新终端,并通过C#代码在其中执行命令。

以下是有关如何编写bash脚本的很好的教程:tutorial on bash scripting in linux