public void Start()
{
if (IsStarted)
{
throw new SshException("Shell is started.");
}
if (Starting != null)
{
Starting(this, new EventArgs());
}
_channel = _session.CreateChannelSession();
_channel.DataReceived += Channel_DataReceived;
_channel.ExtendedDataReceived += Channel_ExtendedDataReceived;
_channel.Closed += Channel_Closed;
_session.Disconnected += Session_Disconnected;
_session.ErrorOccured += Session_ErrorOccured;
_channel.Open();
_channel.SendPseudoTerminalRequest(_terminalName, _columns, _rows, _width, _height, _terminalModes);
_channel.SendShellRequest();
_channelClosedWaitHandle = new AutoResetEvent(false);
// Start input stream listener
_dataReaderTaskCompleted = new ManualResetEvent(false);
ThreadAbstraction.ExecuteThread(() =>
{
try
{
var buffer = new byte[_bufferSize];
while (_channel.IsOpen)
{
#if FEATURE_STREAM_TAP
var readTask = _input.ReadAsync(buffer, 0, buffer.Length);
var readWaitHandle = ((IAsyncResult) readTask).AsyncWaitHandle;
if (WaitHandle.WaitAny(new[] {readWaitHandle, _channelClosedWaitHandle}) == 0)
{
var read = readTask.Result;
_channel.SendData(buffer, 0, read);
continue;
}
#elif FEATURE_STREAM_APM
var asyncResult = _input.BeginRead(buffer, 0, buffer.Length, result =>
{
// If input stream is closed and disposed already don't finish reading the stream
if (_input == null)
return;
var read = _input.EndRead(result);
_channel.SendData(buffer, 0, read);
}, null);
WaitHandle.WaitAny(new[] { asyncResult.AsyncWaitHandle, _channelClosedWaitHandle });
if (asyncResult.IsCompleted)
continue;
#else
#error Async receive is not implemented.
#endif
break;
}
}
catch (Exception exp)
{
RaiseError(new ExceptionEventArgs(exp));
}
finally
{
_dataReaderTaskCompleted.Set();
}
});
IsStarted = true;
if (Started != null)
{
Started(this, new EventArgs());
}
}