Merge branch 'develop' of https://github.com/mRemoteNG/mRemoteNG into develop

This commit is contained in:
Faryan Rezagholi
2019-10-01 09:31:36 +02:00
2 changed files with 363 additions and 316 deletions

View File

@@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### Fixed
- #1595: Unhandled exception when trying to browse through non existent multi ssh history with keyboard key strokes
- #1337: Unhandled exception after closing mRemoteNG
- #359: Making a VNC connection to an unreachable host causes the application to not respond for 20-30 seconds
## [1.77.1] - 2019-09-02
### Added

View File

@@ -1,316 +1,362 @@
using System;
using System.ComponentModel;
using mRemoteNG.App;
using mRemoteNG.Tools;
using mRemoteNG.UI.Forms;
// ReSharper disable ArrangeAccessorOwnerBody
namespace mRemoteNG.Connection.Protocol.VNC
{
public class ProtocolVNC : ProtocolBase, ISupportsViewOnly
{
#region Properties
public bool SmartSize
{
get { return _VNC.Scaled; }
set { _VNC.Scaled = value; }
}
public bool ViewOnly
{
get { return _VNC.ViewOnly; }
set { _VNC.ViewOnly = value; }
}
#endregion
#region Private Declarations
private VncSharp.RemoteDesktop _VNC;
private ConnectionInfo Info;
#endregion
#region Public Methods
public ProtocolVNC()
{
Control = new VncSharp.RemoteDesktop();
}
public override bool Initialize()
{
base.Initialize();
try
{
_VNC = (VncSharp.RemoteDesktop)Control;
Info = InterfaceControl.Info;
_VNC.VncPort = Info.Port;
return true;
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
Language.strVncSetPropsFailed + Environment.NewLine + ex.Message,
true);
return false;
}
}
public override bool Connect()
{
SetEventHandlers();
try
{
_VNC.Connect(Info.Hostname, Info.VNCViewOnly, Info.VNCSmartSizeMode != SmartSizeMode.SmartSNo);
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
Language.strConnectionOpenFailed + Environment.NewLine +
ex.Message);
return false;
}
return true;
}
public override void Disconnect()
{
try
{
_VNC.Disconnect();
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
Language.strVncConnectionDisconnectFailed + Environment.NewLine +
ex.Message, true);
}
}
public void SendSpecialKeys(SpecialKeys Keys)
{
try
{
// ReSharper disable once SwitchStatementMissingSomeCases
switch (Keys)
{
case SpecialKeys.CtrlAltDel:
_VNC.SendSpecialKeys(VncSharp.SpecialKeys.CtrlAltDel);
break;
case SpecialKeys.CtrlEsc:
_VNC.SendSpecialKeys(VncSharp.SpecialKeys.CtrlEsc);
break;
}
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
Language.strVncSendSpecialKeysFailed + Environment.NewLine +
ex.Message, true);
}
}
public void ToggleSmartSize()
{
try
{
SmartSize = !SmartSize;
RefreshScreen();
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
Language.strVncToggleSmartSizeFailed + Environment.NewLine +
ex.Message, true);
}
}
public void ToggleViewOnly()
{
try
{
ViewOnly = !ViewOnly;
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
Language.strVncToggleViewOnlyFailed + Environment.NewLine +
ex.Message, true);
}
}
public void StartChat()
{
throw new NotImplementedException();
}
public void StartFileTransfer()
{
throw new NotImplementedException();
}
public void RefreshScreen()
{
try
{
_VNC.FullScreenUpdate();
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
Language.strVncRefreshFailed + Environment.NewLine + ex.Message,
true);
}
}
#endregion
#region Private Methods
private void SetEventHandlers()
{
try
{
_VNC.ConnectComplete += VNCEvent_Connected;
_VNC.ConnectionLost += VNCEvent_Disconnected;
FrmMain.ClipboardChanged += VNCEvent_ClipboardChanged;
if (!Force.HasFlag(ConnectionInfo.Force.NoCredentials) && Info?.Password?.Length > 0)
{
_VNC.GetPassword = VNCEvent_Authenticate;
}
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
Language.strVncSetEventHandlersFailed + Environment.NewLine +
ex.Message, true);
}
}
#endregion
#region Private Events & Handlers
private void VNCEvent_Connected(object sender, EventArgs e)
{
Event_Connected(this);
_VNC.AutoScroll = Info.VNCSmartSizeMode == SmartSizeMode.SmartSNo;
}
private void VNCEvent_Disconnected(object sender, EventArgs e)
{
FrmMain.ClipboardChanged -= VNCEvent_ClipboardChanged;
Event_Disconnected(sender, @"VncSharp Disconnected.", null);
Close();
}
private void VNCEvent_ClipboardChanged()
{
_VNC.FillServerClipboard();
}
private string VNCEvent_Authenticate()
{
return Info.Password;
}
#endregion
#region Enums
public enum Defaults
{
Port = 5900
}
public enum SpecialKeys
{
CtrlAltDel,
CtrlEsc
}
public enum Compression
{
[LocalizedAttributes.LocalizedDescription("strNoCompression")]
CompNone = 99,
[Description("0")] Comp0 = 0,
[Description("1")] Comp1 = 1,
[Description("2")] Comp2 = 2,
[Description("3")] Comp3 = 3,
[Description("4")] Comp4 = 4,
[Description("5")] Comp5 = 5,
[Description("6")] Comp6 = 6,
[Description("7")] Comp7 = 7,
[Description("8")] Comp8 = 8,
[Description("9")] Comp9 = 9
}
public enum Encoding
{
[Description("Raw")] EncRaw,
[Description("RRE")] EncRRE,
[Description("CoRRE")] EncCorre,
[Description("Hextile")] EncHextile,
[Description("Zlib")] EncZlib,
[Description("Tight")] EncTight,
[Description("ZlibHex")] EncZLibHex,
[Description("ZRLE")] EncZRLE
}
public enum AuthMode
{
[LocalizedAttributes.LocalizedDescription("VNC")]
AuthVNC,
[LocalizedAttributes.LocalizedDescription("Windows")]
AuthWin
}
public enum ProxyType
{
[LocalizedAttributes.LocalizedDescription("strNone")]
ProxyNone,
[LocalizedAttributes.LocalizedDescription("strHttp")]
ProxyHTTP,
[LocalizedAttributes.LocalizedDescription("strSocks5")]
ProxySocks5,
[LocalizedAttributes.LocalizedDescription("strUltraVncRepeater")]
ProxyUltra
}
public enum Colors
{
[LocalizedAttributes.LocalizedDescription("strNormal")]
ColNormal,
[Description("8-bit")] Col8Bit
}
public enum SmartSizeMode
{
[LocalizedAttributes.LocalizedDescription("strNoSmartSize")]
SmartSNo,
[LocalizedAttributes.LocalizedDescription("strFree")]
SmartSFree,
[LocalizedAttributes.LocalizedDescription("strAspect")]
SmartSAspect
}
#endregion
}
}
using System;
using System.Threading;
using System.ComponentModel;
using System.Net.Sockets;
using mRemoteNG.App;
using mRemoteNG.Tools;
using mRemoteNG.UI.Forms;
// ReSharper disable ArrangeAccessorOwnerBody
namespace mRemoteNG.Connection.Protocol.VNC
{
public class ProtocolVNC : ProtocolBase, ISupportsViewOnly
{
#region Properties
public bool SmartSize
{
get { return _vnc.Scaled; }
set { _vnc.Scaled = value; }
}
public bool ViewOnly
{
get { return _vnc.ViewOnly; }
set { _vnc.ViewOnly = value; }
}
#endregion
#region Private Declarations
private VncSharp.RemoteDesktop _vnc;
private ConnectionInfo _info;
private static bool _isConnectionSuccessful;
private static Exception _socketexception;
private static readonly ManualResetEvent TimeoutObject = new ManualResetEvent(false);
#endregion
#region Public Methods
public ProtocolVNC()
{
Control = new VncSharp.RemoteDesktop();
}
public override bool Initialize()
{
base.Initialize();
try
{
_vnc = (VncSharp.RemoteDesktop)Control;
_info = InterfaceControl.Info;
_vnc.VncPort = _info.Port;
return true;
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
Language.strVncSetPropsFailed + Environment.NewLine + ex.Message,
true);
return false;
}
}
public override bool Connect()
{
SetEventHandlers();
try
{
if (TestConnect(_info.Hostname, _info.Port, 500))
_vnc.Connect(_info.Hostname, _info.VNCViewOnly, _info.VNCSmartSizeMode != SmartSizeMode.SmartSNo);
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
Language.strConnectionOpenFailed + Environment.NewLine +
ex.Message);
return false;
}
return true;
}
public override void Disconnect()
{
try
{
_vnc.Disconnect();
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
Language.strVncConnectionDisconnectFailed + Environment.NewLine +
ex.Message, true);
}
}
public void SendSpecialKeys(SpecialKeys Keys)
{
try
{
// ReSharper disable once SwitchStatementMissingSomeCases
switch (Keys)
{
case SpecialKeys.CtrlAltDel:
_vnc.SendSpecialKeys(VncSharp.SpecialKeys.CtrlAltDel);
break;
case SpecialKeys.CtrlEsc:
_vnc.SendSpecialKeys(VncSharp.SpecialKeys.CtrlEsc);
break;
}
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
Language.strVncSendSpecialKeysFailed + Environment.NewLine +
ex.Message, true);
}
}
public void ToggleSmartSize()
{
try
{
SmartSize = !SmartSize;
RefreshScreen();
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
Language.strVncToggleSmartSizeFailed + Environment.NewLine +
ex.Message, true);
}
}
public void ToggleViewOnly()
{
try
{
ViewOnly = !ViewOnly;
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
Language.strVncToggleViewOnlyFailed + Environment.NewLine +
ex.Message, true);
}
}
public void StartChat()
{
throw new NotImplementedException();
}
public void StartFileTransfer()
{
throw new NotImplementedException();
}
public void RefreshScreen()
{
try
{
_vnc.FullScreenUpdate();
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
Language.strVncRefreshFailed + Environment.NewLine + ex.Message,
true);
}
}
#endregion
#region Private Methods
private void SetEventHandlers()
{
try
{
_vnc.ConnectComplete += VNCEvent_Connected;
_vnc.ConnectionLost += VNCEvent_Disconnected;
FrmMain.ClipboardChanged += VNCEvent_ClipboardChanged;
if (!Force.HasFlag(ConnectionInfo.Force.NoCredentials) && _info?.Password?.Length > 0)
{
_vnc.GetPassword = VNCEvent_Authenticate;
}
}
catch (Exception ex)
{
Runtime.MessageCollector.AddMessage(Messages.MessageClass.ErrorMsg,
Language.strVncSetEventHandlersFailed + Environment.NewLine +
ex.Message, true);
}
}
private static bool TestConnect(string hostName, int port, int timeoutMSec)
{
var tcpclient = new TcpClient();
TimeoutObject.Reset();
tcpclient.BeginConnect(hostName, port, CallBackMethod, tcpclient);
if (TimeoutObject.WaitOne(timeoutMSec, false))
{
if (_isConnectionSuccessful) return true;
}
else
{
tcpclient.Close();
throw new TimeoutException($"Connection timed out to host " + hostName + " on port " + port);
}
return false;
}
private static void CallBackMethod(IAsyncResult asyncresult)
{
try
{
_isConnectionSuccessful = false;
var tcpclient = asyncresult.AsyncState as TcpClient;
if (tcpclient?.Client == null) return;
tcpclient.EndConnect(asyncresult);
_isConnectionSuccessful = true;
}
catch (Exception ex)
{
_isConnectionSuccessful = false;
_socketexception = ex;
}
finally
{
TimeoutObject.Set();
}
}
#endregion
#region Private Events & Handlers
private void VNCEvent_Connected(object sender, EventArgs e)
{
Event_Connected(this);
_vnc.AutoScroll = _info.VNCSmartSizeMode == SmartSizeMode.SmartSNo;
}
private void VNCEvent_Disconnected(object sender, EventArgs e)
{
FrmMain.ClipboardChanged -= VNCEvent_ClipboardChanged;
Event_Disconnected(sender, @"VncSharp Disconnected.", null);
Close();
}
private void VNCEvent_ClipboardChanged()
{
_vnc.FillServerClipboard();
}
private string VNCEvent_Authenticate()
{
return _info.Password;
}
#endregion
#region Enums
public enum Defaults
{
Port = 5900
}
public enum SpecialKeys
{
CtrlAltDel,
CtrlEsc
}
public enum Compression
{
[LocalizedAttributes.LocalizedDescription("strNoCompression")]
CompNone = 99,
[Description("0")] Comp0 = 0,
[Description("1")] Comp1 = 1,
[Description("2")] Comp2 = 2,
[Description("3")] Comp3 = 3,
[Description("4")] Comp4 = 4,
[Description("5")] Comp5 = 5,
[Description("6")] Comp6 = 6,
[Description("7")] Comp7 = 7,
[Description("8")] Comp8 = 8,
[Description("9")] Comp9 = 9
}
public enum Encoding
{
[Description("Raw")] EncRaw,
[Description("RRE")] EncRRE,
[Description("CoRRE")] EncCorre,
[Description("Hextile")] EncHextile,
[Description("Zlib")] EncZlib,
[Description("Tight")] EncTight,
[Description("ZlibHex")] EncZLibHex,
[Description("ZRLE")] EncZRLE
}
public enum AuthMode
{
[LocalizedAttributes.LocalizedDescription("VNC")]
AuthVNC,
[LocalizedAttributes.LocalizedDescription("Windows")]
AuthWin
}
public enum ProxyType
{
[LocalizedAttributes.LocalizedDescription("strNone")]
ProxyNone,
[LocalizedAttributes.LocalizedDescription("strHttp")]
ProxyHTTP,
[LocalizedAttributes.LocalizedDescription("strSocks5")]
ProxySocks5,
[LocalizedAttributes.LocalizedDescription("strUltraVncRepeater")]
ProxyUltra
}
public enum Colors
{
[LocalizedAttributes.LocalizedDescription("strNormal")]
ColNormal,
[Description("8-bit")] Col8Bit
}
public enum SmartSizeMode
{
[LocalizedAttributes.LocalizedDescription("strNoSmartSize")]
SmartSNo,
[LocalizedAttributes.LocalizedDescription("strFree")]
SmartSFree,
[LocalizedAttributes.LocalizedDescription("strAspect")]
SmartSAspect
}
#endregion
}
}