Allow cancel long running async executed commands

Add BreakRequestInfo for possible future support
This commit is contained in:
olegkap_cp
2011-11-22 20:09:42 +00:00
parent a0c40a5842
commit 148be6f50e
10 changed files with 142 additions and 32 deletions
@@ -295,6 +295,9 @@
<Compile Include="..\Renci.SshNet\Messages\Connection\ChannelOpen\X11ChannelOpenInfo.cs">
<Link>Messages\Connection\ChannelOpen\X11ChannelOpenInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Messages\Connection\ChannelRequest\BreakRequestInfo.cs">
<Link>Messages\Connection\ChannelRequest\BreakRequestInfo.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Messages\Connection\ChannelRequest\ChannelRequestMessage.cs">
<Link>Messages\Connection\ChannelRequest\ChannelRequestMessage.cs</Link>
</Compile>
@@ -712,7 +715,7 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
<UserProperties ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
<UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" />
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -196,14 +196,20 @@ namespace Renci.SshNet.Channels
this._session.Disconnected += Session_Disconnected;
}
/// <summary>
/// Sends the SSH_MSG_CHANNEL_EOF message.
/// </summary>
internal void SendEof()
{
// Send EOF message first when channel need to be closed
this.SendMessage(new ChannelEofMessage(this.RemoteChannelNumber));
}
/// <summary>
/// Closes the channel.
/// </summary>
public virtual void Close()
{
// Send EOF message first when channel need to be closed
this.SendMessage(new ChannelEofMessage(this.RemoteChannelNumber));
// Send message to close the channel on the server
this.SendMessage(new ChannelCloseMessage(this.RemoteChannelNumber));
@@ -137,6 +137,14 @@ namespace Renci.SshNet.Channels
throw exception;
}
public override void Close()
{
// Send EOF message first when channel need to be closed
this.SendMessage(new ChannelEofMessage(this.RemoteChannelNumber));
base.Close();
}
/// <summary>
/// Called when channel data is received.
/// </summary>
@@ -106,13 +106,19 @@ namespace Renci.SshNet.Channels
}
}
this.SendMessage(new ChannelEofMessage(this.RemoteChannelNumber));
this.Close();
}
partial void OpenSocket(string connectedHost, uint connectedPort);
public override void Close()
{
// Send EOF message first when channel need to be closed
this.SendMessage(new ChannelEofMessage(this.RemoteChannelNumber));
base.Close();
}
/// <summary>
/// Called when channel data is received.
/// </summary>
@@ -189,6 +189,22 @@ namespace Renci.SshNet.Channels
return this._channelRequestSucces;
}
/// <summary>
/// Sends the exec request.
/// </summary>
/// <param name="breakLength">Length of the break.</param>
/// <returns>true if request was successful; otherwise false.</returns>
public bool SendBreakRequest(uint breakLength)
{
this._channelRequestResponse.Reset();
this.SendMessage(new ChannelRequestMessage(this.RemoteChannelNumber, new BreakRequestInfo(breakLength)));
this._channelRequestResponse.WaitOne();
return this._channelRequestSucces;
}
/// <summary>
/// Sends the subsystem request.
/// </summary>
@@ -301,7 +317,6 @@ namespace Renci.SshNet.Channels
return this._channelRequestSucces;
}
/// <summary>
/// Called when channel request was successful
/// </summary>
@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Renci.SshNet.Messages.Connection
{
/// <summary>
/// Represents "break" type channel request information
/// </summary>
internal class BreakRequestInfo : RequestInfo
{
/// <summary>
/// Channel request name
/// </summary>
public const string NAME = "break";
/// <summary>
/// Gets the name of the request.
/// </summary>
/// <value>
/// The name of the request.
/// </value>
public override string RequestName
{
get { return BreakRequestInfo.NAME; }
}
/// <summary>
/// Gets break length in milliseconds.
/// </summary>
public UInt32 BreakLength { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="ExecRequestInfo"/> class.
/// </summary>
public BreakRequestInfo()
{
this.WantReply = true;
}
/// <summary>
/// Initializes a new instance of the <see cref="ExecRequestInfo"/> class.
/// </summary>
/// <param name="breakLength">Length of the break.</param>
public BreakRequestInfo(UInt32 breakLength)
: this()
{
this.BreakLength = breakLength;
}
/// <summary>
/// Called when type specific data need to be loaded.
/// </summary>
protected override void LoadData()
{
base.LoadData();
this.BreakLength = this.ReadUInt32();
}
/// <summary>
/// Called when type specific data need to be saved.
/// </summary>
protected override void SaveData()
{
base.SaveData();
this.Write(this.BreakLength);
}
}
}
@@ -154,6 +154,7 @@
<Compile Include="Messages\Connection\ChannelOpen\ForwardedTcpipChannelInfo.cs" />
<Compile Include="Messages\Connection\ChannelOpen\SessionChannelOpenInfo.cs" />
<Compile Include="Messages\Connection\ChannelOpen\X11ChannelOpenInfo.cs" />
<Compile Include="Messages\Connection\ChannelRequest\BreakRequestInfo.cs" />
<Compile Include="Messages\Connection\ChannelRequest\ChannelRequestMessage.cs" />
<Compile Include="Messages\Connection\ChannelRequest\EndOfWriteRequestInfo.cs" />
<Compile Include="Messages\Connection\ChannelRequest\EnvironmentVariableRequestInfo.cs" />
+6
View File
@@ -198,6 +198,8 @@ namespace Renci.SshNet
// If channel is open then close it to cause Channel_Closed method to be called
if (this._channel != null && this._channel.IsOpen)
{
this._channel.SendEof();
this._channel.Close();
}
}
@@ -245,7 +247,11 @@ namespace Renci.SshNet
}
if (this._channel.IsOpen)
{
this._channel.SendEof();
this._channel.Close();
}
this._channelClosedWaitHandle.Set();
+16 -25
View File
@@ -198,6 +198,7 @@ namespace Renci.SshNet
public IAsyncResult BeginExecute(string commandText, AsyncCallback callback, object state)
{
this.CommandText = commandText;
return BeginExecute(callback, state);
}
@@ -218,7 +219,12 @@ namespace Renci.SshNet
// Make sure that operation completed if not wait for it to finish
this.WaitHandle(this._asyncResult.AsyncWaitHandle);
this._channel.Close();
if (this._channel.IsOpen)
{
this._channel.SendEof();
this._channel.Close();
}
this._channel = null;
@@ -244,30 +250,15 @@ namespace Renci.SshNet
}
/// <summary>
/// Cancels command execution in asynchronous scenarios. CURRENTLY NOT IMPLEMENTED.
/// Cancels command execution in asynchronous scenarios.
/// </summary>
//public void Cancel()
//{
// if (this._channel != null && this._channel.IsOpen)
// {
// //this._channel.SendData(Encoding.ASCII.GetBytes("~."));
// this._channel.SendExecRequest("\0x03");
// //this._channel.SendSignalRequest("ABRT");
// //this._channel.SendSignalRequest("ALRM");
// //this._channel.SendSignalRequest("FPE");
// //this._channel.SendSignalRequest("HUP");
// //this._channel.SendSignalRequest("ILL");
// //this._channel.SendSignalRequest("INT");
// //this._channel.SendSignalRequest("PIPE");
// //this._channel.SendSignalRequest("QUIT");
// //this._channel.SendSignalRequest("SEGV");
// //this._channel.SendSignalRequest("TERM");
// //this._channel.SendSignalRequest("SEGV");
// //this._channel.SendSignalRequest("USR1");
// //this._channel.SendSignalRequest("USR2");
// }
//}
public void CancelAsync()
{
if (this._channel != null && this._channel.IsOpen && this._asyncResult != null)
{
this._channel.Close();
}
}
/// <summary>
/// Executes the specified command text.
@@ -279,6 +270,7 @@ namespace Renci.SshNet
public string Execute(string commandText)
{
this.CommandText = commandText;
return this.Execute();
}
@@ -385,7 +377,6 @@ namespace Renci.SshNet
if (this.OutputStream != null)
{
this.OutputStream.Write(e.Data, 0, e.Data.Length);
//this._outputSteamWriter.Write(this._encoding.GetString(e.Data, 0, e.Data.Length));
this.OutputStream.Flush();
}
@@ -90,6 +90,8 @@ namespace Renci.SshNet.Sftp
/// </summary>
public void Disconnect()
{
this._channel.SendEof();
this._channel.Close();
}