Get exitcode from Process via arguments - c#

Im trying to start CMD process from my program that starts another process that redirect output and errors into file. And I have to have exit code of this process.
var exe = pathToExe
var output = Path.GetTempFileName();
var process = Process.Start(new ProcessStartInfo
{
FileName = "cmd",
Arguments = $"/c "{exe} {command} > {output} 2<&1" & echo %errorlevel% > {output})",
Verb = "runas",
UseShellExecute = true,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden
});
process.WaitForExit();
var res = File.ReadAllText(output);
Console.WriteLine(res);
Same command (cmd /c "pathToExe command > output 2<&1" & echo %errorlevel% > output) worked fine in cmd, but in this code is errorlevel always 0 (I suggest its just errorlevel of cmd process)
At this point you may ask me why am I even using cmd to start process... Well, Ive tried
using (var process = CreateProcess(processName, argumnets))
{
var error = 0;
var output = Path.GetTempFileName();
process.StartInfo.UseShellExecute = true;
process.StartInfo.Verb = "runas";
process.StartInfo.Arguments = $"{command} > {output} 2<&1";
process.Start();
process.WaitForExit();
statusInfo = File.ReadAllText(output);
File.Delete(output);
if (process.ExitCode != 0)
{
error = process.ExitCode;
}
return error;
}
But it didnt work for me.
Also i cant redirect outputrs programmatically because of process.StartInfo.UseShellExecute.

Related

How to run multiple cmd commands without reopening cmd in C#?

This is my code and I'm using it in a while loop.
The cmd command changes every time. It means if I write "cd .." and in the next round of while loop if I write "dir" that's not gonna give me the previous folder items or in simpler language previous cmd closed and another one opens.
while (i < 99) {
System.Diagnostics.Process process = new
System.Diagnostics.Process();
process.StartInfo.WindowStyle =
System.Diagnostics.ProcessWindowStyle.Hidden;
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = #"/C " + lastMsg; //this line is a cmd command
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
process.Start();
string q = "";
while (!process.HasExited)
{
q += process.StandardOutput.ReadToEnd();
}
}
If you want to send all commands to the same instance of cmd, you must create this instance outside your loop, redirect the standard input, and send the commands through the standard input:
var cmdStartInfo = new ProcessStartInfo
{
FileName = "cmd",
RedirectStandardInput = true,
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true
};
var cmdProcess = Process.Start(cmdStartInfo);
while (i < 99)
{
cmdProcess.StandardInput.WriteLine(lastMsg);
}

How to open Ubuntu's bash.exe shell using C# on Windows?

as described in the title, I wanna open up the ubuntu-shell on my windows pc, passing a
"cd /mnt/c/users/xyz/desktop" to it then passing a
"python3 some_script.py arg1, arg2" to it
all this works wonderful if done manually via mouseclicks but from code (see below:)
it doesnt write anything to the console which opens.
string ExecuteCommand(string command)
{
// Execute wsl command:
var StartInfo = new ProcessStartInfo
{
FileName = #"bash.exe",
WorkingDirectory = #"C:\Windows\System32",
//Arguments = "/c " + "root#DESKTOP-OUTEVME:~#",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
CreateNoWindow = false,
WindowStyle = ProcessWindowStyle.Normal,
};
using (var process = Process.Start(StartInfo))
{
process.StandardInput.WriteLine();
process.EnableRaisingEvents = true;
process.OutputDataReceived += (s, e) => MessageBox.Show(e.Data);
process.BeginOutputReadLine();
process.StandardInput.WriteLine(command);
process.StandardInput.WriteLine("exit");
process.WaitForExit();
//result = process.StandardOutput.ReadToEndAsync().Result;
}
return result;
}
return ExecuteCommand(#"wsl cd /mnt/c/users/shho3/desktop");
Anyone maybe an idea what I could do wrong?
Much thanks!
You could pass everything in the command line instead of piping into the process. I think it would save you a lot of trouble. Try bash.exe -c "cd /mnt/c/Users/shho3/Desktop; python some_script.py arg1 arg2":
Process.Start("bash.exe", "-c \"cd /mnt/c/Users/shho3/Desktop; python some_script.py arg1 arg2\"").WaitForExit()
Alternatively you can also just set the working directory to C:\Users\shho3\Desktop (instead of C:\Windows\System32) and call bash.exe -c "python some_script.py arg1 arg2", then you don't even have to convert the path:
Process.Start(new ProcessStartInfo("bash.exe", "-c \"python some_script.py arg1 arg2\"") {
WorkingDirectory = "C:\\Users\\ssho3\\Desktop"
}).WaitForExit()

Input to processes (batch files)

I'm trying to make some kind of app, in C# Windows Forms Application (not console one, with tab pages, configuration, and console as a list box).
My problem is, that when I am writing some kind of input (to the text box), nothing happens (I'm new to coding).
My code:
Process process = new Process
{
StartInfo =
{
FileName = textBox2.Text,
//Arguments = textBox3.Text,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
CreateNoWindow = false,
}
};
server = process;
process.Start();
...
/* LATER */
...
serverInput = process.StandardInput;
...
serverInput.Write(textBoxInput.Text);
UPDATE - SOLVED: code:
serverInput.WriteLine(...);
Method 1:
This will be enough to run a batch files present in a directory:
string[] arrBatFiles = Directory.GetFiles(textBox2.Text, "*.bat"); //search at directory path
//loop through all batch files
foreach(string sFile in arrBatFiles)
{
Process.Start(sFile);
}
Method 2:
If you want to use ProcessStartInfo members, use following method:
public void ExecuteCommand(string sBatchFile, string command)
{
int ExitCode;
ProcessStartInfo ProcessInfo;
Process process;
string sBatchFilePath = textBox2.Text; //batch file Path
ProcessInfo = new ProcessStartInfo(sBatchFile, command);
ProcessInfo.CreateNoWindow = false;
ProcessInfo.UseShellExecute = false;
ProcessInfo.WorkingDirectory = Path.GetDirectoryName(sBatchFile);
// *** Redirect the output ***
ProcessInfo.RedirectStandardError = true;
ProcessInfo.RedirectStandardOutput = true;
process = Process.Start(ProcessInfo);
process.WaitForExit();
// *** Read the streams ***
string sInput = process.StardardInput.ReadToEnd();
string sOutput = process.StandardOutput.ReadToEnd();
string sError = process.StandardError.ReadToEnd();
ExitCode = process.ExitCode;
}
UPDATE:
How to call when you have directory of batch files.
string[] arrBatFiles = Directory.GetFiles(textBox2.Text, "*.bat"); //search at directory path
//loop through all batch files
foreach(string sFile in arrBatFiles)
{
ExecuteCommand(sFile, string.Empty); //string.Empty refer optional command args
}

Run Bash Commands from Mono C#

I am trying to make a directory using this code to see if the code is executing but for some reason it executes with no error but the directory is never made. Is there and error in my code somewhere?
var startInfo = new
var startinfo = new ProcessStartInfo();
startinfo.WorkingDirectory = "/home";
proc.StartInfo.FileName = "/bin/bash";
proc.StartInfo.Arguments = "-c cd Desktop && mkdir hey";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start ();
Console.WriteLine ("Shell has been executed!");
Console.ReadLine();
This works best for me because now I do not have to worry about escaping quotes etc...
using System;
using System.Diagnostics;
class HelloWorld
{
static void Main()
{
// lets say we want to run this command:
// t=$(echo 'this is a test'); echo "$t" | grep -o 'is a'
var output = ExecuteBashCommand("t=$(echo 'this is a test'); echo \"$t\" | grep -o 'is a'");
// output the result
Console.WriteLine(output);
}
static string ExecuteBashCommand(string command)
{
// according to: https://stackoverflow.com/a/15262019/637142
// thans to this we will pass everything as one command
command = command.Replace("\"","\"\"");
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "/bin/bash",
Arguments = "-c \""+ command + "\"",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
proc.WaitForExit();
return proc.StandardOutput.ReadToEnd();
}
}
This works for me:
Process.Start("/bin/bash", "-c \"echo 'Hello World!'\"");
My guess is that your working directory is not where you expect it to be.
See here for more information on the working directory of Process.Start()
also your command seems wrong, use && to execute multiple commands:
proc.StartInfo.Arguments = "-c cd Desktop && mkdir hey";
Thirdly you are setting your working directory wrongly:
proc.StartInfo.WorkingDirectory = "/home";

c# run command not executing the command

I want to run this:
string command = "echo test > test.txt";
System.Diagnostics.Process.Start("cmd.exe", command);
It's not working, what am I doing wrong?
You are missing to pass the /C switch to cmd.exe to indicate that you want to execute a command. Also notice that the command is put in double quotes:
string command = "/C \"echo test > test.txt\"";
System.Diagnostics.Process.Start("cmd.exe", command).WaitForExit();
And if you don't want to see the shell window you could use the following:
string command = "/C \"echo test > test.txt\"";
var psi = new ProcessStartInfo("cmd.exe")
{
Arguments = command,
UseShellExecute = false,
CreateNoWindow = true
};
using (var process = Process.Start(psi))
{
process.WaitForExit();
}
This should sort of get you started:
//create your command
string cmd = string.Format(#"/c echo Hello World > mydata.txt");
//prepare how you want to execute cmd.exe
ProcessStartInfo psi = new ProcessStartInfo("cmd.exe");
psi.Arguments = cmd;//<<pass in your command
//this will make echo's and any outputs accessiblen on the output stream
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
Process p = Process.Start(psi);
//read the output our command generated
string result = p.StandardOutput.ReadToEnd();

Categories

Resources