S
Instead of using the object StreamReader returned by the property Process.StandardOutput ( https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.standardoutput ), to synchronously capture the process output you fired, you could use the event Process.OutputDataReceived ( https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.outputdatareceived ) to capture asynchronously the output of the fired process.To do this you need to pass a event handler, with the signature of DataReceivedEventHandler Delegate ( https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.datareceivedeventhandler ) for the event Process.OutputDataReceived.How you are using MessageBox.Show(), I imagine you're using Windows Forms, and in that case I suggest you display the process output fired in one TextBox, instead of displaying it with MessageBox. For this it is important to pass the reference of your Form for the property Process.SynchronizingObject ( https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.synchronizingobject ), otherwise your event handler will run on a different thread of your GUI thread, and would make error if you tried to access your TextBox from inside event handler.The code would look like this:private void OpenCliente()
{
Process processo = new Process();
processo.StartInfo.WorkingDirectory = Application.StartupPath + @"\Debug";
processo.StartInfo.FileName = @"app.exe";
processo.StartInfo.Arguments = "args";
processo.StartInfo.Verb = "runas";
processo.StartInfo.LoadUserProfile = true;
processo.StartInfo.UseShellExecute = false;
processo.StartInfo.CreateNoWindow = true;
processo.StartInfo.RedirectStandardOutput = true;
processo.StartInfo.ErrorDialog = true;
//processo.EnableRaisingEvents = true;
processo.SynchronizingObject = this;
processo.OutputDataReceived += (sender, e) => {
if (!String.IsNullOrEmpty(e.Data))
{
txtConsole.Text += e.Data + Environment.NewLine;
}
};
processo.Start();
// Dá início ao processo de leitura do output, e a partir
// daqui o event handler será disparado a cada linha do output.
processo.BeginOutputReadLine();
processo.WaitForExit();
}
But I also researched this braking problem you reported, and found a response in the SOEN in which the author said that this probably occurs because the output is very large and exceeds the capacity of the internal buffer: https://stackoverflow.com/a/7608823/8133067 EDITION 1I researched the subject a little more, and, looking at the source of the class Process ( https://referencesource.microsoft.com/#System/services/monitoring/system/diagnosticts/Process.cs,2159 ) I could see that the object StreamReader created for the property Process.StandardOutput has one buffer internal with equal size 4096, i.e. 4 KB:if (startInfo.RedirectStandardOutput) {
Encoding enc = (startInfo.StandardOutputEncoding != null) ? startInfo.StandardOutputEncoding : Console.OutputEncoding;
standardOutput = new StreamReader(new FileStream(standardOutputReadPipeHandle, FileAccess.Read, 4096, false), enc, true, 4096);
}
So when the result that would be displayed on screen by the application fired by its application exceeds 4 KB, the internal output buffer gets full, and apparently that's what's causing the locking of your application.EDITION 2As a test, you could open a Command Prompt (cmd.exe) and run this application by the command line that you fire from your program, with the same arguments, redirecting the output to a text file:C:\PastaSuaApp\Debug>app.exe args > app_saida.txt
In this way you could check what size of the text file created, and could check if this 4 KB theory is true. Also take a test with arguments that you know do not crash your program, to see if the output was below 4 KB.EDITION 3I forgot to comment that if it is not possible to put a TextBox to display target application output result in real-time, it is also possible to play the output result for one StringBuilder, as in the example of event documentation Process.OutputDataReceived, and show this result at the end, the way you were doing:using System.Text;
//[...]
private StringBuilder output = new StringBuilder();
private void OpenCliente()
{
Process processo = new Process();
processo.StartInfo.WorkingDirectory = Application.StartupPath + @"\Debug";
processo.StartInfo.FileName = @"app.exe";
processo.StartInfo.Arguments = "args";
processo.StartInfo.Verb = "runas";
processo.StartInfo.LoadUserProfile = true;
processo.StartInfo.UseShellExecute = false;
processo.StartInfo.CreateNoWindow = true;
processo.StartInfo.RedirectStandardOutput = true;
processo.StartInfo.ErrorDialog = true;
processo.OutputDataReceived += (sender, e) => {
if (!String.IsNullOrEmpty(e.Data))
{
output.Append(e.Data + Environment.NewLine);
}
};
processo.Start();
// Dá início ao processo de leitura do output, e a partir
// daqui o event handler será disparado a cada linha do output.
processo.BeginOutputReadLine();
processo.WaitForExit();
MessageBox.Show(output.ToString());
}
EDITION 4The author reported that when running the third-party program using the solution I suggested, from asynchronous redirect of the output, nothing was displayed, but that when the program was run directly on the console, the output was displayed normally, but also that when doing a redirect on the console using app.exe args > app_saida.txt, nothing was recorded in the text file.I thought https://stackoverflow.com/q/7990851/8133067 in the SOen in which the author had a problem very similar to this in question, and a user https://stackoverflow.com/q/7990851/#comment9813069_7990851 that could simply be a bug in the program and asked if the author contacted the provider of the program. The author later https://stackoverflow.com/q/7990851/#comment26961093_8621612 that was a bug in the program, admitted by the vendor, after contact. So, if there's a possibility of contacting the supplier, maybe it's a way out.But another way I thought to solve the problem would simply start the process using the shell the operating system itself, through ownership https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.useshellexecute and leaving to create a window for the process, with the property https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.createnowindow .An example of code:var p = new Process();
p.StartInfo.FileName = "ping.exe";
p.StartInfo.Arguments = "pt.stackoverflow.com";
p.StartInfo.UseShellExecute = true;
p.StartInfo.CreateNoWindow = false;
p.Start();
p.WaitForExit();
If you want the screen to be displayed for a while after the end of the process, you can add time in milliseconds as an argument in the method WaitForExit().But if you need the console screen to open until the user closes it, you can run the command cmd.exe /k <linha-de-comando>, the only problem is that at the end of the process the console will be available for the user to interact:var p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/k ping.exe pt.stackoverflow.com";
p.StartInfo.UseShellExecute = true;
p.StartInfo.CreateNoWindow = false;
p.Start();
p.WaitForExit();