I am trying to run a python program in Ubuntu using wsl. I need to access Windows Terminal from C# application and execute commands in wsl. I am able to open the Windows Terminal. But cannot programmatically execute multiple commands after it.
I tried the below code. But the StandardInput.WriteLine is not working as I expected.
StartInfo = new ProcessStartInfo
{
FileName = #"wt.exe",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
CreateNoWindow = false,
Arguments = "wsl"
}
})
{
proc.Start();
proc.BeginOutputReadLine();
proc.StandardInput.WriteLine("cd Ubuntu/MyProject");
proc.StandardInput.WriteLine("python3 MyProgram.py ABC.wav");
}
Related
This is supposed to be simple but I don't understand why it's not working. I'm trying to run a batch file (that runs a console application) from a .NET 6.0 Windows Service with this content:
#echo off
cd "C:\MyFolder"
MyExecutable.exe
pause
and I have this code:
var command = "\"C:\\Users\\Administrator\\Desktop\\mybatchfile.bat\"";
ProcessStartInfo start = new()
{
FileName = "cmd.exe",
Arguments = $"/c {command}",
UseShellExecute = false,
CreateNoWindow = false,
ErrorDialog = false,
RedirectStandardError = false,
RedirectStandardOutput = false,
WindowStyle = ProcessWindowStyle.Normal
};
Process.Start(start);
What's happening is that my console application (MyExecutable.exe) is executed, yet I do not see the Command window for it. It's launched in the background despite CreateNoWindow set to false and WindowStyle set to ProcessWindowStyle.Normal.
I am writing a code to execute some commands against wsl, parsing and reading the returned value is important.
Project is a .net core console app 3.1
wsl2 is enabled on the system
for example, listing all the available wsl images on my local machine i am using a snippet found in an answer provided in another "kind of related" SO post.
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 --list");
System.Threading.Thread.Sleep(500);
proc.StandardInput.Flush();
proc.StandardInput.Close();
proc.WaitForExit(5000);
var c = proc.StandardOutput.ReadToEnd();
Console.WriteLine(c);
Console.ReadLine();
}
now the expected output should be
what i am getting is
if i inspect using breakpoint i get this in "var c"
Ideally i want to be able to have a list that contains the 2 dockers items inside C#, changing the wait time didn't help.
in the ProcessStartInfo you have to set
StandardOutputEncoding = Encoding.Unicode;
StandardErrorEncoding = Encoding.Unicode;
for direct call of wsl use additionally:
FileName = #"wsl.exe";
Arguments = #"-l -v";
I'm trying to popup a dialog with some questions from a local network server
and receive the users answers, something like a winforms window, using c#.
Are there any recommendations for a way of doing this?
The solution I found was using PsExec tools.
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "path of psExec",
Arguments = $"psexec -i -s \\\\{machineName} {path}",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
proc.WaitForExit();`
I am trying to automate the machine setup using net core 2.0 with a console application, and I need to run some nvm commands to configure node versions.
I am trying to run a .bat file with the nvm commands that I need, but I am getting the following error:
This file does not have a program associated with it for performing this action. Please install a program or, if one is already installed, create an association in the Default Programs control panel.
If I execute the .bat file directly from cmd it works ok, but when my console app run it I get this error.
The 'file.bat' commands are:
nvm version
nvm install 6.11.4
nvm use 6.11.4
nvm list
npm --version
My csharp function to run the command:
public static int ExecuteCommand()
{
int exitCode;
ProcessStartInfo processInfo;
Process process;
processInfo = new ProcessStartInfo("cmd.exe", $"/C file.bat")
{
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true
};
process = Process.Start(processInfo);
process.OutputDataReceived += (s, e) =>
{
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.WriteLine("cmd >" + e.Data);
Console.ResetColor();
};
process.BeginOutputReadLine();
process.ErrorDataReceived += (s, e) =>
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(e.Data);
Console.ResetColor();
};
process.BeginErrorReadLine();
process.WaitForExit();
exitCode = process.ExitCode;
Console.WriteLine("ExitCode: " + exitCode.ToString(), "ExecuteCommand");
process.Close();
return exitCode;
}
My expectation is to have this working, because after that I will need to run several other commands, like npm install, gulp install, etc.
Any idea of what could be happening?
Based purely on testing, if you change this section:
processInfo = new ProcessStartInfo("cmd.exe", $"/C file.bat")
{
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true
};
to not use the constructor arguments and instead manually set parameters like:
processInfo = new ProcessStartInfo()
{
FileName = "cmd.exe",
Arguments = $"/C file.bat",
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true
};
should do the trick. Not sure on why, since from github code on ProcessStartInfo the constructor merely receives arguments and stores them on respective properties (FileName and Arguments).
I'm trying to run automated installations via CMD commands. The programs output progress and I need to capture that output and calculate total progress in a nice window. In my understanding it is impossible to elevate and redirect at the same time. I've tried...
Running cmd elevated and feeding it commands.
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Verb = "runas",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
CreateNoWindow = true
}
};
proc.Start();
proc.StandardInput.WriteLine("command");
Running cmd with command as an argument
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/C " + "command",
Verb = "runas",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
CreateNoWindow = true
}
};
proc.Start();
To no effect. Is there any tricks to this? Elevating after input/output has been captured? I need this to work. Would this be possible with psexec?
If you own the installer programs, you can rewrite them so that they do not use standard streams as a means of communication, but for example named pipes. If you don't, you can write a wrapper program that runs elevated (you run it with UseShellExecute), does not use the standard streams, but runs the installer programs and redirects their input (you run them without UseShellExecute) reporting progress to the nonelevated main program via named pipes or some other means. I hope this diagram makes it clearer:
non-elevated.exe
\
\ named pipes
\
elevated-wrapper.exe (ran with UseShellExecute=true)
\
\ redirected standard streams
\
installer-program.exe (ran with UseShellExecute=false and redirected streams)