diff --git a/src/Renci.SshNet/SshCommand.cs b/src/Renci.SshNet/SshCommand.cs
index 37e91da08..288e778d3 100644
--- a/src/Renci.SshNet/SshCommand.cs
+++ b/src/Renci.SshNet/SshCommand.cs
@@ -195,6 +195,8 @@ public IAsyncResult BeginExecute(AsyncCallback callback)
///
/// An optional asynchronous callback, to be called when the command execution is complete.
/// A user-provided object that distinguishes this particular asynchronous read request from other requests.
+ /// A stream to be used as the output stream.
+ /// A stream to be used as the extended output stream.
///
/// An that represents the asynchronous command execution, which could still be pending.
///
@@ -205,7 +207,7 @@ public IAsyncResult BeginExecute(AsyncCallback callback)
/// Operation has timed out.
/// Asynchronous operation is already in progress.
/// CommandText property is empty.
- public IAsyncResult BeginExecute(AsyncCallback callback, object state)
+ public IAsyncResult BeginExecute(AsyncCallback callback, object state, Stream stdout = null, Stream stderr = null)
{
// Prevent from executing BeginExecute before calling EndExecute
if (_asyncResult != null && !_asyncResult.EndCalled)
@@ -245,8 +247,8 @@ public IAsyncResult BeginExecute(AsyncCallback callback, object state)
}
// Initialize output streams
- OutputStream = new PipeStream();
- ExtendedOutputStream = new PipeStream();
+ OutputStream = (stdout == null ? new PipeStream() : stdout);
+ ExtendedOutputStream = (stderr == null ? new PipeStream() : stderr);
_result = null;
_error = null;
@@ -307,6 +309,9 @@ public string EndExecute(IAsyncResult asyncResult)
throw new ArgumentException("EndExecute can only be called once for each asynchronous operation.");
}
+ // always send EOF when closing exec channel
+ _channel.SendEof();
+
// wait for operation to complete (or time out)
WaitOnHandle(_asyncResult.AsyncWaitHandle);
@@ -514,6 +519,44 @@ private void UnsubscribeFromEventsAndDisposeChannel(IChannel channel)
channel.Dispose();
}
+ ///
+ /// Sends the data to channel.
+ ///
+ /// Data.
+ public void SendData(byte[] data)
+ {
+ SendData(data, 0, data.Length);
+ }
+
+ ///
+ /// Sends the data with offset and size to channel.
+ ///
+ /// Data.
+ /// Offset.
+ /// Size.
+ public void SendData(byte[] data, int offset, int size)
+ {
+ _channel.SendData(data, offset, size);
+ }
+
+ ///
+ /// Sends the data to channel.
+ ///
+ /// Data.
+ public void SendData(Stream data)
+ {
+ if (data == null)
+ return;
+
+ byte[] buffer = new byte[2048]; // read in chunks of 2KB
+ int bytesRead;
+
+ while ((bytesRead = data.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ _channel.SendData(buffer, 0, bytesRead);
+ }
+ }
+
#region IDisposable Members
private bool _isDisposed;