I have a Windows Service that is going to process results from plink.exe (Putty/SSH thing). I'm currently successfully capturing the standard output and sending commands via the standard input to the process.
My problem is, the OutputDataReceived
event doesn't seem to get raised until I receive a line break from the console application process. The process prompts for a password and there isn't a line break until after I input a password.
So my question is, is there a way to process the Standard Output character-by-character, instead of line-by-line from the System.Diagnostics.Process
class?
Here is my code:
_processInfoTest = new ProcessStartInfo();
_processInfoTest.FileName = serviceSettings.PlinkExecutable;
_processInfoTest.Arguments = GetPlinkArguments(serviceSettings);
_processInfoTest.RedirectStandardOutput = true;
_processInfoTest.RedirectStandardError = true;
_processInfoTest.RedirectStandardInput = true;
_processInfoTest.UseShellExecute = false;
_processInfoTest.CreateNoWindow = true;
_processTest = new Process();
_processTest.StartInfo = _processInfoTest;
_processTest.OutputDataReceived += processTest_OutputDataReceived;
_processTest.ErrorDataReceived += processTest_OutputDataReceived;
_processTest.Start();
_processTest.BeginOutputReadLine();
_processTest.BeginErrorReadLine();
And the event handler that handles the incoming lines of text:
private static void processTest_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
string line = e.Data;
if (line != null)
{
WcfServerHelper.BroadcastRemoteCallback(x => x.PlinkTextOutput(line, DateTime.Now));
if (line.Contains("If you do not trust this host, press Return to abandon the"))
{
_processTest.StandardInput.Write("y");
_processTest.StandardInput.Write("\n");
_processTest.StandardInput.Flush();
}
// This code never gets called because the event doesn't get raised until a line-break occurs
if (line.Contains("'s password:"))
{
_processTest.StandardInput.Write("mypassword");
_processTest.StandardInput.Write("\n");
_processTest.StandardInput.Flush();
}
if (line.Contains("Access granted"))
{
if (!_processTest.HasExited)
_processTest.Kill();
WcfServerHelper.BroadcastRemoteCallback(x => x.TestConnectionCallback(PlinkStatus.Success));
}
else if (line.Contains("Access denied") || line.Contains("Password authentication failed"))
{
if (!_processTest.HasExited)
_processTest.Kill();
WcfServerHelper.BroadcastRemoteCallback(x => x.TestConnectionCallback(PlinkStatus.InvalidUserOrPass));
}
else if (line.Contains("Host does not exist"))
{
if (!_processTest.HasExited)
_processTest.Kill();
WcfServerHelper.BroadcastRemoteCallback(x => x.TestConnectionCallback(PlinkStatus.InvalidHostname));
}
else if (line.Contains("Connection timed out"))
{
if (!_processTest.HasExited)
_processTest.Kill();
WcfServerHelper.BroadcastRemoteCallback(x => x.TestConnectionCallback(PlinkStatus.TimedOut));
}
}
}
Thank you!