Files
mRemoteNG/mRemoteV1/Connection/ConnectionInitiator.cs
2019-05-13 14:07:10 -05:00

306 lines
13 KiB
C#

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Container;
using mRemoteNG.Messages;
using mRemoteNG.Tools;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.Panels;
using mRemoteNG.UI.Tabs;
using mRemoteNG.UI.Window;
using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNG.Connection
{
public class ConnectionInitiator : IConnectionInitiator
{
private readonly PanelAdder _panelAdder = new PanelAdder();
private readonly List<string> _activeConnections = new List<string>();
public IEnumerable<string> ActiveConnections => _activeConnections;
public bool SwitchToOpenConnection(ConnectionInfo connectionInfo)
{
var interfaceControl = FindConnectionContainer(connectionInfo);
if (interfaceControl == null) return false;
var connT = (ConnectionTab)interfaceControl.FindForm();
connT?.Focus();
var findForm = (ConnectionTab)interfaceControl.FindForm();
findForm?.Show(findForm.DockPanel);
return true;
}
public void OpenConnection(
ContainerInfo containerInfo,
ConnectionInfo.Force force = ConnectionInfo.Force.None,
ConnectionWindow conForm = null)
{
if (containerInfo == null || containerInfo.Children.Count == 0)
return;
foreach (var child in containerInfo.Children)
{
if (child is ContainerInfo childAsContainer)
OpenConnection(childAsContainer, force, conForm);
else
OpenConnection(child, force, conForm);
}
}
public void OpenConnection(
ConnectionInfo connectionInfo,
ConnectionInfo.Force force = ConnectionInfo.Force.None,
ConnectionWindow conForm = null)
{
if (connectionInfo == null)
return;
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(conForm, 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++)
{
// the new structure is ConnectionWindow.Controls[0].ActiveDocument.Controls[0]
// DockPanel InterfaceControl
if (!(Runtime.WindowList[i] is ConnectionWindow connectionWindow)) continue;
if (connectionWindow.Controls.Count < 1) continue;
if (!(connectionWindow.Controls[0] is DockPanel cwDp)) continue;
foreach (var dockContent in cwDp.Documents)
{
var tab = (ConnectionTab)dockContent;
var ic = InterfaceControl.FindInterfaceControl(tab);
if (ic == null) continue;
if (ic.Info == connectionInfo)
return ic;
}
}
return null;
}
private static string SetConnectionPanel(ConnectionInfo connectionInfo, ConnectionInfo.Force force)
{
if (connectionInfo.Panel != "" &&
!force.HasFlag(ConnectionInfo.Force.OverridePanel) &&
!Settings.Default.AlwaysShowPanelSelectionDlg)
return connectionInfo.Panel;
var frmPnl = new FrmChoosePanel();
return frmPnl.ShowDialog() == DialogResult.OK
? frmPnl.Panel
: null;
}
private ConnectionWindow SetConnectionForm(ConnectionWindow conForm, string connectionPanel)
{
var connectionForm = conForm ?? Runtime.WindowList.FromString(connectionPanel) as ConnectionWindow;
if (connectionForm == null)
connectionForm = _panelAdder.AddPanel(connectionPanel);
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)
((ConnectionTab)connectionContainer).Icon = extT.Icon;
return connectionContainer;
}
private static void SetConnectionFormEventHandlers(ProtocolBase newProtocol, Form connectionForm)
{
newProtocol.Closed += ((ConnectionWindow)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
}
}