Geesh_SO
Geesh_SO

Reputation: 2206

Calling WSL bash.exe from C#

Mostly just as a curiosity, I wrote a little app to start up Terminator shell on Windows, using Ubuntu/WSL and Xming window server.

Doing things manually from the shell, I can run Firefox, gedit, Terminator, etc on Windows, it's pretty cool.

So I checked the location of bash.exe using where bash and it returned...

C:\Windows\System32\bash.exe

However when I tried to run this code...

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();
}

I get the error...

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

And checking my entire system for bash.exe reveals it really be in another place altogether...

bash.exe location

I'm not sure if this location is one that I can rely on, I'm worried it's ephemeral and can change during a Windows Store update, although I may be wrong about that.

Why does the command prompt show bash.exe to be in System32 but it's really in another location altogether?

Can I get C# to also use the System32 location?

Upvotes: 11

Views: 6061

Answers (1)

Tono Nam
Tono Nam

Reputation: 36048

As @Biswapriyo stated first set the platafrom to x64 on your solution:

enter image description here

Then you may run on your ubuntu machine from c# as:

            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();

            }

Upvotes: 7

Related Questions