从C#调用WSL bash.exe

时间:2018-04-03 10:30:27

标签: c# windows-subsystem-for-linux

主要是好奇心,我写了一个小应用程序,在Windows上使用Ubuntu / WSL和Xming窗口服务器启动终结者shell。

从shell手动操作,我可以在Windows上运行Firefox,gedit,Terminator等,这很酷。

所以我使用bash.exe检查了where bash的位置,然后又返回了...

C:\Windows\System32\bash.exe

但是,当我尝试运行此代码时......

using (var xminProc = new Process())
{
    xminProc.StartInfo.FileName = @"C:\Program Files (x86)\Xming\Xming.exe";
    xminProc.StartInfo.Arguments = ":0 -clipboard -multiwindow";
    xminProc.StartInfo.CreateNoWindow = true;
    xminProc.Start();
}
using (var bashProc = new Process())
{
    bashProc.StartInfo.FileName = @"C:\Windows\System32\bash.exe";
    bashProc.StartInfo.Arguments = "-c \"export DISPLAY=:0; terminator; \"";
    bashProc.StartInfo.CreateNoWindow = true;
    bashProc.Start();
}

我收到了错误......

System.ComponentModel.Win32Exception: 'The system cannot find the file specified'

检查我的整个系统bash.exe显示它确实在另一个地方......

bash.exe location

我不确定这个位置是否是我可以依赖的位置,我担心它是短暂的并且可以在Windows Store更新期间更改,尽管我可能错了。

为什么命令提示符显示bash.exe位于System32,但它确实位于另一个位置?

我可以让C#也使用System32位置吗?

1 个答案:

答案 0 :(得分:0)

如@Biswapriyo所述,首先在解决方案上将platafrom设置为x64:

enter image description here

然后,您可以通过以下方式从c#在ubuntu计算机上运行:

            Console.WriteLine("Enter command to execute on your Ubuntu GNU/Linux");
            var commandToExecute = Console.ReadLine();

            // if command is null use 'ifconfig' for demo purposes
            if (string.IsNullOrWhiteSpace(commandToExecute))
            {
                commandToExecute = "ifconfig";
            }


            // Execute wsl command:
            using (var proc = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = @"cmd.exe",
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardInput = true,
                    CreateNoWindow = true,
                }
            })
            {
                proc.Start();
                proc.StandardInput.WriteLine("wsl " + commandToExecute);
                System.Threading.Thread.Sleep(500); // give some time for command to execute
                proc.StandardInput.Flush();
                proc.StandardInput.Close();
                proc.WaitForExit(5000); // wait up to 5 seconds for command to execute
                Console.WriteLine(proc.StandardOutput.ReadToEnd());
                Console.ReadLine();

            }