I would like to run a bash script using WSL from a WPF application. I have been using the Process.Start() method to try and run this script, passing some arguments along with it. I thought I had this function running perfectly before, however I am struggling to get the script to run on WSL.
Here is the code I have below, I can include the WSL script if needed. I need to run the WSL script and pass some arguments to the script from the command line.
string path = "\"" store.LPFolderPath "\"";
Debug.WriteLine(path);
Process p = new Process();
ProcessStartInfo info = new ProcessStartInfo
{
FileName = "cmd.exe",
RedirectStandardInput = true,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
};
p.StartInfo = info;
p.Start();
if(p.StandardInput.BaseStream.CanWrite)
{
p.StandardInput.WriteLine(@"wsl");
p.StandardInput.WriteLine(@"cd path/To/Script");
//"./lpass == scriptFile "//
p.StandardInput.WriteLine(@"./lpass " `ARG`);
p.StandardInput.WriteLine("exit");
p.StandardInput.Close();
};
p.WaitForExit();
From what I know this script does not run at all. Is there a mistake I am making utilizing Process
or how would I go about debugging this C# call in order to find out my error?
CodePudding user response:
This reminds me a bit of two questions I answered around using Python to launch WSL applications:
In your case, you are attempting to use standard input, but I think the issue is similar. The first WriteLine
launches WSL, but I believe it's now a separate process with its own standard input. The additional lines of standard input are probably going to the original process p
, but are probably just waiting there until the WSL process terminates, which doesn't happen until your parent process terminates. Disclaimer - I haven't tried this myself; I'm just basing it on past experience with other languages.
The solution should be the same as I mention in the other answers -- Use arguments to the wsl
command itself to call your script. E.g.:
p.StandardInput.WriteLine(@"wsl --cd path/To/Script -e bash -c lpass");
Or something similar. Try it from the command-line first:
wsl --cd path/To/Script -e bash -c lpass
The -e
tells it to run the Bash shell, with the -c
passing the ./lpass
directly to Bash. The --cd
is also a WSL argument which will set the initial starting directory, although it should be possible to move it into the Bash command as well:
wsl -e bash -c "cd path/To/Script; ./lpass"
If the lpass
script has a shebang line, you can even bypass calling Bash:
wsl --cd path/to/Script -e ./lpass