Files
mRemoteNG/mRemoteV1/Connection/ConnectionInitiator.cs

290 lines
12 KiB
C#

using mRemoteNG.App;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Container;
using mRemoteNG.Messages;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.Panels;
using mRemoteNG.UI.Window;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using TabPage = Crownwood.Magic.Controls.TabPage;
namespace mRemoteNG.Connection
{
public class ConnectionInitiator : IConnectionInitiator
{
private readonly PanelAdder _panelAdder = new PanelAdder();
private readonly List<string> _activeConnections = new List<string>();
/// <summary>
/// List of unique IDs of the currently active connections
/// </summary>
public IEnumerable<string> ActiveConnections => _activeConnections;
public bool SwitchToOpenConnection(ConnectionInfo connectionInfo)
{
var interfaceControl = FindConnectionContainer(connectionInfo);
if (interfaceControl == null) return false;
var connectionWindow = (ConnectionWindow)interfaceControl.FindForm();
connectionWindow?.Focus();
var findForm = (ConnectionWindow)interfaceControl.FindForm();
findForm?.Show(FrmMain.Default.pnlDock);
var tabPage = (TabPage)interfaceControl.Parent;
tabPage.Selected = true;
return true;
}
public void OpenConnection(ContainerInfo containerInfo, ConnectionInfo.Force force)
{
var children = containerInfo.Children;
if (children.Count == 0) return;
foreach (var child in children)
{
var childAsContainer = child as ContainerInfo;
if (childAsContainer != null)
OpenConnection(childAsContainer, force);
else
OpenConnection(child, force);
}
}
public void OpenConnection(ConnectionInfo connectionInfo, ConnectionInfo.Force force = ConnectionInfo.Force.None)
{
try
{
if (connectionInfo.Hostname == "" && connectionInfo.Protocol != ProtocolType.IntApp)
{
Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, Language.strConnectionOpenFailedNoHostname);
return;
}
StartPreConnectionExternalApp(connectionInfo);
if (!force.HasFlag(ConnectionInfo.Force.DoNotJump))
{
if (SwitchToOpenConnection(connectionInfo))
return;
}
var protocolFactory = new ProtocolFactory();
var newProtocol = protocolFactory.CreateProtocol(connectionInfo);
var connectionPanel = SetConnectionPanel(connectionInfo, force);
if (string.IsNullOrEmpty(connectionPanel)) return;
var connectionForm = SetConnectionForm(connectionPanel);
var connectionContainer = SetConnectionContainer(connectionInfo, connectionForm);
SetConnectionFormEventHandlers(newProtocol, connectionForm);
SetConnectionEventHandlers(newProtocol);
BuildConnectionInterfaceController(connectionInfo, newProtocol, connectionContainer);
newProtocol.Force = force;
if (newProtocol.Initialize() == false)
{
newProtocol.Close();
return;
}
if (newProtocol.Connect() == false)
{
newProtocol.Close();
return;
}
connectionInfo.OpenConnections.Add(newProtocol);
_activeConnections.Add(connectionInfo.ConstantID);
FrmMain.Default.SelectedConnection = connectionInfo;
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionStackTrace(Language.strConnectionOpenFailed, ex);
}
}
#region Private
private static void StartPreConnectionExternalApp(ConnectionInfo connectionInfo)
{
if (connectionInfo.PreExtApp == "") return;
var extA = Runtime.ExternalToolsService.GetExtAppByName(connectionInfo.PreExtApp);
extA?.Start(connectionInfo);
}
private static InterfaceControl FindConnectionContainer(ConnectionInfo connectionInfo)
{
if (connectionInfo.OpenConnections.Count <= 0) return null;
for (var i = 0; i <= Runtime.WindowList.Count - 1; i++)
{
var window = Runtime.WindowList[i] as ConnectionWindow;
var connectionWindow = window;
if (connectionWindow?.TabController == null) continue;
foreach (TabPage t in connectionWindow.TabController.TabPages)
{
var ic = t.Controls[0] as InterfaceControl;
if (ic == null) continue;
if (ic.Info == connectionInfo)
{
return ic;
}
}
}
return null;
}
private static string SetConnectionPanel(ConnectionInfo connectionInfo, ConnectionInfo.Force force)
{
var connectionPanel = "";
if (connectionInfo.Panel == "" || force.HasFlag(ConnectionInfo.Force.OverridePanel) || Settings.Default.AlwaysShowPanelSelectionDlg)
{
var frmPnl = new FrmChoosePanel();
if (frmPnl.ShowDialog() == DialogResult.OK)
{
connectionPanel = frmPnl.Panel;
}
else
{
return null;
}
}
else
{
connectionPanel = connectionInfo.Panel;
}
return connectionPanel;
}
private ConnectionWindow SetConnectionForm(string connectionPanelName)
{
var connectionForm = Runtime.WindowList.FromString(connectionPanelName) as ConnectionWindow;
if (connectionForm == null)
connectionForm = _panelAdder.AddPanel(connectionPanelName);
else
connectionForm.Show(FrmMain.Default.pnlDock);
connectionForm.Focus();
return connectionForm;
}
private static Control SetConnectionContainer(ConnectionInfo connectionInfo, ConnectionWindow connectionForm)
{
Control connectionContainer = connectionForm.AddConnectionTab(connectionInfo);
if (connectionInfo.Protocol != ProtocolType.IntApp) return connectionContainer;
var extT = Runtime.ExternalToolsService.GetExtAppByName(connectionInfo.ExtApp);
if(extT == null) return connectionContainer;
if (extT.Icon != null)
((TabPage)connectionContainer).Icon = extT.Icon;
return connectionContainer;
}
private static void SetConnectionFormEventHandlers(ProtocolBase newProtocol, ConnectionWindow connectionForm)
{
newProtocol.Closed += connectionForm.Prot_Event_Closed;
}
private void SetConnectionEventHandlers(ProtocolBase newProtocol)
{
newProtocol.Disconnected += Prot_Event_Disconnected;
newProtocol.Connected += Prot_Event_Connected;
newProtocol.Closed += Prot_Event_Closed;
newProtocol.ErrorOccured += Prot_Event_ErrorOccured;
}
private static void BuildConnectionInterfaceController(ConnectionInfo connectionInfo, ProtocolBase newProtocol, Control connectionContainer)
{
newProtocol.InterfaceControl = new InterfaceControl(connectionContainer, newProtocol, connectionInfo);
}
#endregion
#region Event handlers
private static void Prot_Event_Disconnected(object sender, string disconnectedMessage, int? reasonCode)
{
try
{
var prot = (ProtocolBase)sender;
var msgClass = MessageClass.InformationMsg;
if (prot.InterfaceControl.Info.Protocol == ProtocolType.RDP)
{
if (reasonCode > 3)
{
msgClass = MessageClass.WarningMsg;
}
}
Runtime.MessageCollector.AddMessage(msgClass,
string.Format(
Language.strProtocolEventDisconnected,
disconnectedMessage,
prot.InterfaceControl.Info.Hostname,
prot.InterfaceControl.Info.Protocol.ToString()));
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionStackTrace(Language.strProtocolEventDisconnectFailed, ex);
}
}
private void Prot_Event_Closed(object sender)
{
try
{
var prot = (ProtocolBase)sender;
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strConnenctionCloseEvent, true);
string connDetail;
if (prot.InterfaceControl.Info.Hostname == "" && prot.InterfaceControl.Info.Protocol == ProtocolType.IntApp)
connDetail = prot.InterfaceControl.Info.ExtApp;
else if (prot.InterfaceControl.Info.Hostname != "")
connDetail = prot.InterfaceControl.Info.Hostname;
else
connDetail = "UNKNOWN";
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strConnenctionClosedByUser, connDetail, prot.InterfaceControl.Info.Protocol, Environment.UserName));
prot.InterfaceControl.Info.OpenConnections.Remove(prot);
if (_activeConnections.Contains(prot.InterfaceControl.Info.ConstantID))
_activeConnections.Remove(prot.InterfaceControl.Info.ConstantID);
if (prot.InterfaceControl.Info.PostExtApp == "") return;
var extA = Runtime.ExternalToolsService.GetExtAppByName(prot.InterfaceControl.Info.PostExtApp);
extA?.Start(prot.InterfaceControl.Info);
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionStackTrace(Language.strConnenctionCloseEventFailed, ex);
}
}
private static void Prot_Event_Connected(object sender)
{
var prot = (ProtocolBase)sender;
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strConnectionEventConnected, true);
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strConnectionEventConnectedDetail, prot.InterfaceControl.Info.Hostname, prot.InterfaceControl.Info.Protocol, Environment.UserName, prot.InterfaceControl.Info.Description, prot.InterfaceControl.Info.UserField));
}
private static void Prot_Event_ErrorOccured(object sender, string errorMessage, int? errorCode)
{
try
{
var prot = (ProtocolBase) sender;
var msg = string.Format(
Language.strConnectionEventErrorOccured,
errorMessage,
prot.InterfaceControl.Info.Hostname,
errorCode?.ToString() ?? "-");
Runtime.MessageCollector.AddMessage(MessageClass.WarningMsg, msg);
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionStackTrace(Language.strConnectionEventConnectionFailed, ex);
}
}
#endregion
}
}