resolve conflicts

This commit is contained in:
BlueBlock
2023-03-21 16:04:32 -04:00
parent d5eea9db20
commit 20e04c0d75

View File

@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Timers;
@@ -15,14 +16,13 @@ using mRemoteNG.UI.Forms;
using mRemoteNG.UI.Tabs;
using MSTSCLib;
using mRemoteNG.Resources.Language;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
using System.DirectoryServices.ActiveDirectory;
using System.Runtime.Versioning;
using FileDialog = Microsoft.Win32.FileDialog;
namespace mRemoteNG.Connection.Protocol.RDP
{
[SupportedOSPlatform("windows")]
public class RdpProtocol6 : ProtocolBase, ISupportsViewOnly
public class RdpProtocol : ProtocolBase, ISupportsViewOnly
{
/* RDP v8 requires Windows 7 with:
* https://support.microsoft.com/en-us/kb/2592687
@@ -31,17 +31,22 @@ namespace mRemoteNG.Connection.Protocol.RDP
*
* Windows 8+ support RDP v8 out of the box.
*/
private MsRdpClient6NotSafeForScripting _rdpClient;
private MsRdpClient6NotSafeForScripting _rdpClient; // lowest version supported
protected virtual RdpVersion RdpProtocolVersion => RDP.RdpVersion.Rdc6;
protected ConnectionInfo connectionInfo;
protected Version RdpVersion;
private readonly DisplayProperties _displayProperties;
protected readonly FrmMain _frmMain = FrmMain.Default;
protected bool loginComplete;
private Version _rdpVersion;
private bool _redirectKeys;
private bool _alertOnIdleDisconnect;
private readonly DisplayProperties _displayProperties;
private readonly FrmMain _frmMain = FrmMain.Default;
protected virtual RdpVersion RdpProtocolVersion => RdpVersion.Rdc6;
protected uint DesktopScaleFactor => (uint)(_displayProperties.ResolutionScalingFactor.Width * 100);
protected readonly uint DeviceScaleFactor = 100;
protected readonly uint Orientation = 0;
private AxHost AxHost => (AxHost)Control;
#region Properties
public virtual bool SmartSize
@@ -58,12 +63,6 @@ namespace mRemoteNG.Connection.Protocol.RDP
private bool RedirectKeys
{
/*
get
{
return _redirectKeys;
}
*/
set
{
_redirectKeys = value;
@@ -75,7 +74,7 @@ namespace mRemoteNG.Connection.Protocol.RDP
}
Debug.Assert(Convert.ToBoolean(_rdpClient.SecuredSettingsEnabled));
var msRdpClientSecuredSettings = _rdpClient.SecuredSettings2;
IMsRdpClientSecuredSettings msRdpClientSecuredSettings = _rdpClient.SecuredSettings2;
msRdpClientSecuredSettings.KeyboardHookMode = 1; // Apply key combinations at the remote server.
}
catch (Exception ex)
@@ -97,7 +96,7 @@ namespace mRemoteNG.Connection.Protocol.RDP
#region Constructors
public RdpProtocol6()
public RdpProtocol()
{
_displayProperties = new DisplayProperties();
tmrReconnect.Elapsed += tmrReconnect_Elapsed;
@@ -106,27 +105,29 @@ namespace mRemoteNG.Connection.Protocol.RDP
#endregion
#region Public Methods
protected virtual AxHost CreateActiveXRdpClientControl()
{
return new AxMsRdpClient6NotSafeForScripting();
}
public override bool Initialize()
{
connectionInfo = InterfaceControl.Info;
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg,
$"Requesting RDP version: {connectionInfo.RdpVersion}. Using: {RdpProtocolVersion}");
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, $"Requesting RDP version: {connectionInfo.RdpVersion}. Using: {RdpProtocolVersion}");
Control = CreateActiveXRdpClientControl();
base.Initialize();
try
{
if (!InitializeActiveXControl())
return false;
if (!InitializeActiveXControl()) return false;
RdpVersion = new Version(_rdpClient.Version);
if (RdpVersion < Versions.RDC61) return false; // only RDP versions 6.1 and greater are supported; minimum dll version checked, MSTSCLIB is not capable
_rdpVersion = new Version(_rdpClient.Version);
SetRdpClientProperties();
return true;
}
catch (Exception ex)
@@ -141,23 +142,25 @@ namespace mRemoteNG.Connection.Protocol.RDP
try
{
Control.GotFocus += RdpClient_GotFocus;
Control.CreateControl();
while (!Control.Created)
{
Thread.Sleep(0);
Thread.Sleep(50);
Application.DoEvents();
}
Control.Anchor = AnchorStyles.None;
_rdpClient = (MsRdpClient6NotSafeForScripting)((AxHost)Control).GetOcx();
return true;
}
catch (COMException ex)
{
if (ex.Message.Contains("CLASS_E_CLASSNOTAVAILABLE"))
{
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg,
string.Format(Language.RdpProtocolVersionNotSupported, connectionInfo.RdpVersion));
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, string.Format(Language.RdpProtocolVersionNotSupported, connectionInfo.RdpVersion));
}
else
{
@@ -265,11 +268,9 @@ namespace mRemoteNG.Connection.Protocol.RDP
{
try
{
using (var control = CreateActiveXRdpClientControl())
{
control.CreateControl();
return true;
}
using var control = CreateActiveXRdpClientControl();
control.CreateControl();
return true;
}
catch
{
@@ -280,8 +281,21 @@ namespace mRemoteNG.Connection.Protocol.RDP
#region Private Methods
protected static class Versions
{
// https://en.wikipedia.org/wiki/Remote_Desktop_Protocol
public static readonly Version RDC60 = new Version(6, 0, 6000);
public static readonly Version RDC61 = new Version(6, 0, 6001);
public static readonly Version RDC70 = new Version(6, 1, 7600);
public static readonly Version RDC80 = new Version(6, 2, 9200);
public static readonly Version RDC81 = new Version(6, 3, 9600);
public static readonly Version RDC100 = new Version(10, 0, 0);
}
private void SetRdpClientProperties()
{
// https://learn.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/rdp-files
_rdpClient.Server = connectionInfo.Hostname;
SetCredentials();
@@ -307,21 +321,12 @@ namespace mRemoteNG.Connection.Protocol.RDP
_rdpClient.AdvancedSettings2.overallConnectionTimeout = Settings.Default.ConRDPOverallConnectionTimeout;
_rdpClient.AdvancedSettings2.BitmapPeristence = Convert.ToInt32(connectionInfo.CacheBitmaps);
if (_rdpVersion >= Versions.RDC61)
if (RdpVersion >= Versions.RDC61)
{
_rdpClient.AdvancedSettings7.EnableCredSspSupport = connectionInfo.UseCredSsp;
}
if(_rdpVersion >= Versions.RDC81)
{
if (connectionInfo.UseRestrictedAdmin)
SetExtendedProperty("RestrictedLogon", true);
else if (connectionInfo.UseRCG)
{
SetExtendedProperty("DisableCredentialsDelegation", true);
SetExtendedProperty("RedirectedAuthentication", true);
}
}
SetUseConsoleSession();
SetPort();
RedirectKeys = connectionInfo.RedirectKeys;
@@ -345,10 +350,9 @@ namespace mRemoteNG.Connection.Protocol.RDP
// ReSharper disable once UseIndexedProperty
return ((IMsRdpExtendedSettings)_rdpClient).get_Property(property);
}
catch (Exception e)
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionMessage($"Error getting extended RDP property '{property}'",
e, MessageClass.WarningMsg, false);
Runtime.MessageCollector.AddExceptionMessage($"Error getting extended RDP property '{property}'", ex, MessageClass.WarningMsg, false);
return null;
}
}
@@ -360,10 +364,9 @@ namespace mRemoteNG.Connection.Protocol.RDP
// ReSharper disable once UseIndexedProperty
((IMsRdpExtendedSettings)_rdpClient).set_Property(property, ref value);
}
catch (Exception e)
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionMessage($"Error setting extended RDP property '{property}'",
e, MessageClass.WarningMsg, false);
Runtime.MessageCollector.AddExceptionMessage($"Error setting extended RDP property '{property}'", ex, MessageClass.WarningMsg, false);
}
}
@@ -373,63 +376,62 @@ namespace mRemoteNG.Connection.Protocol.RDP
{
if (_rdpClient.TransportSettings.GatewayIsSupported == 0)
{
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.RdpGatewayNotSupported,
true);
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.RdpGatewayNotSupported, true);
return;
}
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.RdpGatewayIsSupported,
true);
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.RdpGatewayIsSupported, true);
if (connectionInfo.RDGatewayUsageMethod != RDGatewayUsageMethod.Never)
if (connectionInfo.RDGatewayUsageMethod == RDGatewayUsageMethod.Never) return;
// USE GATEWAY
_rdpClient.TransportSettings.GatewayUsageMethod = (uint)connectionInfo.RDGatewayUsageMethod;
_rdpClient.TransportSettings.GatewayHostname = connectionInfo.RDGatewayHostname;
_rdpClient.TransportSettings.GatewayProfileUsageMethod = 1; // TSC_PROXY_PROFILE_MODE_EXPLICIT
if (connectionInfo.RDGatewayUseConnectionCredentials == RDGatewayUseConnectionCredentials.SmartCard)
{
_rdpClient.TransportSettings.GatewayUsageMethod = (uint)connectionInfo.RDGatewayUsageMethod;
_rdpClient.TransportSettings.GatewayHostname = connectionInfo.RDGatewayHostname;
_rdpClient.TransportSettings.GatewayProfileUsageMethod = 1; // TSC_PROXY_PROFILE_MODE_EXPLICIT
if (connectionInfo.RDGatewayUseConnectionCredentials == RDGatewayUseConnectionCredentials.SmartCard)
_rdpClient.TransportSettings.GatewayCredsSource = 1; // TSC_PROXY_CREDS_MODE_SMARTCARD
}
if (RdpVersion < Versions.RDC61 || Force.HasFlag(ConnectionInfo.Force.NoCredentials)) return;
switch (connectionInfo.RDGatewayUseConnectionCredentials)
{
case RDGatewayUseConnectionCredentials.Yes:
_rdpClient.TransportSettings2.GatewayUsername = connectionInfo.Username;
_rdpClient.TransportSettings2.GatewayPassword = connectionInfo.Password;
_rdpClient.TransportSettings2.GatewayDomain = connectionInfo?.Domain;
break;
case RDGatewayUseConnectionCredentials.SmartCard:
_rdpClient.TransportSettings2.GatewayCredSharing = 0;
break;
default:
{
_rdpClient.TransportSettings.GatewayCredsSource = 1; // TSC_PROXY_CREDS_MODE_SMARTCARD
}
_rdpClient.TransportSettings2.GatewayCredSharing = 0;
if (_rdpVersion >= Versions.RDC61 && !Force.HasFlag(ConnectionInfo.Force.NoCredentials))
{
if (connectionInfo.RDGatewayUseConnectionCredentials == RDGatewayUseConnectionCredentials.Yes)
{
_rdpClient.TransportSettings2.GatewayUsername = connectionInfo.Username;
_rdpClient.TransportSettings2.GatewayPassword = connectionInfo.Password;
_rdpClient.TransportSettings2.GatewayDomain = connectionInfo?.Domain;
}
else if (connectionInfo.RDGatewayUseConnectionCredentials == RDGatewayUseConnectionCredentials.SmartCard)
{
_rdpClient.TransportSettings2.GatewayCredSharing = 0;
}
else
{
_rdpClient.TransportSettings2.GatewayCredSharing = 0;
var gwu = connectionInfo.RDGatewayUsername;
var gwp = connectionInfo.RDGatewayPassword;
var gwd = connectionInfo.RDGatewayDomain;
var pkey = "";
string gwu = connectionInfo.RDGatewayUsername;
string gwp = connectionInfo.RDGatewayPassword;
string gwd = connectionInfo.RDGatewayDomain;
string pkey = "";
// access secret server api if necessary
if (InterfaceControl.Info.RDGatewayExternalCredentialProvider == ExternalCredentialProvider.DelineaSecretServer)
// access secret server api if necessary
if (InterfaceControl.Info.RDGatewayExternalCredentialProvider == ExternalCredentialProvider.DelineaSecretServer)
{
try
{
try
{
string RDGUserViaAPI = InterfaceControl.Info.RDGatewayUserViaAPI;
ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer($"{RDGUserViaAPI}", out gwu, out gwp, out gwd, out pkey);
}
catch (Exception ex)
{
Event_ErrorOccured(this, "Secret Server Interface Error: " + ex.Message, 0);
}
string RDGUserViaAPI = InterfaceControl.Info.RDGatewayUserViaAPI;
ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer($"{RDGUserViaAPI}", out gwu, out gwp, out gwd, out pkey);
}
_rdpClient.TransportSettings2.GatewayUsername = gwu;
_rdpClient.TransportSettings2.GatewayPassword = gwp;
_rdpClient.TransportSettings2.GatewayDomain = gwd;
catch (Exception ex)
{
Event_ErrorOccured(this, "Secret Server Interface Error: " + ex.Message, 0);
}
}
_rdpClient.TransportSettings2.GatewayUsername = gwu;
_rdpClient.TransportSettings2.GatewayPassword = gwp;
_rdpClient.TransportSettings2.GatewayDomain = gwd;
break;
}
}
}
@@ -458,20 +460,14 @@ namespace mRemoteNG.Connection.Protocol.RDP
value = connectionInfo.UseConsoleSession;
}
if (_rdpVersion >= Versions.RDC61)
if (RdpVersion >= Versions.RDC61)
{
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg,
string.Format(Language.RdpSetConsoleSwitch, _rdpVersion),
true);
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.RdpSetConsoleSwitch, RdpVersion), true);
_rdpClient.AdvancedSettings7.ConnectToAdministerServer = value;
}
else
{
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg,
string.Format(Language.RdpSetConsoleSwitch, _rdpVersion) +
Environment.NewLine +
"No longer supported in this RDP version. Reference: https://msdn.microsoft.com/en-us/library/aa380863(v=vs.85).aspx",
true);
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, $"{string.Format(Language.RdpSetConsoleSwitch, RdpVersion)}{Environment.NewLine}No longer supported in this RDP version. Reference: https://msdn.microsoft.com/en-us/library/aa380863(v=vs.85).aspx", true);
// ConnectToServerConsole is deprecated
//https://msdn.microsoft.com/en-us/library/aa380863(v=vs.85).aspx
//_rdpClient.AdvancedSettings2.ConnectToServerConsole = value;
@@ -495,21 +491,21 @@ namespace mRemoteNG.Connection.Protocol.RDP
var userName = connectionInfo?.Username ?? "";
var password = connectionInfo?.Password ?? "";
var domain = connectionInfo?.Domain ?? "";
var UserViaAPI = connectionInfo?.UserViaAPI ?? "";
string pkey = "";
var userViaApi = connectionInfo?.UserViaAPI ?? "";
var pkey = "";
// access secret server api if necessary
if (InterfaceControl.Info.ExternalCredentialProvider == ExternalCredentialProvider.DelineaSecretServer)
{
try
{
ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer($"{UserViaAPI}", out userName, out password, out domain, out pkey);
ExternalConnectors.DSS.SecretServerInterface.FetchSecretFromServer($"{userViaApi}", out userName, out password, out domain, out pkey);
}
catch (Exception ex)
{
Event_ErrorOccured(this, "Secret Server Interface Error: " + ex.Message, 0);
}
}
if (string.IsNullOrEmpty(userName))
@@ -581,9 +577,8 @@ namespace mRemoteNG.Connection.Protocol.RDP
{
try
{
var scaleFactor = (uint)(_displayProperties.ResolutionScalingFactor.Width * 100);
SetExtendedProperty("DesktopScaleFactor", scaleFactor);
SetExtendedProperty("DeviceScaleFactor", (uint)100);
SetExtendedProperty("DesktopScaleFactor", DesktopScaleFactor);
SetExtendedProperty("DeviceScaleFactor", DeviceScaleFactor);
if (Force.HasFlag(ConnectionInfo.Force.Fullscreen))
{
@@ -594,28 +589,33 @@ namespace mRemoteNG.Connection.Protocol.RDP
return;
}
if (InterfaceControl.Info.Resolution == RDPResolutions.FitToWindow ||
InterfaceControl.Info.Resolution == RDPResolutions.SmartSize)
switch (InterfaceControl.Info.Resolution)
{
_rdpClient.DesktopWidth = InterfaceControl.Size.Width;
_rdpClient.DesktopHeight = InterfaceControl.Size.Height;
case RDPResolutions.FitToWindow:
case RDPResolutions.SmartSize:
{
_rdpClient.DesktopWidth = InterfaceControl.Size.Width;
_rdpClient.DesktopHeight = InterfaceControl.Size.Height;
if (InterfaceControl.Info.Resolution == RDPResolutions.SmartSize)
{
_rdpClient.AdvancedSettings2.SmartSizing = true;
}
}
else if (InterfaceControl.Info.Resolution == RDPResolutions.Fullscreen)
{
_rdpClient.FullScreen = true;
_rdpClient.DesktopWidth = Screen.FromControl(_frmMain).Bounds.Width;
_rdpClient.DesktopHeight = Screen.FromControl(_frmMain).Bounds.Height;
}
else
{
var resolution = connectionInfo.Resolution.GetResolutionRectangle();
_rdpClient.DesktopWidth = resolution.Width;
_rdpClient.DesktopHeight = resolution.Height;
if (InterfaceControl.Info.Resolution == RDPResolutions.SmartSize)
{
_rdpClient.AdvancedSettings2.SmartSizing = true;
}
break;
}
case RDPResolutions.Fullscreen:
_rdpClient.FullScreen = true;
_rdpClient.DesktopWidth = Screen.FromControl(_frmMain).Bounds.Width;
_rdpClient.DesktopHeight = Screen.FromControl(_frmMain).Bounds.Height;
break;
default:
{
var resolution = connectionInfo.Resolution.GetResolutionRectangle();
_rdpClient.DesktopWidth = resolution.Width;
_rdpClient.DesktopHeight = resolution.Height;
break;
}
}
}
catch (Exception ex)
@@ -643,7 +643,7 @@ namespace mRemoteNG.Connection.Protocol.RDP
{
try
{
_rdpClient.AdvancedSettings2.RedirectDrives = connectionInfo.RedirectDiskDrives;
SetDriveRedirection();
_rdpClient.AdvancedSettings2.RedirectPorts = connectionInfo.RedirectPorts;
_rdpClient.AdvancedSettings2.RedirectPrinters = connectionInfo.RedirectPrinters;
_rdpClient.AdvancedSettings2.RedirectSmartCards = connectionInfo.RedirectSmartCards;
@@ -656,6 +656,46 @@ namespace mRemoteNG.Connection.Protocol.RDP
}
}
private void SetDriveRedirection()
{
if (RDPDiskDrives.None == connectionInfo.RedirectDiskDrives)
_rdpClient.AdvancedSettings2.RedirectDrives = false;
else if (RDPDiskDrives.All == connectionInfo.RedirectDiskDrives)
_rdpClient.AdvancedSettings2.RedirectDrives = true;
else if (RDPDiskDrives.Custom == connectionInfo.RedirectDiskDrives)
{
var rdpNS5 = (IMsRdpClientNonScriptable5)((AxHost)Control).GetOcx();
for (uint i = 0; i < rdpNS5.DriveCollection.DriveCount; i++)
{
IMsRdpDrive drive = rdpNS5.DriveCollection.DriveByIndex[i];
drive.RedirectionState = connectionInfo.RedirectDiskDrivesCustom.Contains(drive.Name.Substring(0, 1));
}
}
else
{
// Local Drives
var rdpNS5 = (IMsRdpClientNonScriptable5)((AxHost)Control).GetOcx();
for (uint i = 0; i < rdpNS5.DriveCollection.DriveCount; i++)
{
IMsRdpDrive drive = rdpNS5.DriveCollection.DriveByIndex[i];
drive.RedirectionState = IsLocal(drive);
}
}
}
private bool IsLocal(IMsRdpDrive drive)
{
DriveInfo[] myDrives = DriveInfo.GetDrives();
foreach (DriveInfo myDrive in myDrives)
{
if (myDrive.Name.Substring(0, 1).Equals(drive.Name.Substring(0,1)))
{
return myDrive.DriveType == DriveType.Fixed;
}
}
return false;
}
private void SetPerformanceFlags()
{
try
@@ -724,7 +764,7 @@ namespace mRemoteNG.Connection.Protocol.RDP
}
}
private void SetEventHandlers()
protected virtual void SetEventHandlers()
{
try
{
@@ -733,15 +773,15 @@ namespace mRemoteNG.Connection.Protocol.RDP
_rdpClient.OnLoginComplete += RDPEvent_OnLoginComplete;
_rdpClient.OnFatalError += RDPEvent_OnFatalError;
_rdpClient.OnDisconnected += RDPEvent_OnDisconnected;
_rdpClient.OnLeaveFullScreenMode += RDPEvent_OnLeaveFullscreenMode;
_rdpClient.OnIdleTimeoutNotification += RDPEvent_OnIdleTimeoutNotification;
_rdpClient.OnLeaveFullScreenMode += RDPEvent_OnLeaveFullscreenMode;
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionStackTrace(Language.RdpSetEventHandlersFailed, ex);
}
}
#endregion
#region Private Events & Handlers
@@ -751,11 +791,9 @@ namespace mRemoteNG.Connection.Protocol.RDP
Close(); //Simply close the RDP Session if the idle timeout has been triggered.
if (!_alertOnIdleDisconnect) return;
MessageBox.Show($"The {connectionInfo.Name} session was disconnected due to inactivity",
"Session Disconnected", MessageBoxButtons.OK, MessageBoxIcon.Information);
MessageBox.Show($@"The {connectionInfo.Name} session was disconnected due to inactivity", @"Session Disconnected", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void RDPEvent_OnFatalError(int errorCode)
{
var errorMsg = RdpErrorCodes.GetError(errorCode);
@@ -767,8 +805,7 @@ namespace mRemoteNG.Connection.Protocol.RDP
const int UI_ERR_NORMAL_DISCONNECT = 0xB08;
if (discReason != UI_ERR_NORMAL_DISCONNECT)
{
var reason =
_rdpClient.GetErrorDescription((uint)discReason, (uint)_rdpClient.ExtendedDisconnectReason);
var reason = _rdpClient.GetErrorDescription((uint)discReason, (uint)_rdpClient.ExtendedDisconnectReason);
Event_Disconnected(this, reason, discReason);
}
@@ -806,7 +843,7 @@ namespace mRemoteNG.Connection.Protocol.RDP
private void RDPEvent_OnLeaveFullscreenMode()
{
Fullscreen = false;
_leaveFullscreenEvent?.Invoke(this, new EventArgs());
_leaveFullscreenEvent?.Invoke(this, EventArgs.Empty);
}
private void RdpClient_GotFocus(object sender, EventArgs e)
@@ -824,8 +861,7 @@ namespace mRemoteNG.Connection.Protocol.RDP
public event LeaveFullscreenEventHandler LeaveFullscreen
{
add => _leaveFullscreenEvent = (LeaveFullscreenEventHandler)Delegate.Combine(_leaveFullscreenEvent, value);
remove =>
_leaveFullscreenEvent = (LeaveFullscreenEventHandler)Delegate.Remove(_leaveFullscreenEvent, value);
remove => _leaveFullscreenEvent = (LeaveFullscreenEventHandler)Delegate.Remove(_leaveFullscreenEvent, value);
}
#endregion
@@ -841,20 +877,10 @@ namespace mRemoteNG.Connection.Protocol.RDP
}
#endregion
public static class Versions
{
public static readonly Version RDC60 = new Version(6, 0, 6000);
public static readonly Version RDC61 = new Version(6, 0, 6001);
public static readonly Version RDC70 = new Version(6, 1, 7600);
public static readonly Version RDC80 = new Version(6, 2, 9200);
public static readonly Version RDC81 = new Version(6, 3, 9600);
public static readonly Version RDC100 = new Version(10, 0, 0);
}
#region Reconnect Stuff
public void tmrReconnect_Elapsed(object sender, ElapsedEventArgs e)
private void tmrReconnect_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
@@ -877,5 +903,6 @@ namespace mRemoteNG.Connection.Protocol.RDP
}
#endregion
}
}