C# Read text (output?) from console that runs as a Process - c#

I'm trying to check if username and password for git repository is valid. In console I run:
git clone http://username:password#server/test.git
And I get:
fatal: Authentication failed for ...
So now I know username and password are not valid. I'm trying to run this command as a process:
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "git.exe",
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
WorkingDirectory = "some_directory"
CreateNoWindow = true,
Arguments = "git clone http://username:password#server/test.git"
},
};
process.Start();
I'd like to access the result of this command. Both process.StandardError and process.StandardOutput are equals string.Empty. Is there any way to read the result?

Normally you should read the exit code of the process.
process.ExitCode
If the process failed, the return value should be non 0. Of course you can only retrieve the exit code after the process completes.
So:
if (process.ExitCode != 0)
//error
Please note: I haven't tested it but it is standard convention.
To read the output, one normally uses:
string output = process.StandardOutput.ReadToEnd();
string err = process.StandardError.ReadToEnd();
Console.WriteLine(output);
Console.WriteLine(err);

What you really need is your standard output, which can be accessed as below:
string stdout = p.StandardOutput.ReadToEnd();
and use p.WaitForExit(); right after because sometimes it takes a while to give error message.

Related

How to write a command to cmd.exe when using ProcessStartInfo

I have some script files that would usually be edited and run through a ui, but the offer to run on the command line when using the syntax: program.exe scriptfile.fmw --userparameter "some parameter".
If I simply write
arguments = "program.exe scriptfile.fmw --userparameter \"some parameter\"";
Process process = Process.Start("cmd.exe", $"/K {arguments};
process.WaitForExit();
the commandline starts, calls the correct exe and runs the script.
Now I want to retrieve the response of the script after it ran to catch possible error messages.
As far as I can see this requires to use ProcessStartInfo and that's basically where my problem seems to start.
ProcessStartInfo startInfo = new ProcessStartInfo()
{
FileName = "cmd.exe",
Arguments = $"/K {arguments}",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
};
Process process = Process.Start(startInfo);
process.BeginErrorReadLine();
process.WaitForExit();
The code above opens a commandline window, but never uses the arguments given.
It escapes me on how I should hand the argument line over to the cmd.exe - process.
I was playing around with RedirectStandardInput and its StreamWriter, but never managed to get anything written into the cmd-window.
The same goes for the RedirectStandardOutput, where I would like to gather the script response in the cmd-window as a string or string[], to parse for specific exit codes of the script.
I think this is what you want, have a look below :
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo()
{
FileName = "program.exe", //You must use your program directly without invoking through cmd.exe
Arguments = "scriptfile.fmw --userparameter \"some parameter\"", //Add parameters and arguments here needed by your application
UseShellExecute = false,
EnableRaisingEvents = true, //You are missing this
RedirectStandardOutput = true,
RedirectStandardError = true
};
process.ErrorDataReceived += process_ErrorDataReceived; //You should listen to its output error data by subscribing to this event
process.BeginErrorReadLine();
process.Start(startInfo);
process.WaitForExit(); // You may now avoid this
Then at here do anything with your received error data!
private static void process_ErrorDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
DoSomething(e.Data); // Handle your error data here
}
EDIT-(1) : Please try this solution and ping me if it works or if you need some extra help. Everyone in comments is suggesting that you must not use cmd.exe to invoke your program as it may causes debugging overhead, performance issue and you might not get error details as well.
Cheers!

Read output from console dialog box

I want to get output text from the external process that runs the application and this application displays something that looks like a console dialog box like in the screenshot below:
I tried to get output via StandardOutput:
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = pathToExeFile,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
},
};
process.Start();
var output = process.StandardOutput.ReadToEnd();
var err = process.StandardError.ReadToEnd();
process.WaitForExit();
But in this case both output and err variables have null values only. I assume that this is because the output from the app is not available via stdout but from something which looks like a dialogbox/messagebox. Is there any way to get this output?

Start process with IO stream redirection

How to start process and run command like this:
mysql -u root --password="some-password" < "some-file.sql"
Is it possible to do with process.Start()?
I need cross-platform solution (we cannot use cmd.exe).
Yes, this is possible through the System.Diagnostics.Process class. You need to set RedirectStandardInput to true, after which you can write the content of a file redirect the standard input of a process, and write the contents of the file to the Process.StandardInput (which is a StreamWriter)
This should get you started:
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "mysql.exe", // assumes mysql.exe is in PATH
Arguments = "-u root --password=\"some-password\"",
RedirectStandardInput = true,
UseShellExecute = false
},
};
process.Start();
process.StandardInput.Write(File.ReadAllText("some-file.sql"));
Update: this is pretty well documented [here](
https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.redirectstandardinput)

How to run the exe from a different folder using ProcessStartInfo?

I have a program under c:\windows\system32\csexport.exe . If I open a cmd window, and run the command, it works fine and generate an output file under c:\windows\system32\csexport
However, if I use File.Exists(file), it will always return false because of some security reason. So, I open a cmd window, then go to c:\tmp folder, then run the csexport.exe with full path, then it will output the file in c:\tmp .
So I try to do this in C#. Here is the code
public ProcessResult RunProcess(string fileName, string arguments, string workingDirectory)
{
var processResult = new ProcessResult();
// prep process
var psi = new ProcessStartInfo(fileName, arguments)
{
UseShellExecute = true,
RedirectStandardOutput = true,
RedirectStandardError = true
, WorkingDirectory = workingDirectory
};
// start process
using (var process = new System.Diagnostics.Process())
{ // pass process data
process.StartInfo = psi;
process.Start();
processResult.Data = process.StandardOutput.ReadToEnd();
process.WaitForExit();
processResult.ExitCode = process.ExitCode;
}
return processResult;
}
But, how can I set it to run from c:\tmp ?
I did more test, and had weird result:
I set UseShellExecute = false, and then set workingDirectory = "C:\tmp", the filename with full path. when run it, it shows this error:
The following exception occurred: System.InvalidOperationException: The Process object must have the UseShellExecute property set to false in order to redirect IO streams.
at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start()
at ENow.Os.Utilities.ProcessWrapper.RunProcess(String fileName, String arguments, String workingDirectory)
...
But, UseShellExecute is set as false already.

Output data is not full

I need some help. I have a external app (test.exe with some dll files). In cmd i have run command like this: test.exe parmeters and get a lot of data with some needed info.
I have write app which execute this external app and output is not fully as I exec it with cmd. It's just some firstly lines. I don't mind whats wrong. Please help
using(var process = new Process {
StartInfo = new ProcessStartInfo {
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
FileName = orPath,
Arguments = parmeters.ToString(),
}
}) {
process.Start();
process.WaitForExit();
string result = "";
string standard_output;
while ((standard_output = process.StandardOutput.ReadLine()) != null) {
if (standard_output.Contains("xx"))
result = standard_output.Substring(standard_output.Length - 15);
}
Without a concise-but-complete code example that reliably demonstrates the problem, it's hard to say for sure. But it doesn't surprise me that if you try to consume StandardOutput after you have already called WaitForExit(), that not all of the output has been buffered and is available.
Maybe try this instead:
process.Start();
string result = "";
string standard_output;
while ((standard_output = process.StandardOutput.ReadLine())
!= null)
{
if (standard_output.Contains("xx"))
result = standard_output.Substring(
standard_output.Length - 15);
}
Note that I've simply removed the call to WaitForExit(). Reading the StandardOutput TextReader until it returns null will have the same effect as waiting for the end of the process, assuming a normal process (i.e. where the stdout doesn't get closed until the process exits).

Categories