Compare commits

...

33 Commits

Author SHA1 Message Date
David Sparer
7445e917d6 fixed an incomplete merge 2018-10-25 10:26:28 -05:00
David Sparer
7a54b98ea2 Merge branch 'develop' into remove_statics
# Conflicts:
#	mRemoteV1/UI/Controls/MultiSshToolStrip.cs
#	mRemoteV1/UI/Forms/frmMain.cs
#	mRemoteV1/UI/Panels/PanelAdder.cs
#	mRemoteV1/UI/Window/ConnectionTreeWindow.cs
2018-10-25 10:02:32 -05:00
David Sparer
4dea0d03ed Merge branch 'develop' into remove_statics
# Conflicts:
#	mRemoteNGTests/IntegrationTests/XmlSerializationLifeCycleTests.cs
#	mRemoteV1/App/Windows.cs
#	mRemoteV1/Config/Settings/SettingsLoader.cs
#	mRemoteV1/Messages/WriterDecorators/MessageFocusDecorator.cs
#	mRemoteV1/UI/Controls/ConnectionTree/ConnectionTree.cs
#	mRemoteV1/UI/Forms/OptionsPages/ConnectionsPage.cs
#	mRemoteV1/UI/Forms/OptionsPages/CredentialsPage.cs
#	mRemoteV1/UI/Forms/OptionsPages/TabsPanelsPage.cs
#	mRemoteV1/UI/Forms/OptionsPages/UpdatesPage.cs
#	mRemoteV1/UI/Forms/frmChoosePanel.cs
#	mRemoteV1/UI/Forms/frmMain.cs
#	mRemoteV1/UI/Window/ConfigWindow.cs
#	mRemoteV1/UI/Window/ConnectionTreeWindow.cs
#	mRemoteV1/UI/Window/ErrorAndInfoWindow.cs
2018-08-24 18:14:54 -05:00
David Sparer
e05eb0807e fixed a few missed merge items 2018-07-23 15:19:29 -05:00
David Sparer
1aca1b7ae8 Merge branch 'develop' into remove_statics
# Conflicts:
#	mRemoteNGTests/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDeserializerTests.cs
#	mRemoteNGTests/mRemoteNGTests.csproj
#	mRemoteV1/App/Runtime.cs
#	mRemoteV1/Config/Connections/XmlConnectionsLoader.cs
#	mRemoteV1/Config/Serializers/ConnectionSerializers/Xml/XmlConnectionsDeserializer.cs
#	mRemoteV1/Connection/ConnectionsService.cs
#	mRemoteV1/UI/Forms/frmMain.cs
#	mRemoteV1/UI/Menu/MainFileMenu.cs
#	mRemoteV1/UI/Window/ConfigWindow.cs
#	mRemoteV1/UI/Window/ConnectionTreeWindow.cs
#	mRemoteV1/UI/Window/PortScanWindow.cs
2018-07-23 15:06:15 -05:00
David Sparer
75c866f7c1 remove unnecessary frmmain singleton property 2018-05-24 17:49:03 -05:00
David Sparer
c3ae438e9c fix failing test 2018-05-24 17:48:44 -05:00
David Sparer
314c989dae created IConnectionService interface and replaced usage with concrete type 2018-05-24 17:25:04 -05:00
David Sparer
8c350429b7 massive refactor of the rest of the frmmain statics 2018-05-22 21:31:22 -05:00
David Sparer
b21f2ffe65 removed some more default frmmain uses 2018-05-20 20:18:58 -05:00
David Sparer
66b307bff9 rdp protocol now no longer uses static frmmain ref 2018-05-20 20:06:22 -05:00
David Sparer
c43ef052c6 removed some frmmain static instance refs 2018-05-20 19:57:25 -05:00
David Sparer
d0a011d8ff Merge branch 'develop' into remove_statics 2018-05-20 11:08:29 -05:00
David Sparer
de9b78c5fb fix test 2018-05-20 09:51:35 -05:00
David Sparer
991505b043 fixed bug where connection properties weren't being passed to external tools 2018-05-20 09:42:31 -05:00
David Sparer
729166fc30 Merge branch 'develop' into remove_statics
# Conflicts:
#	mRemoteV1/UI/Forms/frmMain.Designer.cs
#	mRemoteV1/UI/Forms/frmMain.cs
#	mRemoteV1/UI/Menu/ViewMenu.cs
2018-05-20 09:29:55 -05:00
David Sparer
3fbad29017 removed a reference to static FrmMain 2018-03-12 21:43:01 -05:00
David Sparer
7a4b232695 updated a few more classes to not rely on Runtime 2018-03-04 12:23:19 -06:00
David Sparer
ba94e10cfa modified a few more classes to reduce reliance on Runtime 2018-03-04 12:04:32 -06:00
David Sparer
5093035f68 changed more classes to not rely on Runtime for the connections service 2018-03-04 11:52:58 -06:00
David Sparer
8159165968 modified some classes to request ConnectionsService as a ctor arg 2018-03-04 11:34:48 -06:00
David Sparer
5903481c87 made the Import class non static 2018-03-03 17:53:00 -06:00
David Sparer
e7afe5ea93 made some references to the connection service non static 2018-03-03 17:34:45 -06:00
David Sparer
f00dad3c96 moved several methods from Runtime to the connections service 2018-03-03 17:20:04 -06:00
David Sparer
db99a32c1d moved encryption key variable to the connections service where it makes more sense 2018-03-03 17:14:02 -06:00
David Sparer
c04bb44da3 fixed a composition bug and created a few tests 2018-03-03 13:25:42 -06:00
David Sparer
ba11746e6f removed ExternalToolsService var from Runtime 2018-03-03 12:47:37 -06:00
David Sparer
ced33027b8 made Shutdown and SettingsSaver non-static 2018-03-03 12:05:38 -06:00
David Sparer
0febc13ec7 removed use of the credential catalog Runtime var 2018-03-03 11:02:36 -06:00
David Sparer
05e62ff76f made Export class non static 2018-03-03 10:48:02 -06:00
David Sparer
107067cead removed unnecessary var in Runtime 2018-03-03 10:47:47 -06:00
David Sparer
13f51629af completed first round of fixes 2018-03-02 13:40:24 -06:00
David Sparer
8dc3303e0f first wave of changes 2018-03-02 06:38:55 -06:00
102 changed files with 1722 additions and 998 deletions

View File

@@ -0,0 +1,17 @@
using System.Windows.Forms;
using NUnit.Framework;
// Dont put this in a namespace. Leaving it by itself tells NUnit
// to run it on assembly load
[SetUpFixture]
public class AssemblyTestSetup
{
[OneTimeSetUp]
public void AssemblySetup()
{
// ensure window options set before any test window created
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
}
}

View File

@@ -1,12 +1,16 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.Config.Putty;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Security;
using mRemoteNG.Tree;
using mRemoteNGTests.Properties;
using NSubstitute;
using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml
@@ -18,7 +22,10 @@ namespace mRemoteNGTests.Config.Serializers.ConnectionSerializers.Xml
public void Setup(string confCons, string password)
{
_xmlConnectionsDeserializer = new XmlConnectionsDeserializer(() => password.ConvertToSecureString());
var connectionsService = new ConnectionsService(PuttySessionsManager.Instance,
new Import(Substitute.For<IWin32Window>()),
Substitute.For<IWin32Window>());
_xmlConnectionsDeserializer = new XmlConnectionsDeserializer(connectionsService, Substitute.For<IWin32Window>(), () => password.ConvertToSecureString());
_connectionTreeModel = _xmlConnectionsDeserializer.Deserialize(confCons);
}

View File

@@ -5,6 +5,7 @@ using mRemoteNG.Connection;
using mRemoteNG.Security;
using mRemoteNG.Tree;
using mRemoteNGTests.TestHelpers;
using NSubstitute;
using NUnit.Framework;
namespace mRemoteNGTests.Config.Serializers
@@ -18,7 +19,7 @@ namespace mRemoteNGTests.Config.Serializers
{
var model = CreateConnectionTreeModel();
var dataTable = CreateDataTable(model.RootNodes[0]);
_deserializer = new DataTableDeserializer();
_deserializer = new DataTableDeserializer(Substitute.For<IConnectionsService>());
var output = _deserializer.Deserialize(dataTable);
Assert.That(output.GetRecursiveChildList().Count(), Is.EqualTo(model.GetRecursiveChildList().Count()));
}
@@ -27,7 +28,7 @@ namespace mRemoteNGTests.Config.Serializers
public void WeCanDeserializeASingleEntry()
{
var dataTable = CreateDataTable(new ConnectionInfo());
_deserializer = new DataTableDeserializer();
_deserializer = new DataTableDeserializer(Substitute.For<IConnectionsService>());
var output = _deserializer.Deserialize(dataTable);
Assert.That(output.GetRecursiveChildList().Count(), Is.EqualTo(1));
}

View File

@@ -5,6 +5,7 @@ using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.SSH;
using mRemoteNG.Container;
using mRemoteNG.Tree.Root;
using NSubstitute;
using NUnit.Framework;
@@ -13,11 +14,13 @@ namespace mRemoteNGTests.Connection
public class ConnectionInfoTests
{
private ConnectionInfo _connectionInfo;
private IConnectionsService _connectionsService;
private const string TestDomain = "somedomain";
[SetUp]
public void Setup()
{
_connectionsService = Substitute.For<IConnectionsService>();
_connectionInfo = new ConnectionInfo();
}
@@ -79,7 +82,7 @@ namespace mRemoteNGTests.Connection
{
var eventWasCalled = false;
_connectionInfo.PropertyChanged += (sender, args) => eventWasCalled = true;
_connectionInfo.OpenConnections.Add(new ProtocolSSH2());
_connectionInfo.OpenConnections.Add(new ProtocolSSH2(_connectionsService));
Assert.That(eventWasCalled);
}
@@ -88,7 +91,7 @@ namespace mRemoteNGTests.Connection
{
var nameOfModifiedProperty = "";
_connectionInfo.PropertyChanged += (sender, args) => nameOfModifiedProperty = args.PropertyName;
_connectionInfo.OpenConnections.Add(new ProtocolSSH2());
_connectionInfo.OpenConnections.Add(new ProtocolSSH2(_connectionsService));
Assert.That(nameOfModifiedProperty, Is.EqualTo("OpenConnections"));
}

View File

@@ -1,31 +1,50 @@
using System.Collections.ObjectModel;
using System;
using System.Security;
using System.Threading;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.App.Update;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Config.Putty;
using mRemoteNG.Config.Settings;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Credential.Repositories;
using mRemoteNG.Tools;
using mRemoteNG.Tools.CustomCollections;
using mRemoteNG.UI.Controls;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.Window;
using NSubstitute;
using NUnit.Framework;
using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNGTests.Connection.Protocol
{
public class IntegratedProgramTests
{
private readonly ExternalTool _extTool = new ExternalTool
{
DisplayName = "notepad",
FileName = @"%windir%\system32\notepad.exe",
Arguments = "",
TryIntegrate = true
};
public class IntegratedProgramTests
{
private ExternalToolsService _externalToolsService;
private IConnectionInitiator _connectionInitiator;
[Test]
[OneTimeSetUp]
public void OneTimeSetUp()
{
_connectionInitiator = Substitute.For<IConnectionInitiator>();
var extTool = new ExternalTool(_connectionInitiator, Substitute.For<IConnectionsService>())
{
DisplayName = "notepad",
FileName = @"%windir%\system32\notepad.exe",
Arguments = "",
TryIntegrate = true
};
_externalToolsService = new ExternalToolsService();
_externalToolsService.ExternalTools.Add(extTool);
}
[Test]
[Apartment(ApartmentState.STA)]
public void CanStartExternalApp()
{
SetExternalToolList(_extTool);
var sut = new IntegratedProgram();
var sut = new IntegratedProgram(_externalToolsService, Substitute.For<IConnectionsService>());
sut.InterfaceControl = BuildInterfaceControl("notepad", sut);
sut.Initialize();
var appStarted = sut.Connect();
@@ -34,23 +53,42 @@ namespace mRemoteNGTests.Connection.Protocol
}
[Test]
[Apartment(ApartmentState.STA)]
public void ConnectingToExternalAppThatDoesntExistDoesNothing()
{
SetExternalToolList(_extTool);
var sut = new IntegratedProgram();
var sut = new IntegratedProgram(_externalToolsService, Substitute.For<IConnectionsService>());
sut.InterfaceControl = BuildInterfaceControl("doesntExist", sut);
var appInitialized = sut.Initialize();
Assert.That(appInitialized, Is.False);
}
private void SetExternalToolList(ExternalTool externalTool)
{
Runtime.ExternalToolsService.ExternalTools = new FullyObservableCollection<ExternalTool> {externalTool};
}
private InterfaceControl BuildInterfaceControl(string extAppName, ProtocolBase sut)
{
var connectionWindow = new ConnectionWindow(new DockContent());
var frmMain = new FrmMain();
var import = new Import(Substitute.For<IWin32Window>());
var connectionsService = new ConnectionsService(PuttySessionsManager.Instance, import, frmMain);
var configWindow = new ConfigWindow(new DockContent(), connectionsService);
var sshTransferWindow = new SSHTransferWindow();
var connectionTreeWindow = new ConnectionTreeWindow(new DockContent(), _connectionInitiator, connectionsService);
Func<SecureString> encryptionKeySelectionFunc = () => connectionsService.EncryptionKey;
var connectionTree = connectionTreeWindow.ConnectionTree;
var export = new Export(new CredentialRepositoryList(), connectionsService, frmMain);
var connectionTreeContextMenu = new ConnectionContextMenu(connectionTree, _connectionInitiator, sshTransferWindow, export, _externalToolsService, import, connectionsService);
connectionTreeWindow.ConnectionTreeContextMenu = connectionTreeContextMenu;
var errorAndInfoWindow = new ErrorAndInfoWindow(new DockContent(), new DockPanel(), connectionTreeWindow);
var screenshotManagerWindow = new ScreenshotManagerWindow(new DockContent(), new DockPanel());
var shutdown = new Shutdown(new SettingsSaver(new ExternalToolsService()), new ConnectionsService(PuttySessionsManager.Instance, import, frmMain), frmMain);
var appUpdater = new AppUpdater(encryptionKeySelectionFunc);
Func<UpdateWindow> updateWindowBuilder = () => new UpdateWindow(new DockContent(), shutdown, appUpdater);
Func<NotificationAreaIcon> notificationAreaIconBuilder = () => new NotificationAreaIcon(frmMain, _connectionInitiator, shutdown, connectionsService);
Func<ExternalToolsWindow> externalToolsWindowBuilder = () => new ExternalToolsWindow(_connectionInitiator, _externalToolsService, () => connectionTree.SelectedNode, frmMain, connectionsService);
Func<PortScanWindow> portScanWindowBuilder = () => new PortScanWindow(connectionTreeWindow, import);
Func<ActiveDirectoryImportWindow> activeDirectoryImportWindowBuilder = () => new ActiveDirectoryImportWindow(() => connectionTreeWindow.SelectedNode, import, connectionsService);
var databaseConnectorFactory = new DatabaseConnectorFactory(encryptionKeySelectionFunc);
var windows = new Windows(_connectionInitiator, connectionTreeWindow, configWindow, errorAndInfoWindow, screenshotManagerWindow,
sshTransferWindow, updateWindowBuilder, notificationAreaIconBuilder, externalToolsWindowBuilder,
connectionsService, portScanWindowBuilder, activeDirectoryImportWindowBuilder, appUpdater, databaseConnectorFactory, frmMain);
var connectionWindow = new ConnectionWindow(new DockContent(), _connectionInitiator, windows, _externalToolsService, frmMain);
var connectionInfo = new ConnectionInfo {ExtApp = extAppName};
return new InterfaceControl(connectionWindow, sut, connectionInfo);
}

View File

@@ -1,9 +1,12 @@
using System.Collections;
using System.Collections.Specialized;
using mRemoteNG.Config.Putty;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.SSH;
using mRemoteNG.Connection.Protocol.Telnet;
using mRemoteNG.Connection.Protocol.VNC;
using NSubstitute;
using NUnit.Framework;
@@ -20,9 +23,10 @@ namespace mRemoteNGTests.Connection.Protocol
[SetUp]
public void Setup()
{
var connectionService = Substitute.For<IConnectionsService>();
_protocolList = new ProtocolList();
_protocol1 = new ProtocolTelnet();
_protocol2 = new ProtocolSSH2();
_protocol1 = new ProtocolTelnet(connectionService);
_protocol2 = new ProtocolSSH2(connectionService);
_protocol3 = new ProtocolVNC();
}

View File

@@ -1,7 +1,8 @@
using System;
using System.Linq;
using System.Xml.Linq;
using mRemoteNG.Config.Serializers;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.Config.Putty;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection;
using mRemoteNG.Container;
@@ -9,6 +10,7 @@ using mRemoteNG.Security;
using mRemoteNG.Security.Factories;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using NSubstitute;
using NUnit.Framework;
@@ -31,7 +33,8 @@ namespace mRemoteNGTests.IntegrationTests
_originalModel.RootNodes.OfType<RootNodeInfo>().First().PasswordString.ConvertToSecureString(),
new SaveFilter());
_serializer = new XmlConnectionsSerializer(cryptoProvider, nodeSerializer);
_deserializer = new XmlConnectionsDeserializer();
var mockWindow = Substitute.For<IWin32Window>();
_deserializer = new XmlConnectionsDeserializer(new ConnectionsService(PuttySessionsManager.Instance, new Import(mockWindow), mockWindow), mockWindow);
}
[TearDown]
@@ -139,4 +142,4 @@ namespace mRemoteNGTests.IntegrationTests
return connectionTreeModel;
}
}
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections;
using mRemoteNG.Connection;
using mRemoteNG.Tools;
using NSubstitute;
using NUnit.Framework;
@@ -34,7 +35,7 @@ namespace mRemoteNGTests.Tools
MacAddress = TestString,
UserField = TestString
};
_argumentParser = new ExternalToolArgumentParser(connectionInfo);
_argumentParser = new ExternalToolArgumentParser(connectionInfo, Substitute.For<IConnectionsService>());
}
[OneTimeTearDown]
@@ -52,7 +53,7 @@ namespace mRemoteNGTests.Tools
[Test]
public void NullConnectionInfoResultsInEmptyVariables()
{
var parser = new ExternalToolArgumentParser(null);
var parser = new ExternalToolArgumentParser(null, Substitute.For<IConnectionsService>());
var parsedText = parser.ParseArguments("test %USERNAME% test");
Assert.That(parsedText, Is.EqualTo("test test"));
}

View File

@@ -0,0 +1,49 @@
using System;
using mRemoteNG.Connection;
using mRemoteNG.Tools;
using mRemoteNG.UI.Controls;
using NSubstitute;
using NUnit.Framework;
namespace mRemoteNGTests.UI.Controls
{
public class ExternalToolsToolStripTests
{
private ExternalToolsToolStrip _externalToolsToolStrip;
[SetUp]
public void Setup()
{
_externalToolsToolStrip = new ExternalToolsToolStrip();
}
[TearDown]
public void Teardown()
{
_externalToolsToolStrip.Dispose();
}
[Test]
public void SettingExternalToolsServiceToNullThrowsException()
{
Assert.Throws<ArgumentNullException>(() => _externalToolsToolStrip.ExternalToolsService = null);
}
[Test]
public void AddExternalToolsToToolBarCreatesControlsForAllExternalTools()
{
var externaltoolsService = new ExternalToolsService();
externaltoolsService.ExternalTools.Add(BuildExternalTool());
externaltoolsService.ExternalTools.Add(BuildExternalTool());
_externalToolsToolStrip.ExternalToolsService = externaltoolsService;
_externalToolsToolStrip.AddExternalToolsToToolBar();
Assert.That(_externalToolsToolStrip.Items.Count, Is.EqualTo(2));
}
private ExternalTool BuildExternalTool()
{
return new ExternalTool(Substitute.For<IConnectionInitiator>(), Substitute.For<IConnectionsService>());
}
}
}

View File

@@ -6,7 +6,6 @@ namespace mRemoteNGTests.UI.Controls
{
public TextBoxExtensionsTestForm()
{
Application.EnableVisualStyles();
InitializeComponent();
}
}

View File

@@ -30,7 +30,8 @@ namespace mRemoteNGTests.UI.Controls
{
const string text = "Type Here";
var textBox = new TextBoxTester(_textBoxExtensionsTestForm.textBox1.Name);
Assert.That(textBox.Properties.SetCueBannerText(text), Is.True);
var textWasSet = textBox.Properties.SetCueBannerText(text);
Assert.That(textWasSet, Is.True);
}
[Test]

View File

@@ -0,0 +1,16 @@
using System.Threading;
using mRemoteNG.UI.Forms;
using NUnit.Framework;
namespace mRemoteNGTests.UI.Forms
{
public class FrmMainTests
{
[Test]
[Apartment(ApartmentState.STA)]
public void CanCreateFrmMain()
{
var frmMain = new FrmMain();
}
}
}

View File

@@ -1,9 +1,24 @@
using NUnit.Framework;
using System;
using System.Security;
using System.Windows.Forms;
using System.Xml.Linq;
using mRemoteNG.App;
using mRemoteNG.App.Update;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Config.Putty;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Config.Settings;
using mRemoteNG.Connection;
using mRemoteNG.Security;
using mRemoteNG.Tools;
using mRemoteNG.UI.Forms;
using NSubstitute;
using NUnit.Framework;
namespace mRemoteNGTests.UI.Forms
{
public class OptionsFormSetupAndTeardown
public class OptionsFormSetupAndTeardown
{
protected frmOptions _optionsForm;
@@ -15,7 +30,16 @@ namespace mRemoteNGTests.UI.Forms
[SetUp]
public void Setup()
{
_optionsForm = new frmOptions();
var frmMain = new FrmMain();
var connectionInitiator = Substitute.For<IConnectionInitiator>();
var import = new Import(Substitute.For<IWin32Window>());
var shutdown = new Shutdown(new SettingsSaver(new ExternalToolsService()), new ConnectionsService(PuttySessionsManager.Instance, import, frmMain), frmMain);
var connectionsService = new ConnectionsService(PuttySessionsManager.Instance, import, frmMain);
Func<NotificationAreaIcon> notificationIconBuilder = () => new NotificationAreaIcon(frmMain, connectionInitiator, shutdown, connectionsService);
Func<SecureString> encryptionKeySelectionFunc = () => connectionsService.EncryptionKey;
var databaseConnectorFactory = new DatabaseConnectorFactory(encryptionKeySelectionFunc);
var appUpdater = new AppUpdater(encryptionKeySelectionFunc);
_optionsForm = new frmOptions(connectionInitiator, type => {}, notificationIconBuilder, connectionsService, appUpdater, databaseConnectorFactory, frmMain);
_optionsForm.Show();
}

View File

@@ -8,7 +8,9 @@ using mRemoteNG.Connection.Protocol.VNC;
using mRemoteNG.Container;
using mRemoteNG.Tree.Root;
using mRemoteNG.UI.Window;
using NSubstitute;
using NUnit.Framework;
using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNGTests.UI.Window.ConfigWindowTests
{
@@ -19,7 +21,7 @@ namespace mRemoteNGTests.UI.Window.ConfigWindowTests
[SetUp]
public void Setup()
{
_configWindow = new ConfigWindow
_configWindow = new ConfigWindow(new DockContent(), Substitute.For<IConnectionsService>())
{
PropertiesVisible = true
};

View File

@@ -2,7 +2,9 @@
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.UI.Window;
using NSubstitute;
using NUnit.Framework;
using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNGTests.UI.Window.ConfigWindowTests
{
@@ -20,7 +22,7 @@ namespace mRemoteNGTests.UI.Window.ConfigWindowTests
ConnectionInfo = ConfigWindowGeneralTests.ConstructConnectionInfo(Protocol, TestAgainstContainerInfo);
ExpectedPropertyList = ConfigWindowGeneralTests.BuildExpectedConnectionInfoPropertyList(Protocol, TestAgainstContainerInfo);
ConfigWindow = new ConfigWindow
ConfigWindow = new ConfigWindow(new DockContent(), Substitute.For<IConnectionsService>())
{
PropertiesVisible = true,
};

View File

@@ -1,19 +1,38 @@
using System.Threading;
using System.Security;
using System.Threading;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.Config.Putty;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection;
using mRemoteNG.Credential.Repositories;
using mRemoteNG.Security;
using mRemoteNG.Security.SymmetricEncryption;
using mRemoteNG.Tools;
using mRemoteNG.UI.Controls;
using mRemoteNG.UI.Window;
using NSubstitute;
using NUnit.Framework;
using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNGTests.UI.Window
{
public class ConnectionTreeWindowTests
public class ConnectionTreeWindowTests
{
private ConnectionTreeWindow _connectionTreeWindow;
[SetUp]
public void Setup()
{
_connectionTreeWindow = new ConnectionTreeWindow(new DockContent());
var connectionInitiator = Substitute.For<IConnectionInitiator>();
var connectionTree = new ConnectionTree();
var sshTransferWindow = new SSHTransferWindow();
var externalToolsService = new ExternalToolsService();
var import = new Import(Substitute.For<IWin32Window>());
var connectionsService = new ConnectionsService(PuttySessionsManager.Instance, import, connectionTree);
var export = new Export(new CredentialRepositoryList(), connectionsService, connectionTree);
var connectionContextMenu = new ConnectionContextMenu(connectionTree, connectionInitiator, sshTransferWindow, export, externalToolsService, import, connectionsService);
_connectionTreeWindow = new ConnectionTreeWindow(new DockContent(), connectionInitiator, connectionsService) {ConnectionTreeContextMenu = connectionContextMenu};
}
[TearDown]

View File

@@ -109,6 +109,7 @@
</Choose>
<ItemGroup>
<Compile Include="App\UpdaterTests.cs" />
<Compile Include="AssemblyTestSetup.cs" />
<Compile Include="BinaryFileTests.cs" />
<Compile Include="Config\Connections\Multiuser\ConnectionsUpdateAvailableEventArgsTests.cs" />
<Compile Include="Config\DataProviders\FileBackupCreatorTests.cs" />
@@ -208,6 +209,7 @@
<Compile Include="Tree\RootNodeInfoTests.cs" />
<Compile Include="Tree\ClickHandlers\SwitchToConnectionClickHandlerTests.cs" />
<Compile Include="Tree\SelectedConnectionDeletionConfirmerTests.cs" />
<Compile Include="UI\Controls\ExternalToolsToolStripTests.cs" />
<Compile Include="UI\Controls\ConnectionTreeTests.cs" />
<Compile Include="UI\Controls\PageSequenceTests.cs" />
<Compile Include="UI\Controls\SecureTextBoxTestForm.cs">
@@ -230,6 +232,7 @@
<DependentUpon>TextBoxExtensionsTestForm.cs</DependentUpon>
</Compile>
<Compile Include="UI\Controls\TextBoxExtensionsTests.cs" />
<Compile Include="UI\Forms\FrmMainTests.cs" />
<Compile Include="UI\Forms\OptionsFormSetupAndTeardown.cs" />
<Compile Include="UI\Forms\PasswordFormTests.cs" />
<Compile Include="UI\WindowListTests.cs" />

View File

@@ -6,25 +6,35 @@ using System;
using System.Diagnostics;
using System.Windows.Forms;
using mRemoteNG.Messages;
using mRemoteNG.Tools;
namespace mRemoteNG.App
{
public static class CompatibilityChecker
public class CompatibilityChecker
{
public static void CheckCompatibility(MessageCollector messageCollector)
private readonly MessageCollector _messageCollector;
private readonly IWin32Window _dialogWindowParent;
public CompatibilityChecker(MessageCollector messageCollector, IWin32Window dialogWindowParent)
{
CheckFipsPolicy(messageCollector);
CheckLenovoAutoScrollUtility(messageCollector);
_messageCollector = messageCollector.ThrowIfNull(nameof(messageCollector));
_dialogWindowParent = dialogWindowParent.ThrowIfNull(nameof(dialogWindowParent));
}
private static void CheckFipsPolicy(MessageCollector messageCollector)
public void CheckCompatibility()
{
messageCollector.AddMessage(MessageClass.InformationMsg, "Checking FIPS Policy...", true);
CheckFipsPolicy();
CheckLenovoAutoScrollUtility();
}
private void CheckFipsPolicy()
{
_messageCollector.AddMessage(MessageClass.InformationMsg, "Checking FIPS Policy...", true);
if (!FipsPolicyEnabledForServer2003() && !FipsPolicyEnabledForServer2008AndNewer()) return;
var errorText = string.Format(Language.strErrorFipsPolicyIncompatible, GeneralAppInfo.ProductName,
GeneralAppInfo.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
messageCollector.AddMessage(MessageClass.ErrorMsg, errorText, true);
MessageBox.Show(FrmMain.Default, errorText);
_messageCollector.AddMessage(MessageClass.ErrorMsg, errorText, true);
MessageBox.Show(_dialogWindowParent, errorText);
Environment.Exit(1);
}
@@ -46,9 +56,9 @@ namespace mRemoteNG.App
return (int)fipsPolicy != 0;
}
private static void CheckLenovoAutoScrollUtility(MessageCollector messageCollector)
private void CheckLenovoAutoScrollUtility()
{
messageCollector.AddMessage(MessageClass.InformationMsg, "Checking Lenovo AutoScroll Utility...", true);
_messageCollector.AddMessage(MessageClass.InformationMsg, "Checking Lenovo AutoScroll Utility...", true);
if (!Settings.Default.CompatibilityWarnLenovoAutoScrollUtility)
return;
@@ -60,7 +70,7 @@ namespace mRemoteNG.App
}
catch (InvalidOperationException ex)
{
messageCollector.AddExceptionMessage("Error in CheckLenovoAutoScrollUtility", ex);
_messageCollector.AddExceptionMessage("Error in CheckLenovoAutoScrollUtility", ex);
}
if (proccesses.Length <= 0) return;

View File

@@ -8,8 +8,10 @@ using mRemoteNG.Config.Serializers.Csv;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Credential;
using mRemoteNG.Security;
using mRemoteNG.Security.Factories;
using mRemoteNG.Tools;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using mRemoteNG.UI.Forms;
@@ -17,9 +19,20 @@ using mRemoteNG.UI.Forms;
namespace mRemoteNG.App
{
public static class Export
public class Export
{
public static void ExportToFile(ConnectionInfo selectedNode, ConnectionTreeModel connectionTreeModel)
private readonly IConnectionsService _connectionsService;
private readonly ICredentialRepositoryList _credentialRepositoryList;
private readonly IWin32Window _dialogWindowParent;
public Export(ICredentialRepositoryList credentialRepositoryList, IConnectionsService connectionsService, IWin32Window dialogWindowParent)
{
_credentialRepositoryList = credentialRepositoryList.ThrowIfNull(nameof(credentialRepositoryList));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
_dialogWindowParent = dialogWindowParent.ThrowIfNull(nameof(dialogWindowParent));
}
public void ExportToFile(ConnectionInfo selectedNode, ConnectionTreeModel connectionTreeModel)
{
try
{
@@ -36,7 +49,7 @@ namespace mRemoteNG.App
exportForm.SelectedConnection = selectedNode;
}
if (exportForm.ShowDialog(FrmMain.Default) != DialogResult.OK)
if (exportForm.ShowDialog(_dialogWindowParent) != DialogResult.OK)
return;
ConnectionInfo exportTarget;
@@ -69,7 +82,7 @@ namespace mRemoteNG.App
}
}
private static void SaveExportFile(string fileName, SaveFormat saveFormat, SaveFilter saveFilter, ConnectionInfo exportTarget)
private void SaveExportFile(string fileName, SaveFormat saveFormat, SaveFilter saveFilter, ConnectionInfo exportTarget)
{
try
{
@@ -86,7 +99,7 @@ namespace mRemoteNG.App
serializer = new XmlConnectionsSerializer(cryptographyProvider, connectionNodeSerializer);
break;
case SaveFormat.mRCSV:
serializer = new CsvConnectionsSerializerMremotengFormat(saveFilter, Runtime.CredentialProviderCatalog);
serializer = new CsvConnectionsSerializerMremotengFormat(saveFilter, _credentialRepositoryList);
break;
default:
throw new ArgumentOutOfRangeException(nameof(saveFormat), saveFormat, null);
@@ -101,7 +114,7 @@ namespace mRemoteNG.App
}
finally
{
Runtime.ConnectionsService.RemoteConnectionsSyncronizer?.Enable();
_connectionsService.RemoteConnectionsSyncronizer?.Enable();
}
}
}

View File

@@ -3,15 +3,26 @@ using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using mRemoteNG.Config.Import;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Container;
using mRemoteNG.Tools;
namespace mRemoteNG.App
{
public static class Import
public class Import
{
public static void ImportFromFile(ContainerInfo importDestinationContainer)
private readonly IWin32Window _dialogWindowParent;
public Import(IWin32Window dialogWindowParent)
{
_dialogWindowParent = dialogWindowParent.ThrowIfNull(nameof(dialogWindowParent));
}
// TODO - this is only a property to break up a circular dependency. move this to ctor when able
public IConnectionsService ConnectionsService { get; set; }
public void ImportFromFile(ContainerInfo importDestinationContainer)
{
try
{
@@ -50,7 +61,7 @@ namespace mRemoteNG.App
}
}
Runtime.ConnectionsService.SaveConnectionsAsync();
ConnectionsService.SaveConnectionsAsync();
}
}
catch (Exception ex)
@@ -59,12 +70,12 @@ namespace mRemoteNG.App
}
}
public static void ImportFromActiveDirectory(string ldapPath, ContainerInfo importDestinationContainer, bool importSubOu)
public void ImportFromActiveDirectory(string ldapPath, ContainerInfo importDestinationContainer, bool importSubOu)
{
try
{
ActiveDirectoryImporter.Import(ldapPath, importDestinationContainer, importSubOu);
Runtime.ConnectionsService.SaveConnectionsAsync();
ConnectionsService.SaveConnectionsAsync();
}
catch (Exception ex)
{
@@ -72,13 +83,13 @@ namespace mRemoteNG.App
}
}
public static void ImportFromPortScan(IEnumerable<ScanHost> hosts, ProtocolType protocol, ContainerInfo importDestinationContainer)
public void ImportFromPortScan(IEnumerable<ScanHost> hosts, ProtocolType protocol, ContainerInfo importDestinationContainer)
{
try
{
var importer = new PortScanImporter(protocol);
importer.Import(hosts, importDestinationContainer);
Runtime.ConnectionsService.SaveConnectionsAsync();
ConnectionsService.SaveConnectionsAsync();
}
catch (Exception ex)
{
@@ -86,14 +97,14 @@ namespace mRemoteNG.App
}
}
private static IConnectionImporter<string> BuildConnectionImporterFromFileExtension(string fileName)
private IConnectionImporter<string> BuildConnectionImporterFromFileExtension(string fileName)
{
// TODO: Use the file contents to determine the file type instead of trusting the extension
var extension = Path.GetExtension(fileName) ?? "";
switch (extension.ToLowerInvariant())
{
case ".xml":
return new MRemoteNGXmlImporter();
return new MRemoteNGXmlImporter(ConnectionsService, _dialogWindowParent);
case ".csv":
return new MRemoteNGCsvImporter();
case ".rdp":

View File

@@ -1,18 +1,24 @@
using System.IO;
using mRemoteNG.Config.Connections;
using mRemoteNG.Connection;
using mRemoteNG.Tools;
using System.IO;
namespace mRemoteNG.App.Initialization
{
public class CredsAndConsSetup
{
public void LoadCredsAndCons()
public class CredsAndConsSetup
{
private readonly IConnectionsService _connectionsService;
public CredsAndConsSetup(IConnectionsService connectionsService)
{
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
}
public void LoadCredsAndCons()
{
new SaveConnectionsOnEdit(Runtime.ConnectionsService);
if (Settings.Default.FirstStart && !Settings.Default.LoadConsFromCustomLocation && !File.Exists(_connectionsService.GetStartupConnectionFileName()))
_connectionsService.NewConnectionsFile(_connectionsService.GetStartupConnectionFileName());
if (Settings.Default.FirstStart && !Settings.Default.LoadConsFromCustomLocation && !File.Exists(Runtime.ConnectionsService.GetStartupConnectionFileName()))
Runtime.ConnectionsService.NewConnectionsFile(Runtime.ConnectionsService.GetStartupConnectionFileName());
Runtime.LoadConnections();
_connectionsService.LoadConnections();
}
}
}

View File

@@ -3,10 +3,13 @@ using System.Linq;
using mRemoteNG.Messages;
using mRemoteNG.Messages.MessageWriters;
using mRemoteNG.Messages.WriterDecorators;
using mRemoteNG.Tools;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.Window;
namespace mRemoteNG.App.Initialization
{
public class MessageCollectorSetup
public class MessageCollectorSetup
{
public static void SetupMessageCollector(MessageCollector messageCollector, IList<IMessageWriter> messageWriterList)
{
@@ -19,13 +22,13 @@ namespace mRemoteNG.App.Initialization
};
}
public static void BuildMessageWritersFromSettings(IList<IMessageWriter> messageWriterList)
public static void BuildMessageWritersFromSettings(IList<IMessageWriter> messageWriterList, FrmMain frmMain, ErrorAndInfoWindow errorAndInfoWindow)
{
#if DEBUG
messageWriterList.Add(BuildDebugConsoleWriter());
#endif
messageWriterList.Add(BuildTextLogMessageWriter());
messageWriterList.Add(BuildNotificationPanelMessageWriter());
messageWriterList.Add(BuildNotificationPanelMessageWriter(frmMain, errorAndInfoWindow));
messageWriterList.Add(BuildPopupMessageWriter());
}
@@ -42,16 +45,17 @@ namespace mRemoteNG.App.Initialization
);
}
private static IMessageWriter BuildNotificationPanelMessageWriter()
private static IMessageWriter BuildNotificationPanelMessageWriter(FrmMain frmMain, ErrorAndInfoWindow errorAndInfoWindow)
{
return new OnlyLogMessageFilter(
errorAndInfoWindow.ThrowIfNull(nameof(errorAndInfoWindow));
return new OnlyLogMessageFilter(
new MessageTypeFilterDecorator(
new NotificationPanelMessageFilteringOptions(),
new MessageFocusDecorator(
Windows.ErrorsForm,
frmMain,
errorAndInfoWindow,
new NotificationPanelSwitchOnMessageFilteringOptions(),
new NotificationPanelMessageWriter(Windows.ErrorsForm)
new NotificationPanelMessageWriter(errorAndInfoWindow)
)
)
);

View File

@@ -26,7 +26,8 @@ namespace mRemoteNG.App
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(FrmMain.Default);
var frmMain = new FrmMain();
Application.Run(frmMain);
}
public static void CloseSingletonInstanceMutex()

View File

@@ -1,24 +1,11 @@
using System;
using System.IO;
using System.Security;
using System.Threading;
using System.Windows.Forms;
using mRemoteNG.App.Info;
using mRemoteNG.Config.Putty;
using mRemoteNG.Connection;
using mRemoteNG.Credential;
using mRemoteNG.Credential.Repositories;
using mRemoteNG.Messages;
using mRemoteNG.Security;
using mRemoteNG.Tools;
using mRemoteNG.Tree.Root;
using mRemoteNG.UI;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.TaskDialog;
namespace mRemoteNG.App
{
public static class Runtime
public class Runtime
{
public static bool IsPortableEdition
{
@@ -32,153 +19,7 @@ namespace mRemoteNG.App
}
}
public static WindowList WindowList { get; set; }
public static MessageCollector MessageCollector { get; } = new MessageCollector();
public static NotificationAreaIcon NotificationAreaIcon { get; set; }
public static ExternalToolsService ExternalToolsService { get; } = new ExternalToolsService();
public static SecureString EncryptionKey { get; set; } = new RootNodeInfo(RootNodeType.Connection).PasswordString.ConvertToSecureString();
public static ICredentialRepositoryList CredentialProviderCatalog { get; } = new CredentialRepositoryList();
public static ConnectionsService ConnectionsService { get; } = new ConnectionsService(PuttySessionsManager.Instance);
#region Connections Loading/Saving
public static void LoadConnectionsAsync()
{
_withDialog = false;
var t = new Thread(LoadConnectionsBGd);
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
private static bool _withDialog;
private static void LoadConnectionsBGd()
{
LoadConnections(_withDialog);
}
public static void LoadConnections(bool withDialog = false)
{
var connectionFileName = "";
try
{
// disable sql update checking while we are loading updates
ConnectionsService.RemoteConnectionsSyncronizer?.Disable();
if (!Settings.Default.UseSQLServer)
{
if (withDialog)
{
var loadDialog = DialogFactory.BuildLoadConnectionsDialog();
if (loadDialog.ShowDialog() != DialogResult.OK) return;
connectionFileName = loadDialog.FileName;
}
else
{
connectionFileName = ConnectionsService.GetStartupConnectionFileName();
}
}
ConnectionsService.LoadConnections(Settings.Default.UseSQLServer, false, connectionFileName);
if (Settings.Default.UseSQLServer)
{
ConnectionsService.LastSqlUpdate = DateTime.Now;
}
// re-enable sql update checking after updates are loaded
ConnectionsService.RemoteConnectionsSyncronizer?.Enable();
}
catch (Exception ex)
{
if (Settings.Default.UseSQLServer)
{
MessageCollector.AddExceptionMessage(Language.strLoadFromSqlFailed, ex);
var commandButtons = string.Join("|", Language.strCommandTryAgain, Language.strCommandOpenConnectionFile, string.Format(Language.strCommandExitProgram, Application.ProductName));
CTaskDialog.ShowCommandBox(Application.ProductName, Language.strLoadFromSqlFailed, Language.strLoadFromSqlFailedContent, MiscTools.GetExceptionMessageRecursive(ex), "", "", commandButtons, false, ESysIcons.Error, ESysIcons.Error);
switch (CTaskDialog.CommandButtonResult)
{
case 0:
LoadConnections(withDialog);
return;
case 1:
Settings.Default.UseSQLServer = false;
LoadConnections(true);
return;
default:
Application.Exit();
return;
}
}
if (ex is FileNotFoundException && !withDialog)
{
MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotBeLoadedNew, connectionFileName), ex, MessageClass.InformationMsg);
string[] commandButtons =
{
Language.ConfigurationCreateNew,
Language.ConfigurationCustomPath,
Language.ConfigurationImportFile,
Language.strMenuExit
};
var answered = false;
while (!answered)
{
try
{
CTaskDialog.ShowTaskDialogBox(
GeneralAppInfo.ProductName,
Language.ConnectionFileNotFound,
"", "", "", "", "",
string.Join(" | ", commandButtons),
ETaskDialogButtons.None,
ESysIcons.Question,
ESysIcons.Question);
switch (CTaskDialog.CommandButtonResult)
{
case 0:
ConnectionsService.NewConnectionsFile(connectionFileName);
answered = true;
break;
case 1:
LoadConnections(true);
answered = true;
break;
case 2:
ConnectionsService.NewConnectionsFile(connectionFileName);
Import.ImportFromFile(ConnectionsService.ConnectionTreeModel.RootNodes[0]);
answered = true;
break;
case 3:
Application.Exit();
answered = true;
break;
}
}
catch (Exception exc)
{
MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotBeLoadedNew, connectionFileName), exc, MessageClass.InformationMsg);
}
}
return;
}
MessageCollector.AddExceptionStackTrace(string.Format(Language.strConnectionsFileCouldNotBeLoaded, connectionFileName), ex);
if (connectionFileName != ConnectionsService.GetStartupConnectionFileName())
{
LoadConnections(withDialog);
}
else
{
MessageBox.Show(FrmMain.Default,
string.Format(Language.strErrorStartupConnectionFileLoad, Environment.NewLine, Application.ProductName, ConnectionsService.GetStartupConnectionFileName(), MiscTools.GetExceptionMessageRecursive(ex)),
@"Could not load startup file.", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.Exit();
}
}
}
#endregion
}
}

View File

@@ -1,31 +1,38 @@
using System.Windows.Forms;
using mRemoteNG.Tools;
using mRemoteNG.UI.Forms;
using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNG.App
{
public static class Screens
public class Screens
{
public static void SendFormToScreen(Screen screen)
private readonly FrmMain _frmMain;
public Screens(FrmMain frmMain)
{
_frmMain = frmMain.ThrowIfNull(nameof(frmMain));
}
public void SendFormToScreen(Screen screen)
{
var frmMain = FrmMain.Default;
var wasMax = false;
if (frmMain.WindowState == FormWindowState.Maximized)
if (_frmMain.WindowState == FormWindowState.Maximized)
{
wasMax = true;
frmMain.WindowState = FormWindowState.Normal;
_frmMain.WindowState = FormWindowState.Normal;
}
frmMain.Location = screen.Bounds.Location;
_frmMain.Location = screen.Bounds.Location;
if (wasMax)
{
frmMain.WindowState = FormWindowState.Maximized;
_frmMain.WindowState = FormWindowState.Maximized;
}
}
public static void SendPanelToScreen(DockContent panel, Screen screen)
public void SendPanelToScreen(DockContent panel, Screen screen)
{
panel.DockState = DockState.Float;
if (panel.ParentForm == null) return;

View File

@@ -3,29 +3,41 @@ using System;
using System.Diagnostics;
using System.Windows.Forms;
using mRemoteNG.Config.Putty;
using mRemoteNG.Config.Settings;
using mRemoteNG.Connection;
using mRemoteNG.UI.Controls;
using mRemoteNG.UI.Forms;
// ReSharper disable ArrangeAccessorOwnerBody
namespace mRemoteNG.App
{
public static class Shutdown
public class Shutdown
{
private readonly SettingsSaver _settingsSaver;
private readonly IConnectionsService _connectionsService;
private readonly FrmMain _frmMain;
private static string _updateFilePath;
public Shutdown(SettingsSaver settingsSaver, IConnectionsService connectionsService, FrmMain frmMain)
{
_settingsSaver = settingsSaver.ThrowIfNull(nameof(settingsSaver));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
_frmMain = frmMain.ThrowIfNull(nameof(frmMain));
}
private static bool UpdatePending
{
get { return !string.IsNullOrEmpty(_updateFilePath); }
}
public static void Quit(string updateFilePath = null)
public void Quit(string updateFilePath = null)
{
_updateFilePath = updateFilePath;
FrmMain.Default.Close();
_frmMain.Close();
ProgramRoot.CloseSingletonInstanceMutex();
}
public static void Cleanup(Control quickConnectToolStrip, ExternalToolsToolStrip externalToolsToolStrip, MultiSshToolStrip multiSshToolStrip, FrmMain frmMain)
public void Cleanup(Control quickConnectToolStrip, ExternalToolsToolStrip externalToolsToolStrip, MultiSshToolStrip multiSshToolStrip, FrmMain frmMain)
{
try
{
@@ -41,34 +53,34 @@ namespace mRemoteNG.App
}
}
private static void StopPuttySessionWatcher()
private void StopPuttySessionWatcher()
{
PuttySessionsManager.Instance.StopWatcher();
}
private static void DisposeNotificationAreaIcon()
private void DisposeNotificationAreaIcon()
{
if (Runtime.NotificationAreaIcon != null && Runtime.NotificationAreaIcon.Disposed == false)
Runtime.NotificationAreaIcon.Dispose();
}
private static void SaveConnections()
private void SaveConnections()
{
if (Settings.Default.SaveConsOnExit)
Runtime.ConnectionsService.SaveConnections();
_connectionsService.SaveConnections();
}
private static void SaveSettings(Control quickConnectToolStrip, ExternalToolsToolStrip externalToolsToolStrip, MultiSshToolStrip multiSshToolStrip, FrmMain frmMain)
private void SaveSettings(Control quickConnectToolStrip, ExternalToolsToolStrip externalToolsToolStrip, MultiSshToolStrip multiSshToolStrip, FrmMain frmMain)
{
Config.Settings.SettingsSaver.SaveSettings(quickConnectToolStrip, externalToolsToolStrip, multiSshToolStrip, frmMain);
_settingsSaver.SaveSettings(quickConnectToolStrip, externalToolsToolStrip, multiSshToolStrip, frmMain);
}
private static void UnregisterBrowsers()
private void UnregisterBrowsers()
{
IeBrowserEmulation.Unregister();
}
public static void StartUpdate()
public void StartUpdate()
{
try
{
@@ -80,7 +92,7 @@ namespace mRemoteNG.App
}
}
private static void RunUpdateFile()
private void RunUpdateFile()
{
if (UpdatePending)
Process.Start(_updateFilePath);

View File

@@ -7,6 +7,7 @@ using mRemoteNG.App.Initialization;
using mRemoteNG.App.Update;
using mRemoteNG.Config.Connections;
using mRemoteNG.Config.Connections.Multiuser;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Connection;
using mRemoteNG.Messages;
using mRemoteNG.Tools;
@@ -17,30 +18,34 @@ using mRemoteNG.UI.Forms;
namespace mRemoteNG.App
{
public class Startup
public class Startup
{
private AppUpdater _appUpdate;
private readonly AppUpdater _appUpdate;
private readonly ConnectionIconLoader _connectionIconLoader;
private readonly FrmMain _frmMain = FrmMain.Default;
private readonly FrmMain _frmMain;
private readonly Windows _windows;
private readonly IConnectionsService _connectionsService;
private readonly DatabaseConnectorFactory _databaseConnectorFactory;
private readonly CompatibilityChecker _compatibilityChecker;
public static Startup Instance { get; } = new Startup();
private Startup()
public Startup(FrmMain frmMain, Windows windows, IConnectionsService connectionsService,
AppUpdater appUpdate, DatabaseConnectorFactory databaseConnectorFactory, CompatibilityChecker compatibilityChecker)
{
_appUpdate = new AppUpdater();
_frmMain = frmMain.ThrowIfNull(nameof(frmMain));
_windows = windows.ThrowIfNull(nameof(windows));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
_appUpdate = appUpdate.ThrowIfNull(nameof(appUpdate));
_databaseConnectorFactory = databaseConnectorFactory.ThrowIfNull(nameof(databaseConnectorFactory));
_compatibilityChecker = compatibilityChecker.ThrowIfNull(nameof(compatibilityChecker));
_connectionIconLoader = new ConnectionIconLoader(GeneralAppInfo.HomePath + "\\Icons\\");
}
static Startup()
{
}
public void InitializeProgram(MessageCollector messageCollector)
{
Debug.Print("---------------------------" + Environment.NewLine + "[START] - " + Convert.ToString(DateTime.Now, CultureInfo.InvariantCulture));
var startupLogger = new StartupDataLogger(messageCollector);
startupLogger.LogStartupData();
CompatibilityChecker.CheckCompatibility(messageCollector);
_compatibilityChecker.CheckCompatibility();
ParseCommandLineArgs(messageCollector);
IeBrowserEmulation.Register();
_connectionIconLoader.GetConnectionIcons();
@@ -59,17 +64,14 @@ namespace mRemoteNG.App
messageCollector.AddMessage(MessageClass.DebugMsg, "Determining if we need a database syncronizer");
if (!Settings.Default.UseSQLServer) return;
messageCollector.AddMessage(MessageClass.DebugMsg, "Creating database syncronizer");
Runtime.ConnectionsService.RemoteConnectionsSyncronizer = new RemoteConnectionsSyncronizer(new SqlConnectionsUpdateChecker());
Runtime.ConnectionsService.RemoteConnectionsSyncronizer.Enable();
var sqlConnectionsUpdateChecker = new SqlConnectionsUpdateChecker(_connectionsService, _databaseConnectorFactory);
_connectionsService.RemoteConnectionsSyncronizer = new RemoteConnectionsSyncronizer(sqlConnectionsUpdateChecker, _connectionsService);
_connectionsService.RemoteConnectionsSyncronizer.Enable();
}
public void CheckForUpdate()
{
if (_appUpdate == null)
{
_appUpdate = new AppUpdater();
}
else if (_appUpdate.IsGetUpdateInfoRunning)
if (_appUpdate.IsGetUpdateInfoRunning)
{
return;
}
@@ -107,7 +109,7 @@ namespace mRemoteNG.App
if (_appUpdate.IsUpdateAvailable())
{
Windows.Show(WindowType.Update);
_windows.Show(WindowType.Update);
}
}
catch (Exception ex)

View File

@@ -4,6 +4,7 @@ using System.Net;
using System.ComponentModel;
using System.Threading;
using System.Reflection;
using System.Security;
using mRemoteNG.App.Info;
using mRemoteNG.Security.SymmetricEncryption;
using System.Security.Cryptography;
@@ -22,6 +23,7 @@ namespace mRemoteNG.App.Update
private WebProxy _webProxy;
private Thread _getUpdateInfoThread;
private Thread _getChangeLogThread;
private readonly Func<SecureString> _encryptionKeyRetrievalFunc;
#region Public Properties
@@ -48,8 +50,9 @@ namespace mRemoteNG.App.Update
#region Public Methods
public AppUpdater()
public AppUpdater(Func<SecureString> encryptionKeyRetrievalFunc)
{
_encryptionKeyRetrievalFunc = encryptionKeyRetrievalFunc;
SetProxySettings();
}
@@ -61,7 +64,7 @@ namespace mRemoteNG.App.Update
var useAuthentication = Settings.Default.UpdateProxyUseAuthentication;
var username = Settings.Default.UpdateProxyAuthUser;
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
var password = cryptographyProvider.Decrypt(Settings.Default.UpdateProxyAuthPass, Runtime.EncryptionKey);
var password = cryptographyProvider.Decrypt(Settings.Default.UpdateProxyAuthPass, _encryptionKeyRetrievalFunc());
SetProxySettings(shouldWeUseProxy, proxyAddress, port, useAuthentication, username, password);
}

View File

@@ -1,94 +1,134 @@
using System;
using mRemoteNG.App.Update;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Connection;
using mRemoteNG.Messages;
using mRemoteNG.Tools;
using mRemoteNG.UI;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.Window;
using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNG.App
{
public static class Windows
public class Windows
{
private static AboutWindow _aboutForm;
private static ActiveDirectoryImportWindow _adimportForm;
private static HelpWindow _helpForm;
private static ExternalToolsWindow _externalappsForm;
private static PortScanWindow _portscanForm;
private static UltraVNCWindow _ultravncscForm;
private static ComponentsCheckWindow _componentscheckForm;
private static ConnectionTreeWindow _treeForm;
private readonly IConnectionInitiator _connectionInitiator;
private AboutWindow _aboutForm;
private ActiveDirectoryImportWindow _adimportForm;
private HelpWindow _helpForm;
private ExternalToolsWindow _externalappsForm;
private PortScanWindow _portscanForm;
private UltraVNCWindow _ultravncscForm;
private ComponentsCheckWindow _componentscheckForm;
private UpdateWindow _updateForm;
private readonly Func<UpdateWindow> _updateWindowBuilder;
private readonly Func<NotificationAreaIcon> _notificationAreaIconBuilder;
private readonly Func<ExternalToolsWindow> _externalToolsWindowBuilder;
private readonly Func<PortScanWindow> _portScanWindowBuilder;
private readonly Func<ActiveDirectoryImportWindow> _activeDirectoryImportWindowBuilder;
private readonly IConnectionsService _connectionsService;
private readonly AppUpdater _appUpdater;
private readonly DatabaseConnectorFactory _databaseConnectorFactory;
private readonly FrmMain _frmMain;
internal static ConnectionTreeWindow TreeForm
internal ConnectionTreeWindow TreeForm { get; }
internal ConfigWindow ConfigForm { get; }
internal ErrorAndInfoWindow ErrorsForm { get; }
internal ScreenshotManagerWindow ScreenshotForm { get; }
internal SSHTransferWindow SshtransferForm { get; private set; }
public Windows(
IConnectionInitiator connectionInitiator,
ConnectionTreeWindow treeForm,
ConfigWindow configForm,
ErrorAndInfoWindow errorAndInfoWindow,
ScreenshotManagerWindow screenshotForm,
SSHTransferWindow sshtransferForm,
Func<UpdateWindow> updateWindowBuilder,
Func<NotificationAreaIcon> notificationAreaIconBuilder,
Func<ExternalToolsWindow> externalToolsWindowBuilder,
IConnectionsService connectionsService,
Func<PortScanWindow> portScanWindowBuilder,
Func<ActiveDirectoryImportWindow> activeDirectoryImportWindowBuilder,
AppUpdater appUpdater,
DatabaseConnectorFactory databaseConnectorFactory,
FrmMain frmMain)
{
get => _treeForm ?? (_treeForm = new ConnectionTreeWindow());
set => _treeForm = value;
_connectionInitiator = connectionInitiator.ThrowIfNull(nameof(connectionInitiator));
TreeForm = treeForm.ThrowIfNull(nameof(treeForm));
ConfigForm = configForm.ThrowIfNull(nameof(configForm));
ErrorsForm = errorAndInfoWindow.ThrowIfNull(nameof(errorAndInfoWindow));
ScreenshotForm = screenshotForm.ThrowIfNull(nameof(screenshotForm));
SshtransferForm = sshtransferForm.ThrowIfNull(nameof(sshtransferForm));
_updateWindowBuilder = updateWindowBuilder;
_notificationAreaIconBuilder = notificationAreaIconBuilder;
_externalToolsWindowBuilder = externalToolsWindowBuilder;
_portScanWindowBuilder = portScanWindowBuilder;
_activeDirectoryImportWindowBuilder = activeDirectoryImportWindowBuilder;
_frmMain = frmMain;
_databaseConnectorFactory = databaseConnectorFactory.ThrowIfNull(nameof(databaseConnectorFactory));
_appUpdater = appUpdater.ThrowIfNull(nameof(appUpdater));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
}
internal static ConfigWindow ConfigForm { get; set; } = new ConfigWindow();
internal static ErrorAndInfoWindow ErrorsForm { get; set; } = new ErrorAndInfoWindow();
internal static ScreenshotManagerWindow ScreenshotForm { get; set; } = new ScreenshotManagerWindow();
private static UpdateWindow UpdateForm { get; set; } = new UpdateWindow();
internal static SSHTransferWindow SshtransferForm { get; private set; } = new SSHTransferWindow();
public static void Show(WindowType windowType)
public void Show(WindowType windowType)
{
try
{
var dockPanel = FrmMain.Default.pnlDock;
// ReSharper disable once SwitchStatementMissingSomeCases
switch (windowType)
{
case WindowType.About:
if (_aboutForm == null || _aboutForm.IsDisposed)
_aboutForm = new AboutWindow();
_aboutForm.Show(dockPanel);
_aboutForm.Show(_frmMain.pnlDock);
break;
case WindowType.ActiveDirectoryImport:
if (_adimportForm == null || _adimportForm.IsDisposed)
_adimportForm = new ActiveDirectoryImportWindow();
_adimportForm.Show(dockPanel);
_adimportForm = _activeDirectoryImportWindowBuilder();
_adimportForm.Show(_frmMain.pnlDock);
break;
case WindowType.Options:
using (var optionsForm = new frmOptions())
using (var optionsForm = new frmOptions(_connectionInitiator, Show, _notificationAreaIconBuilder, _connectionsService, _appUpdater, _databaseConnectorFactory, _frmMain))
{
optionsForm.ShowDialog(dockPanel);
optionsForm.ShowDialog(_frmMain);
}
break;
case WindowType.SSHTransfer:
if (SshtransferForm == null || SshtransferForm.IsDisposed)
SshtransferForm = new SSHTransferWindow();
SshtransferForm.Show(dockPanel);
SshtransferForm = new SSHTransferWindow(_frmMain);
SshtransferForm.Show(_frmMain.pnlDock);
break;
case WindowType.Update:
if (UpdateForm == null || UpdateForm.IsDisposed)
UpdateForm = new UpdateWindow();
UpdateForm.Show(dockPanel);
if (_updateForm == null || _updateForm.IsDisposed)
_updateForm = _updateWindowBuilder();
_updateForm.Show(_frmMain.pnlDock);
break;
case WindowType.Help:
if (_helpForm == null || _helpForm.IsDisposed)
_helpForm = new HelpWindow();
_helpForm.Show(dockPanel);
_helpForm.Show(_frmMain.pnlDock);
break;
case WindowType.ExternalApps:
if (_externalappsForm == null || _externalappsForm.IsDisposed)
_externalappsForm = new ExternalToolsWindow();
_externalappsForm.Show(dockPanel);
_externalappsForm = _externalToolsWindowBuilder();
_externalappsForm.Show(_frmMain.pnlDock);
break;
case WindowType.PortScan:
_portscanForm = new PortScanWindow();
_portscanForm.Show(dockPanel);
_portscanForm = _portScanWindowBuilder();
_portscanForm.Show(_frmMain.pnlDock);
break;
case WindowType.UltraVNCSC:
if (_ultravncscForm == null || _ultravncscForm.IsDisposed)
_ultravncscForm = new UltraVNCWindow();
_ultravncscForm.Show(dockPanel);
_ultravncscForm = new UltraVNCWindow(Show);
_ultravncscForm.Show(_frmMain.pnlDock);
break;
case WindowType.ComponentsCheck:
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, "Showing ComponentsCheck window", true);
if (_componentscheckForm == null || _componentscheckForm.IsDisposed)
_componentscheckForm = new ComponentsCheckWindow();
_componentscheckForm.Show(dockPanel);
_componentscheckForm.Show(_frmMain.pnlDock);
break;
}
}
@@ -98,4 +138,4 @@ namespace mRemoteNG.App
}
}
}
}
}

View File

@@ -1,9 +1,8 @@
using System;
using mRemoteNG.App;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers.Csv;
using mRemoteNG.Credential;
using mRemoteNG.Security;
using mRemoteNG.Tools;
using mRemoteNG.Tree;
namespace mRemoteNG.Config.Connections
@@ -12,21 +11,18 @@ namespace mRemoteNG.Config.Connections
{
private readonly string _connectionFileName;
private readonly SaveFilter _saveFilter;
private readonly ICredentialRepositoryList _credentialRepositoryList;
public CsvConnectionsSaver(string connectionFileName, SaveFilter saveFilter)
public CsvConnectionsSaver(string connectionFileName, SaveFilter saveFilter, ICredentialRepositoryList credentialRepositoryList)
{
if (string.IsNullOrEmpty(connectionFileName))
throw new ArgumentException($"Argument '{nameof(connectionFileName)}' cannot be null or empty");
if (saveFilter == null)
throw new ArgumentNullException(nameof(saveFilter));
_connectionFileName = connectionFileName;
_saveFilter = saveFilter;
_connectionFileName = connectionFileName.ThrowIfNullOrEmpty(nameof(connectionFileName));
_saveFilter = saveFilter.ThrowIfNull(nameof(saveFilter));
_credentialRepositoryList = credentialRepositoryList.ThrowIfNull(nameof(credentialRepositoryList));
}
public void Save(ConnectionTreeModel connectionTreeModel)
{
var csvConnectionsSerializer = new CsvConnectionsSerializerMremotengFormat(_saveFilter, Runtime.CredentialProviderCatalog);
var csvConnectionsSerializer = new CsvConnectionsSerializerMremotengFormat(_saveFilter, _credentialRepositoryList);
var dataProvider = new FileDataProvider(_connectionFileName);
var csvContent = csvConnectionsSerializer.Serialize(connectionTreeModel);
dataProvider.Save(csvContent);

View File

@@ -1,6 +1,8 @@
using System;
using System.Timers;
using mRemoteNG.App;
using mRemoteNG.Connection;
using mRemoteNG.Tools;
// ReSharper disable ArrangeAccessorOwnerBody
namespace mRemoteNG.Config.Connections.Multiuser
@@ -9,15 +11,17 @@ namespace mRemoteNG.Config.Connections.Multiuser
{
private readonly Timer _updateTimer;
private readonly IConnectionsUpdateChecker _updateChecker;
private readonly IConnectionsService _connectionsService;
public double TimerIntervalInMilliseconds
{
get { return _updateTimer.Interval; }
}
public RemoteConnectionsSyncronizer(IConnectionsUpdateChecker updateChecker)
public RemoteConnectionsSyncronizer(IConnectionsUpdateChecker updateChecker, IConnectionsService connectionsService)
{
_updateChecker = updateChecker;
_updateChecker = updateChecker.ThrowIfNull(nameof(updateChecker));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
_updateTimer = new Timer(3000);
SetEventListeners();
}
@@ -33,7 +37,7 @@ namespace mRemoteNG.Config.Connections.Multiuser
private void Load(object sender, ConnectionsUpdateAvailableEventArgs args)
{
Runtime.ConnectionsService.LoadConnections(true, false, "");
_connectionsService.LoadConnections(true, false, "");
args.Handled = true;
}

View File

@@ -6,6 +6,8 @@ using System.Data.SqlClient;
using System.Threading;
using mRemoteNG.Config.Connections.Multiuser;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Connection;
using mRemoteNG.Tools;
namespace mRemoteNG.Config.Connections
{
@@ -13,13 +15,15 @@ namespace mRemoteNG.Config.Connections
{
private readonly SqlDatabaseConnector _sqlConnector;
private readonly SqlCommand _sqlQuery;
private readonly IConnectionsService _connectionsService;
private DateTime _lastUpdateTime;
private DateTime _lastDatabaseUpdateTime;
public SqlConnectionsUpdateChecker()
public SqlConnectionsUpdateChecker(IConnectionsService connectionsService, DatabaseConnectorFactory databaseConnectorFactory)
{
_sqlConnector = DatabaseConnectorFactory.SqlDatabaseConnectorFromSettings();
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
databaseConnectorFactory.ThrowIfNull(nameof(databaseConnectorFactory));
_sqlConnector = databaseConnectorFactory.SqlDatabaseConnectorFromSettings();
_sqlQuery = new SqlCommand("SELECT * FROM tblUpdate", _sqlConnector.SqlConnection);
_lastUpdateTime = default(DateTime);
_lastDatabaseUpdateTime = default(DateTime);
@@ -64,7 +68,7 @@ namespace mRemoteNG.Config.Connections
private bool CheckIfIAmTheLastOneUpdated(DateTime lastUpdateInDb)
{
DateTime LastSqlUpdateWithoutMilliseconds = new DateTime(Runtime.ConnectionsService.LastSqlUpdate.Ticks - (Runtime.ConnectionsService.LastSqlUpdate.Ticks % TimeSpan.TicksPerSecond), Runtime.ConnectionsService.LastSqlUpdate.Kind);
DateTime LastSqlUpdateWithoutMilliseconds = new DateTime(_connectionsService.LastSqlUpdate.Ticks - (_connectionsService.LastSqlUpdate.Ticks % TimeSpan.TicksPerSecond), _connectionsService.LastSqlUpdate.Kind);
return lastUpdateInDb == LastSqlUpdateWithoutMilliseconds;
}

View File

@@ -1,16 +1,17 @@
using System;
using mRemoteNG.Connection;
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using mRemoteNG.Connection;
using mRemoteNG.UI.Forms;
namespace mRemoteNG.Config.Connections
{
public class SaveConnectionsOnEdit
{
private readonly ConnectionsService _connectionsService;
private readonly IConnectionsService _connectionsService;
public SaveConnectionsOnEdit(ConnectionsService connectionsService)
public bool Enabled { get; set; } = true;
public SaveConnectionsOnEdit(IConnectionsService connectionsService)
{
if (connectionsService == null)
throw new ArgumentNullException(nameof(connectionsService));
@@ -45,7 +46,8 @@ namespace mRemoteNG.Config.Connections
{
if (!mRemoteNG.Settings.Default.SaveConnectionsAfterEveryEdit)
return;
if (FrmMain.Default.IsClosing)
if (!Enabled)
return;
_connectionsService.SaveConnectionsAsync();

View File

@@ -2,20 +2,31 @@
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Versioning;
using mRemoteNG.Connection;
using mRemoteNG.Tools;
using mRemoteNG.Tree;
namespace mRemoteNG.Config.Connections
{
public class SqlConnectionsLoader
{
private readonly DatabaseConnectorFactory _databaseConnectorFactory;
private readonly IConnectionsService _connectionsService;
public SqlConnectionsLoader(DatabaseConnectorFactory databaseConnectorFactory, IConnectionsService connectionsService)
{
_databaseConnectorFactory = databaseConnectorFactory.ThrowIfNull(nameof(databaseConnectorFactory));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
}
public ConnectionTreeModel Load()
{
var connector = DatabaseConnectorFactory.SqlDatabaseConnectorFromSettings();
var connector = _databaseConnectorFactory.SqlDatabaseConnectorFromSettings();
var dataProvider = new SqlDataProvider(connector);
var databaseVersionVerifier = new SqlDatabaseVersionVerifier(connector);
databaseVersionVerifier.VerifyDatabaseVersion();
var dataTable = dataProvider.Load();
var deserializer = new DataTableDeserializer();
var deserializer = new DataTableDeserializer(_connectionsService);
return deserializer.Deserialize(dataTable);
}
}

View File

@@ -2,13 +2,13 @@
using System.Data.SqlClient;
using System.Globalization;
using System.Linq;
using System.Security;
using mRemoteNG.App;
using mRemoteNG.App.Info;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Versioning;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Messages;
using mRemoteNG.Security;
@@ -21,14 +21,15 @@ namespace mRemoteNG.Config.Connections
{
public class SqlConnectionsSaver : ISaver<ConnectionTreeModel>
{
private SecureString _password = Runtime.EncryptionKey;
private readonly IConnectionsService _connectionsService;
private readonly SaveFilter _saveFilter;
private readonly DatabaseConnectorFactory _databaseConnectorFactory;
public SqlConnectionsSaver(SaveFilter saveFilter)
public SqlConnectionsSaver(SaveFilter saveFilter, IConnectionsService connectionsService, DatabaseConnectorFactory databaseConnectorFactory)
{
if (saveFilter == null)
throw new ArgumentNullException(nameof(saveFilter));
_saveFilter = saveFilter;
_saveFilter = saveFilter.ThrowIfNull(nameof(saveFilter));
_databaseConnectorFactory = databaseConnectorFactory.ThrowIfNull(nameof(databaseConnectorFactory));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
}
public void Save(ConnectionTreeModel connectionTreeModel)
@@ -40,7 +41,7 @@ namespace mRemoteNG.Config.Connections
}
using (var sqlConnector = DatabaseConnectorFactory.SqlDatabaseConnectorFromSettings())
using (var sqlConnector = _databaseConnectorFactory.SqlDatabaseConnectorFromSettings())
{
sqlConnector.Connect();
var databaseVersionVerifier = new SqlDatabaseVersionVerifier(sqlConnector);
@@ -67,17 +68,17 @@ namespace mRemoteNG.Config.Connections
{
if (rootTreeNode.Password)
{
_password = rootTreeNode.PasswordString.ConvertToSecureString();
strProtected = cryptographyProvider.Encrypt("ThisIsProtected", _password);
_connectionsService.EncryptionKey = rootTreeNode.PasswordString.ConvertToSecureString();
strProtected = cryptographyProvider.Encrypt("ThisIsProtected", _connectionsService.EncryptionKey);
}
else
{
strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _password);
strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _connectionsService.EncryptionKey);
}
}
else
{
strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _password);
strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _connectionsService.EncryptionKey);
}
var sqlQuery = new SqlCommand("DELETE FROM tblRoot", sqlDatabaseConnector.SqlConnection);

View File

@@ -1,40 +1,37 @@
using System;
using System.IO;
using System.Security;
using System.Security;
using System.Windows.Forms;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection;
using mRemoteNG.Tools;
using mRemoteNG.Tree;
namespace mRemoteNG.Config.Connections
{
public class XmlConnectionsLoader
{
{
private readonly IConnectionsService _connectionsService;
private readonly string _connectionFilePath;
private readonly IWin32Window _dialogWindowParent;
public XmlConnectionsLoader(string connectionFilePath)
public XmlConnectionsLoader(string connectionFilePath, IConnectionsService connectionsService, IWin32Window dialogWindowParent)
{
if (string.IsNullOrEmpty(connectionFilePath))
throw new ArgumentException($"{nameof(connectionFilePath)} cannot be null or empty");
if (!File.Exists(connectionFilePath))
throw new FileNotFoundException($"{connectionFilePath} does not exist");
_connectionFilePath = connectionFilePath;
_dialogWindowParent = dialogWindowParent;
_connectionFilePath = connectionFilePath.ThrowIfNullOrEmpty(nameof(connectionFilePath));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
}
public ConnectionTreeModel Load()
{
var dataProvider = new FileDataProvider(_connectionFilePath);
var xmlString = dataProvider.Load();
var deserializer = new XmlConnectionsDeserializer(PromptForPassword);
var deserializer = new XmlConnectionsDeserializer(_connectionsService, _dialogWindowParent, PromptForPassword);
return deserializer.Deserialize(xmlString);
}
private Optional<SecureString> PromptForPassword()
{
var password = MiscTools.PasswordDialog("", false);
return password;
return MiscTools.PasswordDialog("", false);
}
}
}

View File

@@ -1,17 +1,26 @@
using mRemoteNG.App;
using System;
using System.Security;
using mRemoteNG.App;
using mRemoteNG.Security.SymmetricEncryption;
namespace mRemoteNG.Config.DatabaseConnectors
{
public class DatabaseConnectorFactory
{
public static SqlDatabaseConnector SqlDatabaseConnectorFromSettings()
private readonly Func<SecureString> _decryptionKeyRetrievalFun;
public DatabaseConnectorFactory(Func<SecureString> decryptionKeyRetrievalFun)
{
_decryptionKeyRetrievalFun = decryptionKeyRetrievalFun;
}
public SqlDatabaseConnector SqlDatabaseConnectorFromSettings()
{
var sqlHost = mRemoteNG.Settings.Default.SQLHost;
var sqlCatalog = mRemoteNG.Settings.Default.SQLDatabaseName;
var sqlUsername = mRemoteNG.Settings.Default.SQLUser;
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
var sqlPassword = cryptographyProvider.Decrypt(mRemoteNG.Settings.Default.SQLPass, Runtime.EncryptionKey);
var sqlPassword = cryptographyProvider.Decrypt(mRemoteNG.Settings.Default.SQLPass, _decryptionKeyRetrievalFun());
return new SqlDatabaseConnector(sqlHost, sqlCatalog, sqlUsername, sqlPassword);
}
}

View File

@@ -1,11 +1,13 @@
using System.IO;
using System.Linq;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Messages;
using mRemoteNG.Tools;
namespace mRemoteNG.Config.Import
@@ -13,6 +15,15 @@ namespace mRemoteNG.Config.Import
// ReSharper disable once InconsistentNaming
public class MRemoteNGXmlImporter : IConnectionImporter<string>
{
private readonly IConnectionsService _connectionsService;
private readonly IWin32Window _dialogWindowParent;
public MRemoteNGXmlImporter(IConnectionsService connectionsService, IWin32Window dialogWindowParent)
{
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
_dialogWindowParent = dialogWindowParent.ThrowIfNull(nameof(dialogWindowParent));
}
public void Import(string fileName, ContainerInfo destinationContainer)
{
if (fileName == null)
@@ -26,7 +37,7 @@ namespace mRemoteNG.Config.Import
var dataProvider = new FileDataProvider(fileName);
var xmlString = dataProvider.Load();
var xmlConnectionsDeserializer = new XmlConnectionsDeserializer();
var xmlConnectionsDeserializer = new XmlConnectionsDeserializer(_connectionsService, _dialogWindowParent);
var connectionTreeModel = xmlConnectionsDeserializer.Deserialize(xmlString, true);
var rootImportContainer = new ContainerInfo { Name = Path.GetFileNameWithoutExtension(fileName) };

View File

@@ -22,18 +22,22 @@ using mRemoteNG.UI.TaskDialog;
namespace mRemoteNG.Config.Serializers.Xml
{
public class XmlConnectionsDeserializer : IDeserializer<string, ConnectionTreeModel>
{
{
private readonly IConnectionsService _connectionsService;
private XmlDocument _xmlDocument;
private double _confVersion;
private XmlConnectionsDecryptor _decryptor;
private string ConnectionFileName = "";
private const double MaxSupportedConfVersion = 2.8;
private readonly RootNodeInfo _rootNodeInfo = new RootNodeInfo(RootNodeType.Connection);
private readonly IWin32Window _dialogWindowParent;
public Func<Optional<SecureString>> AuthenticationRequestor { get; set; }
public XmlConnectionsDeserializer(Func<Optional<SecureString>> authenticationRequestor = null)
public XmlConnectionsDeserializer(IConnectionsService connectionsService, IWin32Window dialogWindowParent, Func<Optional<SecureString>> authenticationRequestor = null)
{
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
_dialogWindowParent = dialogWindowParent.ThrowIfNull(nameof(dialogWindowParent));
AuthenticationRequestor = authenticationRequestor;
}
@@ -78,13 +82,13 @@ namespace mRemoteNG.Config.Serializers.Xml
AddNodesFromXmlRecursive(_xmlDocument.DocumentElement, _rootNodeInfo);
if (!import)
Runtime.ConnectionsService.IsConnectionsFileLoaded = true;
_connectionsService.IsConnectionsFileLoaded = true;
return connectionTreeModel;
}
catch (Exception ex)
{
Runtime.ConnectionsService.IsConnectionsFileLoaded = false;
_connectionsService.IsConnectionsFileLoaded = false;
Runtime.MessageCollector.AddExceptionStackTrace(Language.strLoadFromXmlFailed, ex);
throw;
}
@@ -114,7 +118,7 @@ namespace mRemoteNG.Config.Serializers.Xml
private void ShowIncompatibleVersionDialogBox()
{
CTaskDialog.ShowTaskDialogBox(
FrmMain.Default,
_dialogWindowParent,
Application.ProductName,
"Incompatible connection file format",
$"The format of this connection file is not supported. Please upgrade to a newer version of {Application.ProductName}.",

View File

@@ -10,18 +10,26 @@ using mRemoteNG.Connection.Protocol.ICA;
using mRemoteNG.Connection.Protocol.RDP;
using mRemoteNG.Connection.Protocol.VNC;
using mRemoteNG.Container;
using mRemoteNG.Tools;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
namespace mRemoteNG.Config.Serializers
{
public class DataTableDeserializer : IDeserializer<DataTable, ConnectionTreeModel>
{
public ConnectionTreeModel Deserialize(DataTable table)
{
private readonly IConnectionsService _connectionsService;
public DataTableDeserializer(IConnectionsService connectionsService)
{
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
}
public ConnectionTreeModel Deserialize(DataTable table)
{
var connectionList = CreateNodesFromTable(table);
var connectionTreeModel = CreateNodeHierarchy(connectionList, table);
Runtime.ConnectionsService.IsConnectionsFileLoaded = true;
_connectionsService.IsConnectionsFileLoaded = true;
return connectionTreeModel;
}

View File

@@ -5,6 +5,7 @@ using mRemoteNG.UI.Window;
using System;
using System.IO;
using mRemoteNG.Messages;
using mRemoteNG.Tools;
using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNG.Config.Settings
@@ -13,16 +14,13 @@ namespace mRemoteNG.Config.Settings
{
private readonly FrmMain _mainForm;
private readonly MessageCollector _messageCollector;
private readonly Windows _windows;
public DockPanelLayoutLoader(FrmMain mainForm, MessageCollector messageCollector)
public DockPanelLayoutLoader(FrmMain mainForm, MessageCollector messageCollector, Windows windows)
{
if (mainForm == null)
throw new ArgumentNullException(nameof(mainForm));
if (messageCollector == null)
throw new ArgumentNullException(nameof(messageCollector));
_mainForm = mainForm;
_messageCollector = messageCollector;
_mainForm = mainForm.ThrowIfNull(nameof(mainForm));
_messageCollector = messageCollector.ThrowIfNull(nameof(messageCollector));
_windows = windows.ThrowIfNull(nameof(windows));
}
public void LoadPanelsFromXml()
@@ -69,16 +67,16 @@ namespace mRemoteNG.Config.Settings
try
{
if (persistString == typeof(ConfigWindow).ToString())
return Windows.ConfigForm;
return _windows.ConfigForm;
if (persistString == typeof(ConnectionTreeWindow).ToString())
return Windows.TreeForm;
return _windows.TreeForm;
if (persistString == typeof(ErrorAndInfoWindow).ToString())
return Windows.ErrorsForm;
return _windows.ErrorsForm;
if (persistString == typeof(ScreenshotManagerWindow).ToString())
return Windows.ScreenshotForm;
return _windows.ScreenshotForm;
}
catch (Exception ex)
{

View File

@@ -25,7 +25,7 @@ namespace mRemoteNG.Config.Settings
_dataProvider = dataProvider;
}
public void Save()
public void Save(DockPanel dockPanel)
{
try
{
@@ -34,7 +34,7 @@ namespace mRemoteNG.Config.Settings
Directory.CreateDirectory(SettingsFileInfo.SettingsPath);
}
var serializedLayout = _dockPanelSerializer.Serialize(FrmMain.Default.pnlDock);
var serializedLayout = _dockPanelSerializer.Serialize(dockPanel);
_dataProvider.Save(serializedLayout);
}
catch (Exception ex)

View File

@@ -4,6 +4,7 @@ using mRemoteNG.App.Info;
using mRemoteNG.UI.Forms;
using System.IO;
using System.Xml;
using mRemoteNG.Connection;
using mRemoteNG.Messages;
using mRemoteNG.Tools;
using mRemoteNG.UI.Controls;
@@ -12,22 +13,20 @@ namespace mRemoteNG.Config.Settings
{
public class ExternalAppsLoader
{
private readonly FrmMain _mainForm;
private readonly MessageCollector _messageCollector;
private readonly ExternalToolsToolStrip _externalToolsToolStrip;
private readonly IConnectionInitiator _connectionInitiator;
private readonly ExternalToolsService _externalToolsService;
private readonly IConnectionsService _connectionsService;
public ExternalAppsLoader(FrmMain mainForm, MessageCollector messageCollector, ExternalToolsToolStrip externalToolsToolStrip)
public ExternalAppsLoader(MessageCollector messageCollector, ExternalToolsToolStrip externalToolsToolStrip,
IConnectionInitiator connectionInitiator, ExternalToolsService externalToolsService, IConnectionsService connectionsService)
{
if (mainForm == null)
throw new ArgumentNullException(nameof(mainForm));
if (messageCollector == null)
throw new ArgumentNullException(nameof(messageCollector));
if (externalToolsToolStrip == null)
throw new ArgumentNullException(nameof(externalToolsToolStrip));
_mainForm = mainForm;
_messageCollector = messageCollector;
_externalToolsToolStrip = externalToolsToolStrip;
_messageCollector = messageCollector.ThrowIfNull(nameof(messageCollector));
_externalToolsToolStrip = externalToolsToolStrip.ThrowIfNull(nameof(externalToolsToolStrip));
_connectionInitiator = connectionInitiator.ThrowIfNull(nameof(connectionInitiator));
_externalToolsService = externalToolsService.ThrowIfNull(nameof(externalToolsService));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
}
@@ -48,7 +47,6 @@ namespace mRemoteNG.Config.Settings
{
_messageCollector.AddMessage(MessageClass.InformationMsg, $"Loading External Apps from: {oldPath}", true);
xDom.Load(oldPath);
}
#endif
else
@@ -65,7 +63,7 @@ namespace mRemoteNG.Config.Settings
foreach (XmlElement xEl in xDom.DocumentElement.ChildNodes)
{
var extA = new ExternalTool
var extA = new ExternalTool(_connectionInitiator, _connectionsService)
{
DisplayName = xEl.Attributes["DisplayName"].Value,
FileName = xEl.Attributes["FileName"].Value,
@@ -94,7 +92,7 @@ namespace mRemoteNG.Config.Settings
}
_messageCollector.AddMessage(MessageClass.InformationMsg, $"Adding External App: {extA.DisplayName} {extA.FileName} {extA.Arguments}", true);
Runtime.ExternalToolsService.ExternalTools.Add(extA);
_externalToolsService.ExternalTools.Add(extA);
}
_externalToolsToolStrip.SwitchToolBarText(mRemoteNG.Settings.Default.ExtAppsTBShowText);

View File

@@ -23,8 +23,8 @@ namespace mRemoteNG.Config.Settings
private readonly QuickConnectToolStrip _quickConnectToolStrip;
private readonly ExternalToolsToolStrip _externalToolsToolStrip;
private readonly MultiSshToolStrip _multiSshToolStrip;
private FrmMain MainForm { get; }
private readonly Func<NotificationAreaIcon> _notificationAreaIconBuilder;
private readonly FrmMain _frmMain;
public SettingsLoader(
@@ -33,29 +33,19 @@ namespace mRemoteNG.Config.Settings
QuickConnectToolStrip quickConnectToolStrip,
ExternalToolsToolStrip externalToolsToolStrip,
MultiSshToolStrip multiSshToolStrip,
ExternalAppsLoader externalAppsLoader,
Func<NotificationAreaIcon> notificationAreaIconBuilder,
MenuStrip mainMenu)
{
if (mainForm == null)
throw new ArgumentNullException(nameof(mainForm));
if (messageCollector == null)
throw new ArgumentNullException(nameof(messageCollector));
if (quickConnectToolStrip == null)
throw new ArgumentNullException(nameof(quickConnectToolStrip));
if (externalToolsToolStrip == null)
throw new ArgumentNullException(nameof(externalToolsToolStrip));
if (multiSshToolStrip == null)
throw new ArgumentNullException(nameof(multiSshToolStrip));
if (mainMenu == null)
throw new ArgumentNullException(nameof(mainMenu));
MainForm = mainForm;
_messageCollector = messageCollector;
_quickConnectToolStrip = quickConnectToolStrip;
_externalToolsToolStrip = externalToolsToolStrip;
_multiSshToolStrip = multiSshToolStrip;
_mainMenu = mainMenu;
_externalAppsLoader = new ExternalAppsLoader(MainForm, messageCollector, _externalToolsToolStrip);
}
_frmMain = mainForm.ThrowIfNull(nameof(mainForm));
_messageCollector = messageCollector.ThrowIfNull(nameof(messageCollector));
_quickConnectToolStrip = quickConnectToolStrip.ThrowIfNull(nameof(quickConnectToolStrip));
_externalToolsToolStrip = externalToolsToolStrip.ThrowIfNull(nameof(externalToolsToolStrip));
_multiSshToolStrip = multiSshToolStrip.ThrowIfNull(nameof(multiSshToolStrip));
_externalAppsLoader = externalAppsLoader.ThrowIfNull(nameof(externalAppsLoader));
_notificationAreaIconBuilder = notificationAreaIconBuilder.ThrowIfNull(nameof(notificationAreaIconBuilder));
_mainMenu = mainMenu.ThrowIfNull(nameof(mainMenu));
}
#region Public Methods
public void LoadSettings()
@@ -85,10 +75,10 @@ namespace mRemoteNG.Config.Settings
}
}
private static void SetAlwaysShowPanelTabs()
private void SetAlwaysShowPanelTabs()
{
if (mRemoteNG.Settings.Default.AlwaysShowPanelTabs)
FrmMain.Default.pnlDock.DocumentStyle = DocumentStyle.DockingWindow;
_frmMain.pnlDock.DocumentStyle = DocumentStyle.DockingWindow;
}
@@ -103,32 +93,32 @@ namespace mRemoteNG.Config.Settings
private void SetApplicationWindowPositionAndSize()
{
MainForm.WindowState = FormWindowState.Normal;
_frmMain.WindowState = FormWindowState.Normal;
if (mRemoteNG.Settings.Default.MainFormState == FormWindowState.Normal)
{
if (!mRemoteNG.Settings.Default.MainFormLocation.IsEmpty)
MainForm.Location = mRemoteNG.Settings.Default.MainFormLocation;
_frmMain.Location = mRemoteNG.Settings.Default.MainFormLocation;
if (!mRemoteNG.Settings.Default.MainFormSize.IsEmpty)
MainForm.Size = mRemoteNG.Settings.Default.MainFormSize;
_frmMain.Size = mRemoteNG.Settings.Default.MainFormSize;
}
else
{
if (!mRemoteNG.Settings.Default.MainFormRestoreLocation.IsEmpty)
MainForm.Location = mRemoteNG.Settings.Default.MainFormRestoreLocation;
_frmMain.Location = mRemoteNG.Settings.Default.MainFormRestoreLocation;
if (!mRemoteNG.Settings.Default.MainFormRestoreSize.IsEmpty)
MainForm.Size = mRemoteNG.Settings.Default.MainFormRestoreSize;
_frmMain.Size = mRemoteNG.Settings.Default.MainFormRestoreSize;
}
if (mRemoteNG.Settings.Default.MainFormState == FormWindowState.Maximized)
{
MainForm.WindowState = FormWindowState.Maximized;
_frmMain.WindowState = FormWindowState.Maximized;
}
// Make sure the form is visible on the screen
const int minHorizontal = 300;
const int minVertical = 150;
var screenBounds = Screen.FromHandle(MainForm.Handle).Bounds;
var newBounds = MainForm.Bounds;
var screenBounds = Screen.FromHandle(_frmMain.Handle).Bounds;
var newBounds = _frmMain.Bounds;
if (newBounds.Right < screenBounds.Left + minHorizontal)
newBounds.X = screenBounds.Left + minHorizontal - newBounds.Width;
@@ -139,29 +129,29 @@ namespace mRemoteNG.Config.Settings
if (newBounds.Top > screenBounds.Bottom - minVertical)
newBounds.Y = screenBounds.Bottom - minVertical;
MainForm.Location = newBounds.Location;
_frmMain.Location = newBounds.Location;
}
private void SetAutoSave()
{
if (mRemoteNG.Settings.Default.AutoSaveEveryMinutes <= 0) return;
MainForm.tmrAutoSave.Interval = mRemoteNG.Settings.Default.AutoSaveEveryMinutes * 60000;
MainForm.tmrAutoSave.Enabled = true;
_frmMain.tmrAutoSave.Interval = mRemoteNG.Settings.Default.AutoSaveEveryMinutes * 60000;
_frmMain.tmrAutoSave.Enabled = true;
}
private void SetKioskMode()
{
if (!mRemoteNG.Settings.Default.MainFormKiosk) return;
MainForm.Fullscreen.Value = true;
_frmMain.Fullscreen.Value = true;
}
private static void SetShowSystemTrayIcon()
private void SetShowSystemTrayIcon()
{
if (mRemoteNG.Settings.Default.ShowSystemTrayIcon)
Runtime.NotificationAreaIcon = new NotificationAreaIcon();
Runtime.NotificationAreaIcon = _notificationAreaIconBuilder();
}
private static void SetPuttyPath()
private void SetPuttyPath()
{
PuttyBase.PuttyPath = mRemoteNG.Settings.Default.UseCustomPuttyPath ? mRemoteNG.Settings.Default.CustomPuttyPath : GeneralAppInfo.PuttyPath;
}
@@ -265,15 +255,15 @@ namespace mRemoteNG.Config.Settings
switch (panel.ToLower())
{
case "top":
return MainForm.tsContainer.TopToolStripPanel;
return _frmMain.tsContainer.TopToolStripPanel;
case "bottom":
return MainForm.tsContainer.BottomToolStripPanel;
return _frmMain.tsContainer.BottomToolStripPanel;
case "left":
return MainForm.tsContainer.LeftToolStripPanel;
return _frmMain.tsContainer.LeftToolStripPanel;
case "right":
return MainForm.tsContainer.RightToolStripPanel;
return _frmMain.tsContainer.RightToolStripPanel;
default:
return MainForm.tsContainer.TopToolStripPanel;
return _frmMain.tsContainer.TopToolStripPanel;
}
}
@@ -283,4 +273,4 @@ namespace mRemoteNG.Config.Settings
}
#endregion
}
}
}

View File

@@ -6,12 +6,20 @@ using mRemoteNG.Config.DataProviders;
using mRemoteNG.Tools;
using mRemoteNG.UI.Controls;
using mRemoteNG.UI.Forms;
using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNG.Config.Settings
{
public static class SettingsSaver
public class SettingsSaver
{
public static void SaveSettings(
private readonly ExternalToolsService _externalToolsService;
public SettingsSaver(ExternalToolsService externalToolsService)
{
_externalToolsService = externalToolsService.ThrowIfNull(nameof(externalToolsService));
}
public void SaveSettings(
Control quickConnectToolStrip,
ExternalToolsToolStrip externalToolsToolStrip,
MultiSshToolStrip multiSshToolStrip,
@@ -19,7 +27,7 @@ namespace mRemoteNG.Config.Settings
{
try
{
var windowPlacement = new WindowPlacement(FrmMain.Default);
var windowPlacement = new WindowPlacement(frmMain);
if (frmMain.WindowState == FormWindowState.Minimized & windowPlacement.RestoreToMaximized)
{
frmMain.Opacity = 0;
@@ -53,7 +61,7 @@ namespace mRemoteNG.Config.Settings
mRemoteNG.Settings.Default.Save();
SaveDockPanelLayout();
SaveDockPanelLayout(frmMain.pnlDock);
SaveExternalApps();
}
catch (Exception ex)
@@ -62,7 +70,7 @@ namespace mRemoteNG.Config.Settings
}
}
private static void SaveExternalAppsToolbarLocation(ExternalToolsToolStrip externalToolsToolStrip)
private void SaveExternalAppsToolbarLocation(ExternalToolsToolStrip externalToolsToolStrip)
{
mRemoteNG.Settings.Default.ExtAppsTBLocation = externalToolsToolStrip.Location;
mRemoteNG.Settings.Default.ExtAppsTBVisible = externalToolsToolStrip.Visible;
@@ -74,7 +82,7 @@ namespace mRemoteNG.Config.Settings
}
}
private static void SaveQuickConnectToolbarLocation(Control quickConnectToolStrip)
private void SaveQuickConnectToolbarLocation(Control quickConnectToolStrip)
{
mRemoteNG.Settings.Default.QuickyTBLocation = quickConnectToolStrip.Location;
mRemoteNG.Settings.Default.QuickyTBVisible = quickConnectToolStrip.Visible;
@@ -85,7 +93,7 @@ namespace mRemoteNG.Config.Settings
}
}
private static void SaveMultiSshToolbarLocation(MultiSshToolStrip multiSshToolStrip)
private void SaveMultiSshToolbarLocation(MultiSshToolStrip multiSshToolStrip)
{
mRemoteNG.Settings.Default.MultiSshToolbarLocation = multiSshToolStrip.Location;
mRemoteNG.Settings.Default.MultiSshToolbarVisible = multiSshToolStrip.Visible;
@@ -96,20 +104,20 @@ namespace mRemoteNG.Config.Settings
}
}
private static void SaveDockPanelLayout()
private void SaveDockPanelLayout(DockPanel dockPanel)
{
var panelLayoutXmlFilePath = SettingsFileInfo.SettingsPath + "\\" + SettingsFileInfo.LayoutFileName;
var panelLayoutSaver = new DockPanelLayoutSaver(
new DockPanelLayoutSerializer(),
new FileDataProvider(panelLayoutXmlFilePath)
);
panelLayoutSaver.Save();
panelLayoutSaver.Save(dockPanel);
}
private static void SaveExternalApps()
private void SaveExternalApps()
{
var externalAppsSaver = new ExternalAppsSaver();
externalAppsSaver.Save(Runtime.ExternalToolsService.ExternalTools);
externalAppsSaver.Save(_externalToolsService.ExternalTools);
}
}
}

View File

@@ -5,6 +5,8 @@ using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.RDP;
using mRemoteNG.Container;
using mRemoteNG.Messages;
using mRemoteNG.Tools;
using mRemoteNG.UI;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.Panels;
using mRemoteNG.UI.Window;
@@ -14,8 +16,25 @@ using TabPage = Crownwood.Magic.Controls.TabPage;
namespace mRemoteNG.Connection
{
public class ConnectionInitiator : IConnectionInitiator
{
private readonly PanelAdder _panelAdder = new PanelAdder();
{
private readonly WindowList _windowList;
private readonly ExternalToolsService _externalToolsService;
private readonly ProtocolFactory _protocolFactory;
private readonly FrmMain _frmMain;
/// <summary>
/// This is a property because we have a circular dependency.
/// </summary>
public PanelAdder Adder { get; set; }
public ConnectionInitiator(WindowList windowList, ExternalToolsService externalToolsService, ProtocolFactory protocolFactory, FrmMain frmMain)
{
_frmMain = frmMain;
_windowList = windowList.ThrowIfNull(nameof(windowList));
_externalToolsService = externalToolsService.ThrowIfNull(nameof(externalToolsService));
_protocolFactory = protocolFactory.ThrowIfNull(nameof(protocolFactory));
}
public void OpenConnection(ContainerInfo containerInfo, ConnectionInfo.Force force = ConnectionInfo.Force.None)
{
@@ -53,7 +72,7 @@ namespace mRemoteNG.Connection
var connectionWindow = (ConnectionWindow)interfaceControl.FindForm();
connectionWindow?.Focus();
var findForm = (ConnectionWindow)interfaceControl.FindForm();
findForm?.Show(FrmMain.Default.pnlDock);
findForm?.Show(_frmMain.pnlDock);
var tabPage = (TabPage)interfaceControl.Parent;
tabPage.Selected = true;
return true;
@@ -92,8 +111,7 @@ namespace mRemoteNG.Connection
return;
}
var protocolFactory = new ProtocolFactory();
var newProtocol = protocolFactory.CreateProtocol(connectionInfo);
var newProtocol = _protocolFactory.CreateProtocol(connectionInfo);
var connectionPanel = SetConnectionPanel(connectionInfo, force);
if (string.IsNullOrEmpty(connectionPanel)) return;
@@ -118,7 +136,7 @@ namespace mRemoteNG.Connection
}
connectionInfo.OpenConnections.Add(newProtocol);
FrmMain.Default.SelectedConnection = connectionInfo;
_frmMain.SelectedConnection = connectionInfo;
}
catch (Exception ex)
{
@@ -126,19 +144,19 @@ namespace mRemoteNG.Connection
}
}
private static void StartPreConnectionExternalApp(ConnectionInfo connectionInfo)
private void StartPreConnectionExternalApp(ConnectionInfo connectionInfo)
{
if (connectionInfo.PreExtApp == "") return;
var extA = Runtime.ExternalToolsService.GetExtAppByName(connectionInfo.PreExtApp);
var extA = _externalToolsService.GetExtAppByName(connectionInfo.PreExtApp);
extA?.Start(connectionInfo);
}
private static InterfaceControl FindConnectionContainer(ConnectionInfo connectionInfo)
private InterfaceControl FindConnectionContainer(ConnectionInfo connectionInfo)
{
if (connectionInfo.OpenConnections.Count <= 0) return null;
for (var i = 0; i <= Runtime.WindowList.Count - 1; i++)
for (var i = 0; i <= _windowList.Count - 1; i++)
{
var window = Runtime.WindowList[i] as ConnectionWindow;
var window = _windowList[i] as ConnectionWindow;
var connectionWindow = window;
if (connectionWindow?.TabController == null) continue;
foreach (TabPage t in connectionWindow.TabController.TabPages)
@@ -154,12 +172,12 @@ namespace mRemoteNG.Connection
return null;
}
private static string SetConnectionPanel(ConnectionInfo connectionInfo, ConnectionInfo.Force force)
private string SetConnectionPanel(ConnectionInfo connectionInfo, ConnectionInfo.Force force)
{
var connectionPanel = "";
if (connectionInfo.Panel == "" || (force & ConnectionInfo.Force.OverridePanel) == ConnectionInfo.Force.OverridePanel | Settings.Default.AlwaysShowPanelSelectionDlg)
{
var frmPnl = new frmChoosePanel();
var frmPnl = new frmChoosePanel(Adder, _windowList);
if (frmPnl.ShowDialog() == DialogResult.OK)
{
connectionPanel = frmPnl.Panel;
@@ -178,24 +196,24 @@ namespace mRemoteNG.Connection
private Form SetConnectionForm(Form conForm, string connectionPanel)
{
var connectionForm = conForm ?? Runtime.WindowList.FromString(connectionPanel);
var connectionForm = conForm ?? _windowList.FromString(connectionPanel);
if (connectionForm == null)
connectionForm = _panelAdder.AddPanel(connectionPanel);
connectionForm = Adder.AddPanel(connectionPanel);
else
((ConnectionWindow)connectionForm).Show(FrmMain.Default.pnlDock);
((ConnectionWindow)connectionForm).Show(_frmMain.pnlDock);
connectionForm.Focus();
return connectionForm;
}
private static Control SetConnectionContainer(ConnectionInfo connectionInfo, Form connectionForm)
private Control SetConnectionContainer(ConnectionInfo connectionInfo, Form connectionForm)
{
Control connectionContainer = ((ConnectionWindow)connectionForm).AddConnectionTab(connectionInfo);
if (connectionInfo.Protocol != ProtocolType.IntApp) return connectionContainer;
var extT = Runtime.ExternalToolsService.GetExtAppByName(connectionInfo.ExtApp);
var extT = _externalToolsService.GetExtAppByName(connectionInfo.ExtApp);
if(extT == null) return connectionContainer;
@@ -210,7 +228,7 @@ namespace mRemoteNG.Connection
newProtocol.Closed += ((ConnectionWindow)connectionForm).Prot_Event_Closed;
}
private static void SetConnectionEventHandlers(ProtocolBase newProtocol)
private void SetConnectionEventHandlers(ProtocolBase newProtocol)
{
newProtocol.Disconnected += Prot_Event_Disconnected;
newProtocol.Connected += Prot_Event_Connected;
@@ -251,7 +269,7 @@ namespace mRemoteNG.Connection
}
}
private static void Prot_Event_Closed(object sender)
private void Prot_Event_Closed(object sender)
{
try
{
@@ -269,7 +287,7 @@ namespace mRemoteNG.Connection
prot.InterfaceControl.Info.OpenConnections.Remove(prot);
if (prot.InterfaceControl.Info.PostExtApp == "") return;
var extA = Runtime.ExternalToolsService.GetExtAppByName(prot.InterfaceControl.Info.PostExtApp);
var extA = _externalToolsService.GetExtAppByName(prot.InterfaceControl.Info.PostExtApp);
extA?.Start(prot.InterfaceControl.Info);
}
catch (Exception ex)

View File

@@ -1,11 +1,13 @@
using System;
using System.IO;
using System.Security;
using System.Threading;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.App.Info;
using mRemoteNG.Config.Connections;
using mRemoteNG.Config.Connections.Multiuser;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Config.Putty;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Messages;
@@ -14,13 +16,17 @@ using mRemoteNG.Tools;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using mRemoteNG.UI;
using mRemoteNG.UI.TaskDialog;
namespace mRemoteNG.Connection
{
public class ConnectionsService
public class ConnectionsService : IConnectionsService
{
private static readonly object SaveLock = new object();
private bool _showDialogWhenLoadingConnections;
private readonly PuttySessionsManager _puttySessionsManager;
private readonly Import _import;
private readonly IWin32Window _dialogWindowParent;
private bool _batchingSaves = false;
private bool _saveRequested = false;
private bool _saveAsyncRequested = false;
@@ -30,15 +36,16 @@ namespace mRemoteNG.Connection
public string ConnectionFileName { get; private set; }
public RemoteConnectionsSyncronizer RemoteConnectionsSyncronizer { get; set; }
public DateTime LastSqlUpdate { get; set; }
public SecureString EncryptionKey { get; set; } = new RootNodeInfo(RootNodeType.Connection).PasswordString.ConvertToSecureString();
// TODO - this is only a property to break up a circular dependency. move to ctor when able
public DatabaseConnectorFactory DatabaseConnectorFactory { get; set; }
public ConnectionTreeModel ConnectionTreeModel { get; private set; }
public ConnectionsService(PuttySessionsManager puttySessionsManager)
public ConnectionsService(PuttySessionsManager puttySessionsManager, Import import, IWin32Window dialogWindowParent)
{
if (puttySessionsManager == null)
throw new ArgumentNullException(nameof(puttySessionsManager));
_puttySessionsManager = puttySessionsManager;
_puttySessionsManager = puttySessionsManager.ThrowIfNull(nameof(puttySessionsManager));
_import = import.ThrowIfNull(nameof(import));
_dialogWindowParent = dialogWindowParent.ThrowIfNull(nameof(dialogWindowParent));
}
public void NewConnectionsFile(string filename)
@@ -107,12 +114,12 @@ namespace mRemoteNG.Connection
var oldIsUsingDatabaseValue = UsingDatabase;
var newConnectionTreeModel = useDatabase
? new SqlConnectionsLoader().Load()
: new XmlConnectionsLoader(connectionFileName).Load();
? new SqlConnectionsLoader(DatabaseConnectorFactory, this).Load()
: new XmlConnectionsLoader(connectionFileName, this, _dialogWindowParent).Load();
if (newConnectionTreeModel == null)
{
DialogFactory.ShowLoadConnectionsFailedDialog(connectionFileName, "Decrypting connection file failed", IsConnectionsFileLoaded);
DialogFactory.ShowLoadConnectionsFailedDialog(connectionFileName, "Decrypting connection file failed", IsConnectionsFileLoaded, this);
return;
}
@@ -196,7 +203,7 @@ namespace mRemoteNG.Connection
var previouslyUsingDatabase = UsingDatabase;
if (useDatabase)
new SqlConnectionsSaver(saveFilter).Save(connectionTreeModel);
new SqlConnectionsSaver(saveFilter, this, DatabaseConnectorFactory).Save(connectionTreeModel);
else
new XmlConnectionsSaver(connectionFileName, saveFilter).Save(connectionTreeModel);
@@ -239,6 +246,157 @@ namespace mRemoteNG.Connection
}
}
public void LoadConnectionsAsync()
{
_showDialogWhenLoadingConnections = false;
var t = new Thread(LoadConnectionsBGd);
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
private void LoadConnectionsBGd()
{
LoadConnections(_showDialogWhenLoadingConnections);
}
public void LoadConnections(bool withDialog = false)
{
var connectionFileName = "";
try
{
// disable sql update checking while we are loading updates
RemoteConnectionsSyncronizer?.Disable();
if (!Settings.Default.UseSQLServer)
{
if (withDialog)
{
var loadDialog = DialogFactory.BuildLoadConnectionsDialog();
if (loadDialog.ShowDialog() != DialogResult.OK) return;
connectionFileName = loadDialog.FileName;
}
else
{
connectionFileName = GetStartupConnectionFileName();
}
}
LoadConnections(Settings.Default.UseSQLServer, false, connectionFileName);
if (Settings.Default.UseSQLServer)
{
LastSqlUpdate = DateTime.Now;
}
else
{
if (connectionFileName == GetDefaultStartupConnectionFileName())
{
Settings.Default.LoadConsFromCustomLocation = false;
}
else
{
Settings.Default.LoadConsFromCustomLocation = true;
Settings.Default.CustomConsPath = connectionFileName;
}
}
// re-enable sql update checking after updates are loaded
RemoteConnectionsSyncronizer?.Enable();
}
catch (Exception ex)
{
if (Settings.Default.UseSQLServer)
{
Runtime.MessageCollector.AddExceptionMessage(Language.strLoadFromSqlFailed, ex);
var commandButtons = string.Join("|", Language.strCommandTryAgain, Language.strCommandOpenConnectionFile, string.Format(Language.strCommandExitProgram, Application.ProductName));
CTaskDialog.ShowCommandBox(Application.ProductName, Language.strLoadFromSqlFailed, Language.strLoadFromSqlFailedContent, MiscTools.GetExceptionMessageRecursive(ex), "", "", commandButtons, false, ESysIcons.Error, ESysIcons.Error);
switch (CTaskDialog.CommandButtonResult)
{
case 0:
LoadConnections(withDialog);
return;
case 1:
Settings.Default.UseSQLServer = false;
LoadConnections(true);
return;
default:
Application.Exit();
return;
}
}
if (ex is FileNotFoundException && !withDialog)
{
Runtime.MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotBeLoadedNew, connectionFileName), ex, MessageClass.InformationMsg);
string[] commandButtons =
{
Language.ConfigurationCreateNew,
Language.ConfigurationCustomPath,
Language.ConfigurationImportFile,
Language.strMenuExit
};
var answered = false;
while (!answered)
{
try
{
CTaskDialog.ShowTaskDialogBox(
GeneralAppInfo.ProductName,
Language.ConnectionFileNotFound,
"", "", "", "", "",
string.Join(" | ", commandButtons),
ETaskDialogButtons.None,
ESysIcons.Question,
ESysIcons.Question);
switch (CTaskDialog.CommandButtonResult)
{
case 0:
NewConnectionsFile(connectionFileName);
answered = true;
break;
case 1:
LoadConnections(true);
answered = true;
break;
case 2:
NewConnectionsFile(connectionFileName);
_import.ImportFromFile(ConnectionTreeModel.RootNodes[0]);
answered = true;
break;
case 3:
Application.Exit();
answered = true;
break;
}
}
catch (Exception exc)
{
Runtime.MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotBeLoadedNew, connectionFileName), exc, MessageClass.InformationMsg);
}
}
return;
}
Runtime.MessageCollector.AddExceptionStackTrace(string.Format(Language.strConnectionsFileCouldNotBeLoaded, connectionFileName), ex);
if (connectionFileName != GetStartupConnectionFileName())
{
LoadConnections(withDialog);
}
else
{
MessageBox.Show(_dialogWindowParent,
string.Format(Language.strErrorStartupConnectionFileLoad, Environment.NewLine, Application.ProductName, GetStartupConnectionFileName(), MiscTools.GetExceptionMessageRecursive(ex)),
@"Could not load startup file.", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.Exit();
}
}
}
public string GetStartupConnectionFileName()
{
return Settings.Default.LoadConsFromCustomLocation == false

View File

@@ -0,0 +1,39 @@
using System;
using System.Security;
using mRemoteNG.Config.Connections;
using mRemoteNG.Config.Connections.Multiuser;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Security;
using mRemoteNG.Tree;
namespace mRemoteNG.Connection
{
public interface IConnectionsService
{
string ConnectionFileName { get; }
ConnectionTreeModel ConnectionTreeModel { get; }
DatabaseConnectorFactory DatabaseConnectorFactory { get; set; }
SecureString EncryptionKey { get; set; }
bool IsConnectionsFileLoaded { get; set; }
DateTime LastSqlUpdate { get; set; }
RemoteConnectionsSyncronizer RemoteConnectionsSyncronizer { get; set; }
bool UsingDatabase { get; }
event EventHandler<ConnectionsLoadedEventArgs> ConnectionsLoaded;
event EventHandler<ConnectionsSavedEventArgs> ConnectionsSaved;
ConnectionInfo CreateQuickConnect(string connectionString, ProtocolType protocol);
string GetDefaultStartupConnectionFileName();
string GetStartupConnectionFileName();
void LoadConnections(bool withDialog = false);
void LoadConnections(bool useDatabase, bool import, string connectionFileName);
void LoadConnectionsAsync();
void NewConnectionsFile(string filename);
void SaveConnections();
void SaveConnections(ConnectionTreeModel connectionTreeModel, bool useDatabase, SaveFilter saveFilter, string connectionFileName, bool forceSave = false);
void SaveConnectionsAsync();
void BeginBatchingSaves();
void EndBatchingSaves();
}
}

View File

@@ -17,12 +17,15 @@ namespace mRemoteNG.Connection.Protocol.ICA
{
private AxICAClient _icaClient;
private ConnectionInfo _info;
private readonly FrmMain _frmMain = FrmMain.Default;
private readonly FrmMain _frmMain;
private readonly IConnectionsService _connectionsService;
#region Public Methods
public IcaProtocol()
public IcaProtocol(FrmMain frmMain, IConnectionsService connectionsService)
{
try
_frmMain = frmMain.ThrowIfNull(nameof(frmMain));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
try
{
Control = new AxICAClient();
}
@@ -144,7 +147,7 @@ namespace mRemoteNG.Connection.Protocol.ICA
if (Settings.Default.DefaultPassword != "")
{
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
_icaClient.SetProp("ClearPassword", cryptographyProvider.Decrypt(Settings.Default.DefaultPassword, Runtime.EncryptionKey));
_icaClient.SetProp("ClearPassword", cryptographyProvider.Decrypt(Settings.Default.DefaultPassword, _connectionsService.EncryptionKey));
}
}
}

View File

@@ -11,19 +11,25 @@ namespace mRemoteNG.Connection.Protocol
{
public class IntegratedProgram : ProtocolBase
{
#region Private Fields
private readonly ExternalToolsService _externalToolsService;
private ExternalTool _externalTool;
private IntPtr _handle;
private Process _process;
#endregion
private readonly IConnectionsService _connectionsService;
#region Public Methods
public IntegratedProgram(ExternalToolsService externalToolsService, IConnectionsService connectionsService)
{
_externalToolsService = externalToolsService.ThrowIfNull(nameof(externalToolsService));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
}
#region Public Methods
public override bool Initialize()
{
if (InterfaceControl.Info == null)
return base.Initialize();
_externalTool = Runtime.ExternalToolsService.GetExtAppByName(InterfaceControl.Info.ExtApp);
_externalTool = _externalToolsService.GetExtAppByName(InterfaceControl.Info.ExtApp);
if (_externalTool == null)
{
@@ -54,7 +60,7 @@ namespace mRemoteNG.Connection.Protocol
return false;
}
var argParser = new ExternalToolArgumentParser(_externalTool.ConnectionInfo);
var argParser = new ExternalToolArgumentParser(_externalTool.ConnectionInfo, _connectionsService);
_process = new Process
{
StartInfo =

View File

@@ -7,11 +7,24 @@ using mRemoteNG.Connection.Protocol.SSH;
using mRemoteNG.Connection.Protocol.Telnet;
using mRemoteNG.Connection.Protocol.VNC;
using System;
using mRemoteNG.Tools;
using mRemoteNG.UI.Forms;
namespace mRemoteNG.Connection.Protocol
{
public class ProtocolFactory
{
private readonly ExternalToolsService _externalToolsService;
private readonly FrmMain _frmMain;
private readonly IConnectionsService _connectionsService;
public ProtocolFactory(ExternalToolsService externalToolsService, FrmMain frmMain, IConnectionsService connectionsService)
{
_externalToolsService = externalToolsService.ThrowIfNull(nameof(externalToolsService));
_frmMain = frmMain.ThrowIfNull(nameof(frmMain));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
}
public ProtocolBase CreateProtocol(ConnectionInfo connectionInfo)
{
var newProtocol = default(ProtocolBase);
@@ -19,7 +32,7 @@ namespace mRemoteNG.Connection.Protocol
switch (connectionInfo.Protocol)
{
case ProtocolType.RDP:
newProtocol = new RdpProtocol
newProtocol = new RdpProtocol(_frmMain, _connectionsService)
{
LoadBalanceInfoUseUtf8 = Settings.Default.RdpLoadBalanceInfoUseUtf8
};
@@ -29,19 +42,19 @@ namespace mRemoteNG.Connection.Protocol
newProtocol = new ProtocolVNC();
break;
case ProtocolType.SSH1:
newProtocol = new ProtocolSSH1();
newProtocol = new ProtocolSSH1(_connectionsService);
break;
case ProtocolType.SSH2:
newProtocol = new ProtocolSSH2();
newProtocol = new ProtocolSSH2(_connectionsService);
break;
case ProtocolType.Telnet:
newProtocol = new ProtocolTelnet();
newProtocol = new ProtocolTelnet(_connectionsService);
break;
case ProtocolType.Rlogin:
newProtocol = new ProtocolRlogin();
newProtocol = new ProtocolRlogin(_connectionsService);
break;
case ProtocolType.RAW:
newProtocol = new RawProtocol();
newProtocol = new RawProtocol(_connectionsService);
break;
case ProtocolType.HTTP:
newProtocol = new ProtocolHTTP(connectionInfo.RenderingEngine);
@@ -50,11 +63,11 @@ namespace mRemoteNG.Connection.Protocol
newProtocol = new ProtocolHTTPS(connectionInfo.RenderingEngine);
break;
case ProtocolType.ICA:
newProtocol = new IcaProtocol();
newProtocol = new IcaProtocol(_frmMain, _connectionsService);
((IcaProtocol) newProtocol).tmrReconnect.Elapsed += ((IcaProtocol) newProtocol).tmrReconnect_Elapsed;
break;
case ProtocolType.IntApp:
newProtocol = new IntegratedProgram();
newProtocol = new IntegratedProgram(_externalToolsService, _connectionsService);
if (connectionInfo.ExtApp == "")
{
throw (new Exception(Language.strNoExtAppDefined));

View File

@@ -16,6 +16,12 @@ namespace mRemoteNG.Connection.Protocol
{
private const int IDM_RECONF = 0x50; // PuTTY Settings Menu ID
private bool _isPuttyNg;
private readonly IConnectionsService _connectionsService;
public PuttyBase(IConnectionsService connectionsService)
{
_connectionsService = connectionsService;
}
#region Public Properties
@@ -99,7 +105,7 @@ namespace mRemoteNG.Connection.Protocol
if (Settings.Default.EmptyCredentials == "custom")
{
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
password = cryptographyProvider.Decrypt(Settings.Default.DefaultPassword, Runtime.EncryptionKey);
password = cryptographyProvider.Decrypt(Settings.Default.DefaultPassword, _connectionsService.EncryptionKey);
}
}

View File

@@ -2,7 +2,8 @@ namespace mRemoteNG.Connection.Protocol.RAW
{
public class RawProtocol : PuttyBase
{
public RawProtocol()
public RawProtocol(IConnectionsService connectionsService)
: base(connectionsService)
{
PuttyProtocol = Putty_Protocol.raw;
}

View File

@@ -30,7 +30,8 @@ namespace mRemoteNG.Connection.Protocol.RDP
private bool _loginComplete;
private bool _redirectKeys;
private bool _alertOnIdleDisconnect;
private readonly FrmMain _frmMain = FrmMain.Default;
private readonly FrmMain _frmMain;
private readonly IConnectionsService _connectionsService;
#region Properties
public bool SmartSize
@@ -92,8 +93,10 @@ namespace mRemoteNG.Connection.Protocol.RDP
#endregion
#region Constructors
public RdpProtocol()
public RdpProtocol(FrmMain frmMain, IConnectionsService connectionsService)
{
_frmMain = frmMain;
_connectionsService = connectionsService;
Control = new AxMsRdpClient8NotSafeForScripting();
}
#endregion
@@ -453,7 +456,7 @@ namespace mRemoteNG.Connection.Protocol.RDP
if (Settings.Default.DefaultPassword != "")
{
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
_rdpClient.AdvancedSettings2.ClearTextPassword = cryptographyProvider.Decrypt(Settings.Default.DefaultPassword, Runtime.EncryptionKey);
_rdpClient.AdvancedSettings2.ClearTextPassword = cryptographyProvider.Decrypt(Settings.Default.DefaultPassword, _connectionsService.EncryptionKey);
}
}
}

View File

@@ -3,7 +3,8 @@ namespace mRemoteNG.Connection.Protocol.Rlogin
public class ProtocolRlogin : PuttyBase
{
public ProtocolRlogin()
public ProtocolRlogin(IConnectionsService connectionsService)
: base(connectionsService)
{
this.PuttyProtocol = Putty_Protocol.rlogin;
}

View File

@@ -5,7 +5,7 @@ namespace mRemoteNG.Connection.Protocol.SSH
public class ProtocolSSH1 : PuttyBase
{
public ProtocolSSH1()
public ProtocolSSH1(IConnectionsService connectionsService) : base(connectionsService)
{
this.PuttyProtocol = Putty_Protocol.ssh;
this.PuttySSHVersion = Putty_SSHVersion.ssh1;

View File

@@ -3,7 +3,7 @@ namespace mRemoteNG.Connection.Protocol.SSH
public class ProtocolSSH2 : PuttyBase
{
public ProtocolSSH2()
public ProtocolSSH2(IConnectionsService connectionsService) : base(connectionsService)
{
this.PuttyProtocol = Putty_Protocol.ssh;
this.PuttySSHVersion = Putty_SSHVersion.ssh2;

View File

@@ -3,7 +3,7 @@ namespace mRemoteNG.Connection.Protocol.Serial
public class ProtocolSerial : PuttyBase
{
public ProtocolSerial()
public ProtocolSerial(IConnectionsService connectionsService) : base(connectionsService)
{
this.PuttyProtocol = Putty_Protocol.serial;
}

View File

@@ -3,7 +3,7 @@ namespace mRemoteNG.Connection.Protocol.Telnet
public class ProtocolTelnet : PuttyBase
{
public ProtocolTelnet()
public ProtocolTelnet(IConnectionsService connectionsService) : base(connectionsService)
{
this.PuttyProtocol = Putty_Protocol.telnet;
}

View File

@@ -1,10 +1,18 @@
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Tools;
namespace mRemoteNG.Connection
{
public class WebHelper
{
public static void GoToUrl(string url)
private readonly IConnectionInitiator _connectionInitiator;
public WebHelper(IConnectionInitiator connectionInitiator)
{
_connectionInitiator = connectionInitiator.ThrowIfNull(nameof(connectionInitiator));
}
public void GoToUrl(string url)
{
var connectionInfo = new ConnectionInfo();
connectionInfo.CopyFrom(DefaultConnectionInfo.Instance);
@@ -16,8 +24,7 @@ namespace mRemoteNG.Connection
if (string.IsNullOrEmpty(connectionInfo.Panel))
connectionInfo.Panel = Language.strGeneral;
connectionInfo.IsQuickConnect = true;
var connectionInitiator = new ConnectionInitiator();
connectionInitiator.OpenConnection(connectionInfo, ConnectionInfo.Force.DoNotJump);
_connectionInitiator.OpenConnection(connectionInfo, ConnectionInfo.Force.DoNotJump);
}
}
}

View File

@@ -9,6 +9,8 @@ namespace mRemoteNG.Credential
{
public class CredentialRecordTypeConverter : TypeConverter
{
public static ICredentialRepositoryList CredentialRepositoryList { get; set; }
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(Guid) ||
@@ -34,7 +36,7 @@ namespace mRemoteNG.Credential
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (!(value is Guid)) return base.ConvertFrom(context, culture, value);
var matchedCredentials = Runtime.CredentialProviderCatalog.GetCredentialRecords().Where(record => record.Id.Equals(value)).ToArray();
var matchedCredentials = CredentialRepositoryList.GetCredentialRecords().Where(record => record.Id.Equals(value)).ToArray();
return matchedCredentials.Any() ? matchedCredentials.First() : null;
}
}

View File

@@ -6,11 +6,19 @@ using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Serializers.CredentialProviderSerializer;
using mRemoteNG.Config.Serializers.CredentialSerializer;
using mRemoteNG.Security.Factories;
using mRemoteNG.Tools;
namespace mRemoteNG.Credential
{
public class CredentialServiceFactory
{
private ICredentialRepositoryList _credentialRepositoryList;
public CredentialServiceFactory(ICredentialRepositoryList credentialRepositoryList)
{
_credentialRepositoryList = credentialRepositoryList.ThrowIfNull(nameof(credentialRepositoryList));
}
// When we get a true CompositionRoot we can move this to that class. We should only require 1 instance of this service at a time
public CredentialServiceFacade Build()
{
@@ -27,7 +35,7 @@ namespace mRemoteNG.Credential
new CredentialRepositoryListDeserializer(credRepoSerializer, credRepoDeserializer));
var repoListSaver = new CredentialRepositoryListSaver(repoListDataProvider);
return new CredentialServiceFacade(Runtime.CredentialProviderCatalog, repoListLoader, repoListSaver);
return new CredentialServiceFacade(_credentialRepositoryList, repoListLoader, repoListSaver);
}
}
}

View File

@@ -2,6 +2,7 @@
using System.Threading.Tasks;
using System.Windows.Forms;
using mRemoteNG.Messages.MessageWriters;
using mRemoteNG.Tools;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.Window;
using WeifenLuo.WinFormsUI.Docking;
@@ -13,13 +14,14 @@ namespace mRemoteNG.Messages.WriterDecorators
private readonly IMessageTypeFilteringOptions _filter;
private readonly IMessageWriter _decoratedWriter;
private readonly ErrorAndInfoWindow _messageWindow;
private readonly FrmMain _frmMain = FrmMain.Default;
private readonly FrmMain _frmMain;
public MessageFocusDecorator(ErrorAndInfoWindow messageWindow, IMessageTypeFilteringOptions filter, IMessageWriter decoratedWriter)
public MessageFocusDecorator(FrmMain frmMain, ErrorAndInfoWindow messageWindow, IMessageTypeFilteringOptions filter, IMessageWriter decoratedWriter)
{
_filter = filter ?? throw new ArgumentNullException(nameof(filter));
_messageWindow = messageWindow ?? throw new ArgumentNullException(nameof(messageWindow));
_decoratedWriter = decoratedWriter ?? throw new ArgumentNullException(nameof(decoratedWriter));
_frmMain = frmMain.ThrowIfNull(nameof(frmMain));
_filter = filter.ThrowIfNull(nameof(filter));
_messageWindow = messageWindow.ThrowIfNull(nameof(messageWindow));
_decoratedWriter = decoratedWriter.ThrowIfNull(nameof(decoratedWriter));
}
public async void Write(IMessage message)
@@ -91,4 +93,4 @@ namespace mRemoteNG.Messages.WriterDecorators
content.DockState == DockState.DockRightAutoHide;
}
}
}
}

View File

@@ -4,6 +4,7 @@ using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using mRemoteNG.App;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
@@ -14,15 +15,16 @@ namespace mRemoteNG.Tools
{
public class ExternalTool : INotifyPropertyChanged
{
private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator();
private string _displayName;
private string _fileName;
private readonly IConnectionInitiator _connectionInitiator;
private string _displayName = "";
private string _fileName = "";
private bool _waitForExit;
private string _arguments;
private string _workingDir;
private string _arguments = "";
private string _workingDir = "";
private bool _tryIntegrate;
private bool _showOnToolbar = true;
private bool _runElevated;
private readonly IConnectionsService _connectionsService;
#region Public Properties
@@ -100,16 +102,13 @@ namespace mRemoteNG.Tools
#endregion
public ExternalTool(string displayName = "", string fileName = "", string arguments = "", string workingDir = "", bool runElevated = false)
public ExternalTool(IConnectionInitiator connectionInitiator, IConnectionsService connectionsService)
{
DisplayName = displayName;
FileName = fileName;
Arguments = arguments;
WorkingDir = workingDir;
RunElevated = runElevated;
_connectionInitiator = connectionInitiator.ThrowIfNull(nameof(connectionInitiator));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
}
public void Start(ConnectionInfo startConnectionInfo = null)
public void Start(Optional<ConnectionInfo> startConnectionInfo)
{
try
{
@@ -119,7 +118,7 @@ namespace mRemoteNG.Tools
return;
}
ConnectionInfo = startConnectionInfo;
ConnectionInfo = startConnectionInfo.FirstOrDefault();
if (TryIntegrate)
StartIntegrated();
@@ -146,7 +145,7 @@ namespace mRemoteNG.Tools
private void SetProcessProperties(Process process, ConnectionInfo startConnectionInfo)
{
var argParser = new ExternalToolArgumentParser(startConnectionInfo);
var argParser = new ExternalToolArgumentParser(startConnectionInfo, _connectionsService);
process.StartInfo.UseShellExecute = true;
process.StartInfo.FileName = argParser.ParseArguments(FileName);
process.StartInfo.Arguments = argParser.ParseArguments(Arguments);

View File

@@ -10,10 +10,12 @@ namespace mRemoteNG.Tools
public class ExternalToolArgumentParser
{
private readonly ConnectionInfo _connectionInfo;
private readonly IConnectionsService _connectionsService;
public ExternalToolArgumentParser(ConnectionInfo connectionInfo)
public ExternalToolArgumentParser(ConnectionInfo connectionInfo, IConnectionsService connectionsService)
{
_connectionInfo = connectionInfo;
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
}
public string ParseArguments(string input)
@@ -183,7 +185,7 @@ namespace mRemoteNG.Tools
if (string.IsNullOrEmpty(replacement) && Settings.Default.EmptyCredentials == "custom")
replacement = new LegacyRijndaelCryptographyProvider()
.Decrypt(Convert.ToString(Settings.Default.DefaultPassword),
Runtime.EncryptionKey);
_connectionsService.EncryptionKey);
break;
case "domain":
replacement = _connectionInfo.Domain;

View File

@@ -5,6 +5,8 @@ namespace mRemoteNG.Tools
{
public class ExternalToolsTypeConverter : StringConverter
{
public static ExternalToolsService ExternalToolsService { get; set; }
public static string[] ExternalTools
{
get
@@ -14,7 +16,7 @@ namespace mRemoteNG.Tools
// Add a blank entry to signify that no external tool is selected
externalToolList.Add(string.Empty);
foreach (var externalTool in App.Runtime.ExternalToolsService.ExternalTools)
foreach (var externalTool in ExternalToolsService.ExternalTools)
{
externalToolList.Add(externalTool.DisplayName);
}
@@ -28,7 +30,7 @@ namespace mRemoteNG.Tools
return new StandardValuesCollection(ExternalTools);
}
public override bool GetStandardValuesExclusive(System.ComponentModel.ITypeDescriptorContext context)
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;
}

View File

@@ -14,16 +14,19 @@ namespace mRemoteNG.Tools
private ArrayList quickConnectConnections = new ArrayList();
private ArrayList previousCommands = new ArrayList();
private int previousCommandIndex = 0;
private readonly IConnectionsService _connectionsService;
public int CommandHistoryLength { get; set; } = 100;
public MultiSSHController(TextBox txtBox)
public MultiSSHController(TextBox txtBox, IConnectionsService connectionsService)
{
DecorateTextBox(txtBox);
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
}
public MultiSSHController(ToolStripTextBox txtBox)
public MultiSSHController(ToolStripTextBox txtBox, IConnectionsService connectionsService)
{
_connectionsService = connectionsService;
DecorateTextBox(txtBox.TextBox);
}
@@ -75,7 +78,7 @@ namespace mRemoteNG.Tools
processHandlers.AddRange(ProcessOpenConnections(connection));
}
var connectionTreeConnections = Runtime.ConnectionsService.ConnectionTreeModel.GetRecursiveChildList().Where(item => item.OpenConnections.Count > 0);
var connectionTreeConnections = _connectionsService.ConnectionTreeModel.GetRecursiveChildList().Where(item => item.OpenConnections.Count > 0);
foreach (ConnectionInfo connection in connectionTreeConnections)
{

View File

@@ -14,13 +14,20 @@ namespace mRemoteNG.Tools
private readonly NotifyIcon _nI;
private readonly ContextMenuStrip _cMen;
private readonly ToolStripMenuItem _cMenCons;
private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator();
private static readonly FrmMain FrmMain = FrmMain.Default;
private readonly IConnectionInitiator _connectionInitiator;
private readonly FrmMain _frmMain;
private readonly Shutdown _shutdown;
private readonly IConnectionsService _connectionsService;
public bool Disposed { get; private set; }
public NotificationAreaIcon()
public NotificationAreaIcon(FrmMain frmMain, IConnectionInitiator connectionInitiator, Shutdown shutdown, IConnectionsService connectionsService)
{
_frmMain = frmMain.ThrowIfNull(nameof(frmMain));
_connectionInitiator = connectionInitiator.ThrowIfNull(nameof(connectionInitiator));
_shutdown = shutdown.ThrowIfNull(nameof(shutdown));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
try
{
_cMenCons = new ToolStripMenuItem
@@ -85,46 +92,46 @@ namespace mRemoteNG.Tools
};
// ReSharper disable once CoVariantArrayConversion
ToolStripItem[] rootMenuItems = menuItemsConverter.CreateToolStripDropDownItems(Runtime.ConnectionsService.ConnectionTreeModel).ToArray();
ToolStripItem[] rootMenuItems = menuItemsConverter.CreateToolStripDropDownItems(_connectionsService.ConnectionTreeModel).ToArray();
_cMenCons.DropDownItems.AddRange(rootMenuItems);
}
private static void nI_MouseDoubleClick(object sender, MouseEventArgs e)
private void nI_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (FrmMain.Visible)
if (_frmMain.Visible)
HideForm();
else
ShowForm();
}
private static void ShowForm()
private void ShowForm()
{
FrmMain.Show();
FrmMain.WindowState = FrmMain.PreviousWindowState;
_frmMain.Show();
_frmMain.WindowState = _frmMain.PreviousWindowState;
if (Settings.Default.ShowSystemTrayIcon) return;
Runtime.NotificationAreaIcon.Dispose();
Runtime.NotificationAreaIcon = null;
}
private static void HideForm()
private void HideForm()
{
FrmMain.Hide();
FrmMain.PreviousWindowState = FrmMain.WindowState;
_frmMain.Hide();
_frmMain.PreviousWindowState = _frmMain.WindowState;
}
private void ConMenItem_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
if (((ToolStripMenuItem)sender).Tag is ContainerInfo) return;
if (FrmMain.Visible == false)
if (_frmMain.Visible == false)
ShowForm();
_connectionInitiator.OpenConnection((ConnectionInfo) ((ToolStripMenuItem) sender).Tag);
}
private static void cMenExit_Click(object sender, EventArgs e)
private void cMenExit_Click(object sender, EventArgs e)
{
Shutdown.Quit();
_shutdown.Quit();
}
}
}

View File

@@ -2,7 +2,7 @@
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms.Design;
using mRemoteNG.App;
using mRemoteNG.Credential;
namespace mRemoteNG.UI.Controls.Adapters
{
@@ -10,6 +10,8 @@ namespace mRemoteNG.UI.Controls.Adapters
{
private IWindowsFormsEditorService _editorService;
public static ICredentialRepositoryList CredentialRepositoryList { get; set; }
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
@@ -21,9 +23,7 @@ namespace mRemoteNG.UI.Controls.Adapters
_editorService = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
if (_editorService == null) return value;
var credentialManager = Runtime.CredentialProviderCatalog;
var listBox = new CredentialRecordListBox(credentialManager.GetCredentialRecords());
var listBox = new CredentialRecordListBox(CredentialRepositoryList.GetCredentialRecords());
listBox.SelectedValueChanged += ListBoxOnSelectedValueChanged;
_editorService.DropDownControl(listBox);

View File

@@ -9,12 +9,14 @@ using mRemoteNG.Container;
using mRemoteNG.Tools;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using mRemoteNG.UI.Window;
// ReSharper disable UnusedParameter.Local
namespace mRemoteNG.UI.Controls
{
public sealed class ConnectionContextMenu : ContextMenuStrip
public sealed class ConnectionContextMenu : ContextMenuStrip
{
private ToolStripMenuItem _cMenTreeAddConnection;
private ToolStripMenuItem _cMenTreeAddFolder;
@@ -48,14 +50,35 @@ namespace mRemoteNG.UI.Controls
private ToolStripMenuItem _cMenTreeImportPortScan;
private readonly ConnectionTree _connectionTree;
private readonly IConnectionInitiator _connectionInitiator;
private readonly SSHTransferWindow _sshTransferWindow;
private readonly Export _export;
private readonly ExternalToolsService _externalToolsService;
private readonly Import _import;
private readonly IConnectionsService _connectionsService;
// TODO - this is only a property to break up a circular dependency
public Action<WindowType> ShowWindowAction { get; set; } = type => { };
public ConnectionContextMenu(ConnectionTree connectionTree)
public ConnectionContextMenu(
ConnectionTree connectionTree,
IConnectionInitiator connectionInitiator,
SSHTransferWindow sshTransferWindow,
Export export,
ExternalToolsService externalToolsService,
Import import,
IConnectionsService connectionsService)
{
_connectionTree = connectionTree;
_connectionInitiator = new ConnectionInitiator();
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
_connectionTree = connectionTree.ThrowIfNull(nameof(connectionTree));
_connectionInitiator = connectionInitiator.ThrowIfNull(nameof(connectionInitiator));
_sshTransferWindow = sshTransferWindow.ThrowIfNull(nameof(sshTransferWindow));
_export = export.ThrowIfNull(nameof(export));
_externalToolsService = externalToolsService.ThrowIfNull(nameof(externalToolsService));
_import = import.ThrowIfNull(nameof(import));
InitializeComponent();
ApplyLanguage();
ApplyLanguage();
EnableShortcutKeys();
Opening += (sender, args) =>
{
@@ -566,13 +589,13 @@ namespace mRemoteNG.UI.Controls
{
ResetExternalAppMenu();
foreach (ExternalTool extA in Runtime.ExternalToolsService.ExternalTools)
foreach (var externalTool in _externalToolsService.ExternalTools)
{
var menuItem = new ToolStripMenuItem
{
Text = extA.DisplayName,
Tag = extA,
Image = extA.Image
Text = externalTool.DisplayName,
Tag = externalTool,
Image = externalTool.Image
};
menuItem.Click += OnExternalToolClicked;
@@ -693,11 +716,11 @@ namespace mRemoteNG.UI.Controls
{
try
{
Windows.Show(WindowType.SSHTransfer);
Windows.SshtransferForm.Hostname = _connectionTree.SelectedNode.Hostname;
Windows.SshtransferForm.Username = _connectionTree.SelectedNode.Username;
Windows.SshtransferForm.Password = _connectionTree.SelectedNode.Password;
Windows.SshtransferForm.Port = Convert.ToString(_connectionTree.SelectedNode.Port);
ShowWindowAction(WindowType.SSHTransfer);
_sshTransferWindow.Hostname = _connectionTree.SelectedNode.Hostname;
_sshTransferWindow.Username = _connectionTree.SelectedNode.Username;
_sshTransferWindow.Password = _connectionTree.SelectedNode.Password;
_sshTransferWindow.Port = Convert.ToString(_connectionTree.SelectedNode.Port);
}
catch (Exception ex)
{
@@ -724,25 +747,25 @@ namespace mRemoteNG.UI.Controls
{
ContainerInfo selectedNodeAsContainer;
if (_connectionTree.SelectedNode == null)
selectedNodeAsContainer = Runtime.ConnectionsService.ConnectionTreeModel.RootNodes.First();
selectedNodeAsContainer = _connectionsService.ConnectionTreeModel.RootNodes.First();
else
selectedNodeAsContainer = _connectionTree.SelectedNode as ContainerInfo ?? _connectionTree.SelectedNode.Parent;
Import.ImportFromFile(selectedNodeAsContainer);
_import.ImportFromFile(selectedNodeAsContainer);
}
private void OnImportActiveDirectoryClicked(object sender, EventArgs e)
{
Windows.Show(WindowType.ActiveDirectoryImport);
ShowWindowAction(WindowType.ActiveDirectoryImport);
}
private void OnImportPortScanClicked(object sender, EventArgs e)
{
Windows.Show(WindowType.PortScan);
ShowWindowAction(WindowType.PortScan);
}
private void OnExportFileClicked(object sender, EventArgs e)
{
Export.ExportToFile(_connectionTree.SelectedNode, Runtime.ConnectionsService.ConnectionTreeModel);
_export.ExportToFile(_connectionTree.SelectedNode, _connectionsService.ConnectionTreeModel);
}
private void OnAddConnectionClicked(object sender, EventArgs e)

View File

@@ -11,6 +11,7 @@ using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
// ReSharper disable ArrangeAccessorOwnerBody
namespace mRemoteNG.UI.Controls
@@ -23,10 +24,11 @@ namespace mRemoteNG.UI.Controls
private readonly ConnectionTreeSearchTextFilter _connectionTreeSearchTextFilter = new ConnectionTreeSearchTextFilter();
private bool _nodeInEditMode;
private bool _allowEdit;
private ConnectionContextMenu _contextMenu;
private ConnectionTreeModel _connectionTreeModel;
public ConnectionInfo SelectedNode => (ConnectionInfo) SelectedObject;
public ConnectionInfo SelectedNode => (ConnectionInfo) SelectedObject;
public IConnectionsService ConnectionsService { get; set; }
public NodeSearcher NodeSearcher { get; private set; }
@@ -38,6 +40,7 @@ namespace mRemoteNG.UI.Controls
public ITreeNodeClickHandler<ConnectionInfo> SingleClickHandler { get; set; } = new TreeNodeCompositeClickHandler();
public ConnectionContextMenu ConnectionContextMenu { get; set; }
public ConnectionTreeModel ConnectionTreeModel
{
get { return _connectionTreeModel; }
@@ -72,8 +75,7 @@ namespace mRemoteNG.UI.Controls
SmallImageList = _statusImageList.ImageList;
AddColumns(_statusImageList.ImageGetter);
LinkModelToView();
_contextMenu = new ConnectionContextMenu(this);
ContextMenuStrip = _contextMenu;
ContextMenuStrip = ConnectionContextMenu;
SetupDropSink();
SetEventHandlers();
}
@@ -117,8 +119,9 @@ namespace mRemoteNG.UI.Controls
container.IsExpanded = true;
AutoResizeColumn(Columns[0]);
};
SelectionChanged += tvConnections_AfterSelect;
MouseDoubleClick += OnMouse_DoubleClick;
SelectionChanged += OnSelectionChanged;
MouseDoubleClick += OnMouse_DoubleClick;
MouseClick += OnMouse_SingleClick;
CellToolTipShowing += tvConnections_CellToolTipShowing;
ModelCanDrop += _dragAndDropHandler.HandleEvent_ModelCanDrop;
@@ -127,7 +130,7 @@ namespace mRemoteNG.UI.Controls
AfterLabelEdit += OnAfterLabelEdit;
}
/// <summary>
/// <summary>
/// Resizes the given column to ensure that all content is shown
/// </summary>
private void AutoResizeColumn(ColumnHeader column)
@@ -321,7 +324,7 @@ namespace mRemoteNG.UI.Controls
if (sortTarget == null)
sortTarget = GetRootConnectionNode();
Runtime.ConnectionsService.BeginBatchingSaves();
ConnectionsService.BeginBatchingSaves();
var sortTargetAsContainer = sortTarget as ContainerInfo;
if (sortTargetAsContainer != null)
@@ -329,7 +332,7 @@ namespace mRemoteNG.UI.Controls
else
SelectedNode.Parent.SortRecursive(sortDirection);
Runtime.ConnectionsService.EndBatchingSaves();
ConnectionsService.EndBatchingSaves();
}
/// <summary>
@@ -390,23 +393,10 @@ namespace mRemoteNG.UI.Controls
AutoResizeColumn(Columns[0]);
}
private void tvConnections_AfterSelect(object sender, EventArgs e)
{
try
{
Windows.ConfigForm.SelectedTreeNode = SelectedNode;
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_AfterSelect (UI.Window.ConnectionTreeWindow) failed", ex);
}
}
private void OnMouse_DoubleClick(object sender, MouseEventArgs mouseEventArgs)
{
if (mouseEventArgs.Clicks < 2) return;
OLVColumn column;
var listItem = GetItemAt(mouseEventArgs.X, mouseEventArgs.Y, out column);
var listItem = GetItemAt(mouseEventArgs.X, mouseEventArgs.Y, out _);
var clickedNode = listItem?.RowObject as ConnectionInfo;
if (clickedNode == null) return;
DoubleClickHandler.Execute(clickedNode);
@@ -415,8 +405,7 @@ namespace mRemoteNG.UI.Controls
private void OnMouse_SingleClick(object sender, MouseEventArgs mouseEventArgs)
{
if (mouseEventArgs.Clicks > 1) return;
OLVColumn column;
var listItem = GetItemAt(mouseEventArgs.X, mouseEventArgs.Y, out column);
var listItem = GetItemAt(mouseEventArgs.X, mouseEventArgs.Y, out _);
var clickedNode = listItem?.RowObject as ConnectionInfo;
if (clickedNode == null) return;
SingleClickHandler.Execute(clickedNode);
@@ -454,7 +443,7 @@ namespace mRemoteNG.UI.Controls
}
_nodeInEditMode = true;
_contextMenu.DisableShortcutKeys();
ConnectionContextMenu.DisableShortcutKeys();
}
private void OnAfterLabelEdit(object sender, LabelEditEventArgs e)
@@ -464,20 +453,32 @@ namespace mRemoteNG.UI.Controls
try
{
_contextMenu.EnableShortcutKeys();
ConnectionContextMenu.EnableShortcutKeys();
ConnectionTreeModel.RenameNode(SelectedNode, e.Label);
_nodeInEditMode = false;
_allowEdit = false;
// ensures that if we are filtering and a new item is added that doesn't match the filter, it will be filtered out
_connectionTreeSearchTextFilter.SpecialInclusionList.Clear();
UpdateFiltering();
Windows.ConfigForm.SelectedTreeNode = SelectedNode;
RaiseSelectedNodeChangedEvent(SelectedNode);
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_AfterLabelEdit (UI.Window.ConnectionTreeWindow) failed", ex);
}
}
#endregion
private void OnSelectionChanged(object o, EventArgs eventArgs)
{
RaiseSelectedNodeChangedEvent(SelectedNode);
}
#endregion
public event EventHandler<ConnectionInfo> SelectedNodeChanged;
private void RaiseSelectedNodeChangedEvent(ConnectionInfo selectedNode)
{
SelectedNodeChanged?.Invoke(this, selectedNode);
}
}
}

View File

@@ -2,22 +2,39 @@
using System.ComponentModel;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.Connection;
using mRemoteNG.Messages;
using mRemoteNG.Tools;
using mRemoteNG.Tools.CustomCollections;
using mRemoteNG.Tree;
namespace mRemoteNG.UI.Controls
{
public class ExternalToolsToolStrip : ToolStrip
public class ExternalToolsToolStrip : ToolStrip
{
private IContainer components;
private ContextMenuStrip _cMenExtAppsToolbar;
internal ToolStripMenuItem CMenToolbarShowText;
private ExternalToolsService _externalToolsService;
internal ToolStripMenuItem CMenToolbarShowText;
public Func<ConnectionInfo> GetSelectedConnectionFunc { get; set; }
public ExternalToolsService ExternalToolsService
{
get { return _externalToolsService; }
set
{
value.ThrowIfNull("value");
if (_externalToolsService != null)
_externalToolsService.ExternalTools.CollectionUpdated -= ExternalToolsOnCollectionUpdated;
_externalToolsService = value;
_externalToolsService.ExternalTools.CollectionUpdated += ExternalToolsOnCollectionUpdated;
}
}
public ExternalToolsToolStrip()
{
Initialize();
Runtime.ExternalToolsService.ExternalTools.CollectionUpdated += (sender, args) => AddExternalToolsToToolBar();
Initialize();
}
private void Initialize()
@@ -69,7 +86,7 @@ namespace mRemoteNG.UI.Controls
Items[index].Dispose();
Items.Clear();
foreach (var tool in Runtime.ExternalToolsService.ExternalTools)
foreach (var tool in ExternalToolsService.ExternalTools)
{
if (tool.ShowOnToolbar)
{
@@ -93,18 +110,18 @@ namespace mRemoteNG.UI.Controls
}
}
private static void tsExtAppEntry_Click(object sender, EventArgs e)
private void tsExtAppEntry_Click(object sender, EventArgs e)
{
var extA = (ExternalTool)((ToolStripButton)sender).Tag;
var selectedTreeNode = Windows.TreeForm.SelectedNode;
var selectedTreeNode = GetSelectedConnectionFunc();
if (selectedTreeNode != null && selectedTreeNode.GetTreeNodeType() == TreeNodeType.Connection |
selectedTreeNode.GetTreeNodeType() == TreeNodeType.PuttySession)
extA.Start(selectedTreeNode);
else
{
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, "No connection was selected, external tool may return errors.", true);
extA.Start();
extA.Start(null);
}
}
@@ -120,6 +137,11 @@ namespace mRemoteNG.UI.Controls
CMenToolbarShowText.Checked = show;
}
private void ExternalToolsOnCollectionUpdated(object o, CollectionUpdatedEventArgs<ExternalTool> collectionUpdatedEventArgs)
{
AddExternalToolsToToolBar();
}
#endregion
// CodeAyalysis doesn't like null propagation

View File

@@ -1,11 +1,12 @@
using System.ComponentModel;
using System.Windows.Forms;
using mRemoteNG.Connection;
using mRemoteNG.Themes;
using mRemoteNG.Tools;
using System.ComponentModel;
using System.Windows.Forms;
namespace mRemoteNG.UI.Controls
{
public class MultiSshToolStrip : ToolStrip
public class MultiSshToolStrip : ToolStrip
{
private IContainer components;
private ToolStripLabel _lblMultiSsh;
@@ -14,13 +15,17 @@ namespace mRemoteNG.UI.Controls
private ThemeManager _themeManager;
public MultiSshToolStrip()
public MultiSshToolStrip() : this(null)
{
}
public MultiSshToolStrip(IConnectionsService connectionsService)
{
InitializeComponent();
_multiSshController = new MultiSSHController(_txtMultiSsh, connectionsService);
_themeManager = ThemeManager.getInstance();
_themeManager.ThemeChanged += ApplyTheme;
ApplyTheme();
_multiSshController = new MultiSSHController(_txtMultiSsh);
}
private void InitializeComponent()

View File

@@ -11,7 +11,7 @@ using mRemoteNG.Tools;
namespace mRemoteNG.UI.Controls
{
public class QuickConnectToolStrip : ToolStrip
public class QuickConnectToolStrip : ToolStrip
{
private IContainer components;
private ToolStripLabel _lblQuickConnect;
@@ -20,20 +20,11 @@ namespace mRemoteNG.UI.Controls
private ContextMenuStrip _mnuQuickConnectProtocol;
private QuickConnectComboBox _cmbQuickConnect;
private ContextMenuStrip _mnuConnections;
private IConnectionInitiator _connectionInitiator = new ConnectionInitiator();
private ThemeManager _themeManager;
private readonly ThemeManager _themeManager;
private WeifenLuo.WinFormsUI.Docking.VisualStudioToolStripExtender vsToolStripExtender;
public IConnectionInitiator ConnectionInitiator
{
get { return _connectionInitiator; }
set
{
if (value == null)
return;
_connectionInitiator = value;
}
}
public IConnectionInitiator ConnectionInitiator { get; set; }
public IConnectionsService ConnectionsService { get; set; }
public QuickConnectToolStrip()
{
@@ -178,7 +169,7 @@ namespace mRemoteNG.UI.Controls
{
try
{
var connectionInfo = Runtime.ConnectionsService.CreateQuickConnect(_cmbQuickConnect.Text.Trim(), Converter.StringToProtocol(Settings.Default.QuickConnectProtocol));
var connectionInfo = ConnectionsService.CreateQuickConnect(_cmbQuickConnect.Text.Trim(), Converter.StringToProtocol(Settings.Default.QuickConnectProtocol));
if (connectionInfo == null)
{
_cmbQuickConnect.Focus();
@@ -225,7 +216,7 @@ namespace mRemoteNG.UI.Controls
};
// ReSharper disable once CoVariantArrayConversion
ToolStripItem[] rootMenuItems = menuItemsConverter.CreateToolStripDropDownItems(Runtime.ConnectionsService.ConnectionTreeModel).ToArray();
ToolStripItem[] rootMenuItems = menuItemsConverter.CreateToolStripDropDownItems(ConnectionsService.ConnectionTreeModel).ToArray();
_btnConnections.DropDownItems.AddRange(rootMenuItems);
}

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.App.Info;
using mRemoteNG.Connection;
using mRemoteNG.Messages;
using mRemoteNG.UI.TaskDialog;
@@ -28,7 +29,8 @@ namespace mRemoteNG.UI
/// <param name="connectionFileName"></param>
/// <param name="messageText"></param>
/// <param name="showCancelButton"></param>
public static void ShowLoadConnectionsFailedDialog(string connectionFileName, string messageText, bool showCancelButton)
/// <param name="connectionsService"></param>
public static void ShowLoadConnectionsFailedDialog(string connectionFileName, string messageText, bool showCancelButton, IConnectionsService connectionsService)
{
var commandButtons = new List<string>
{
@@ -59,11 +61,11 @@ namespace mRemoteNG.UI
case 0: // New
var saveAsDialog = ConnectionsSaveAsDialog();
saveAsDialog.ShowDialog();
Runtime.ConnectionsService.NewConnectionsFile(saveAsDialog.FileName);
connectionsService.NewConnectionsFile(saveAsDialog.FileName);
answered = true;
break;
case 1: // Load
Runtime.LoadConnections(true);
connectionsService.LoadConnections(true);
answered = true;
break;
case 2: // Exit

View File

@@ -1,14 +1,22 @@
using System;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.Connection;
using mRemoteNG.Tools;
namespace mRemoteNG.UI.Forms.OptionsPages
{
public sealed partial class AppearancePage
{
public AppearancePage()
private readonly IConnectionInitiator _connectionInitiator;
private readonly Func<NotificationAreaIcon> _notificationAreaIconBuilder;
private readonly FrmMain _frmMain;
public AppearancePage(IConnectionInitiator connectionInitiator, Func<NotificationAreaIcon> notificationAreaIconBuilder, FrmMain frmMain)
{
_connectionInitiator = connectionInitiator.ThrowIfNull(nameof(connectionInitiator));
_notificationAreaIconBuilder = notificationAreaIconBuilder;
_frmMain = frmMain.ThrowIfNull(nameof(frmMain));
InitializeComponent();
ApplyTheme();
}
@@ -74,14 +82,14 @@ namespace mRemoteNG.UI.Forms.OptionsPages
Settings.Default.ShowDescriptionTooltipsInTree = chkShowDescriptionTooltipsInTree.Checked;
Settings.Default.ShowCompleteConsPathInTitle = chkShowFullConnectionsFilePathInTitle.Checked;
FrmMain.Default.ShowFullPathInTitle = chkShowFullConnectionsFilePathInTitle.Checked;
_frmMain.ShowFullPathInTitle = chkShowFullConnectionsFilePathInTitle.Checked;
Settings.Default.ShowSystemTrayIcon = chkShowSystemTrayIcon.Checked;
if (Settings.Default.ShowSystemTrayIcon)
{
if (Runtime.NotificationAreaIcon == null)
{
Runtime.NotificationAreaIcon = new NotificationAreaIcon();
Runtime.NotificationAreaIcon = _notificationAreaIconBuilder();
}
}
else

View File

@@ -1,16 +1,18 @@
using System;
using mRemoteNG.Config;
using mRemoteNG.Tools;
namespace mRemoteNG.UI.Forms.OptionsPages
{
public sealed partial class ConnectionsPage
{
private readonly FrmMain _frmMain = FrmMain.Default;
private readonly FrmMain _frmMain;
public ConnectionsPage()
public ConnectionsPage(FrmMain frmMain)
{
InitializeComponent();
ApplyTheme();
base.ApplyTheme();
_frmMain = frmMain.ThrowIfNull(nameof(frmMain));
}
public override string PageName
@@ -112,4 +114,4 @@ namespace mRemoteNG.UI.Forms.OptionsPages
Settings.Default.Save();
}
}
}
}

View File

@@ -1,13 +1,16 @@
using System;
using mRemoteNG.App;
using mRemoteNG.Connection;
using mRemoteNG.Security.SymmetricEncryption;
namespace mRemoteNG.UI.Forms.OptionsPages
{
public sealed partial class CredentialsPage : OptionsPage
{
public CredentialsPage()
{
private readonly IConnectionsService _connectionsService;
public CredentialsPage(IConnectionsService connectionsService)
{
_connectionsService = connectionsService;
InitializeComponent();
ApplyTheme();
}
@@ -49,7 +52,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
txtCredentialsUsername.Text = Settings.Default.DefaultUsername;
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
txtCredentialsPassword.Text = cryptographyProvider.Decrypt(Settings.Default.DefaultPassword, Runtime.EncryptionKey);
txtCredentialsPassword.Text = cryptographyProvider.Decrypt(Settings.Default.DefaultPassword, _connectionsService.EncryptionKey);
txtCredentialsDomain.Text = Settings.Default.DefaultDomain;
}
@@ -70,7 +73,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
Settings.Default.DefaultUsername = txtCredentialsUsername.Text;
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
Settings.Default.DefaultPassword = cryptographyProvider.Encrypt(txtCredentialsPassword.Text, Runtime.EncryptionKey);
Settings.Default.DefaultPassword = cryptographyProvider.Encrypt(txtCredentialsPassword.Text, _connectionsService.EncryptionKey);
Settings.Default.DefaultDomain = txtCredentialsDomain.Text;
Settings.Default.Save();
@@ -86,4 +89,4 @@ namespace mRemoteNG.UI.Forms.OptionsPages
txtCredentialsDomain.Enabled = radCredentialsCustom.Checked;
}
}
}
}

View File

@@ -3,16 +3,22 @@ using mRemoteNG.App;
using mRemoteNG.Config.Connections;
using mRemoteNG.Config.Connections.Multiuser;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Connection;
using mRemoteNG.Security.SymmetricEncryption;
using mRemoteNG.Tools;
namespace mRemoteNG.UI.Forms.OptionsPages
{
public sealed partial class SqlServerPage
{
private readonly SqlDatabaseConnectionTester _databaseConnectionTester;
private readonly IConnectionsService _connectionsService;
private readonly DatabaseConnectorFactory _databaseConnectorFactory;
public SqlServerPage()
public SqlServerPage(IConnectionsService connectionsService, DatabaseConnectorFactory databaseConnectorFactory)
{
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
_databaseConnectorFactory = databaseConnectorFactory.ThrowIfNull(nameof(databaseConnectorFactory));
InitializeComponent();
ApplyTheme();
_databaseConnectionTester = new SqlDatabaseConnectionTester();
@@ -49,7 +55,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
txtSQLDatabaseName.Text = Settings.Default.SQLDatabaseName;
txtSQLUsername.Text = Settings.Default.SQLUser;
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
txtSQLPassword.Text = cryptographyProvider.Decrypt(Settings.Default.SQLPass, Runtime.EncryptionKey);
txtSQLPassword.Text = cryptographyProvider.Decrypt(Settings.Default.SQLPass, _connectionsService.EncryptionKey);
chkSQLReadOnly.Checked = Settings.Default.SQLReadOnly;
lblTestConnectionResults.Text = "";
}
@@ -64,7 +70,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
Settings.Default.SQLDatabaseName = txtSQLDatabaseName.Text;
Settings.Default.SQLUser = txtSQLUsername.Text;
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
Settings.Default.SQLPass = cryptographyProvider.Encrypt(txtSQLPassword.Text, Runtime.EncryptionKey);
Settings.Default.SQLPass = cryptographyProvider.Encrypt(txtSQLPassword.Text, _connectionsService.EncryptionKey);
Settings.Default.SQLReadOnly = chkSQLReadOnly.Checked;
if (Settings.Default.UseSQLServer)
@@ -75,18 +81,19 @@ namespace mRemoteNG.UI.Forms.OptionsPages
Settings.Default.Save();
}
private static void ReinitializeSqlUpdater()
private void ReinitializeSqlUpdater()
{
Runtime.ConnectionsService.RemoteConnectionsSyncronizer?.Dispose();
Runtime.ConnectionsService.RemoteConnectionsSyncronizer = new RemoteConnectionsSyncronizer(new SqlConnectionsUpdateChecker());
Runtime.ConnectionsService.RemoteConnectionsSyncronizer.Enable();
_connectionsService.RemoteConnectionsSyncronizer?.Dispose();
var sqlConnectionsUpdateChecker = new SqlConnectionsUpdateChecker(_connectionsService, _databaseConnectorFactory);
_connectionsService.RemoteConnectionsSyncronizer = new RemoteConnectionsSyncronizer(sqlConnectionsUpdateChecker, _connectionsService);
_connectionsService.RemoteConnectionsSyncronizer.Enable();
}
private void DisableSql()
{
Runtime.ConnectionsService.RemoteConnectionsSyncronizer?.Dispose();
Runtime.ConnectionsService.RemoteConnectionsSyncronizer = null;
Runtime.LoadConnections(true);
_connectionsService.RemoteConnectionsSyncronizer?.Dispose();
_connectionsService.RemoteConnectionsSyncronizer = null;
_connectionsService.LoadConnections(true);
}
private void chkUseSQLServer_CheckedChanged(object sender, EventArgs e)

View File

@@ -1,11 +1,16 @@
using mRemoteNG.Tools;
namespace mRemoteNG.UI.Forms.OptionsPages
{
public sealed partial class TabsPanelsPage
{
public TabsPanelsPage()
private readonly FrmMain _frmMain;
public TabsPanelsPage(FrmMain frmMain)
{
InitializeComponent();
ApplyTheme();
_frmMain = frmMain.ThrowIfNull(nameof(frmMain));
base.ApplyTheme();
}
public override string PageName
@@ -50,7 +55,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
base.SaveSettings();
Settings.Default.AlwaysShowPanelTabs = chkAlwaysShowPanelTabs.Checked;
FrmMain.Default.ShowHidePanelTabs();
_frmMain.ShowHidePanelTabs();
Settings.Default.OpenTabsRightOfSelected = chkOpenNewTabRightOfSelected.Checked;
Settings.Default.ShowLogonInfoOnTabs = chkShowLogonInfoOnTabs.Checked;
@@ -74,4 +79,4 @@ namespace mRemoteNG.UI.Forms.OptionsPages
UpdatePanelNameTextBox();
}
}
}
}

View File

@@ -4,6 +4,7 @@ using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.App.Info;
using mRemoteNG.App.Update;
using mRemoteNG.Connection;
using mRemoteNG.Security.SymmetricEncryption;
using mRemoteNG.Tools;
using mRemoteNG.UI.TaskDialog;
@@ -12,16 +13,17 @@ namespace mRemoteNG.UI.Forms.OptionsPages
{
public sealed partial class UpdatesPage
{
#region Private Fields
private readonly AppUpdater _appUpdate;
private readonly Action<WindowType> _showWindowAction;
private readonly IConnectionsService _connectionsService;
private AppUpdater _appUpdate;
#endregion
public UpdatesPage()
public UpdatesPage(AppUpdater appUpdate, Action<WindowType> showWindowAction, IConnectionsService connectionsService)
{
InitializeComponent();
ApplyTheme();
_appUpdate = appUpdate;
_showWindowAction = showWindowAction.ThrowIfNull(nameof(showWindowAction));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
InitializeComponent();
base.ApplyTheme();
}
#region Public Methods
@@ -114,7 +116,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
pnlProxyAuthentication.Enabled = Settings.Default.UpdateProxyUseAuthentication;
txtProxyUsername.Text = Settings.Default.UpdateProxyAuthUser;
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
txtProxyPassword.Text = cryptographyProvider.Decrypt(Settings.Default.UpdateProxyAuthPass, Runtime.EncryptionKey);
txtProxyPassword.Text = cryptographyProvider.Decrypt(Settings.Default.UpdateProxyAuthPass, _connectionsService.EncryptionKey);
btnTestProxy.Enabled = Settings.Default.UpdateUseProxy;
}
@@ -146,7 +148,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
Settings.Default.UpdateProxyUseAuthentication = chkUseProxyAuthentication.Checked;
Settings.Default.UpdateProxyAuthUser = txtProxyUsername.Text;
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
Settings.Default.UpdateProxyAuthPass = cryptographyProvider.Encrypt(txtProxyPassword.Text, Runtime.EncryptionKey);
Settings.Default.UpdateProxyAuthPass = cryptographyProvider.Encrypt(txtProxyPassword.Text, _connectionsService.EncryptionKey);
Settings.Default.Save();
}
@@ -164,7 +166,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
private void btnUpdateCheckNow_Click(object sender, EventArgs e)
{
Windows.Show(WindowType.Update);
_showWindowAction(WindowType.Update);
}
private void chkUseProxyForAutomaticUpdates_CheckedChanged(object sender, EventArgs e)
@@ -190,15 +192,11 @@ namespace mRemoteNG.UI.Forms.OptionsPages
private void btnTestProxy_Click(object sender, EventArgs e)
{
if (_appUpdate != null)
if (_appUpdate.IsGetUpdateInfoRunning)
{
if (_appUpdate.IsGetUpdateInfoRunning)
{
return;
}
return;
}
_appUpdate = new AppUpdater();
//_appUpdate.Load += _appUpdate.Update_Load;
_appUpdate.SetProxySettings(chkUseProxyForAutomaticUpdates.Checked, txtProxyAddress.Text,
(int) numProxyPort.Value, chkUseProxyAuthentication.Checked, txtProxyUsername.Text,
@@ -259,4 +257,4 @@ namespace mRemoteNG.UI.Forms.OptionsPages
#endregion
}
}
}

View File

@@ -1,5 +1,5 @@
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.Tools;
using mRemoteNG.UI.Forms.Input;
using mRemoteNG.UI.Panels;
@@ -8,11 +8,13 @@ namespace mRemoteNG.UI.Forms
public partial class frmChoosePanel
{
private readonly PanelAdder _panelAdder;
private readonly WindowList _windowList;
public frmChoosePanel()
public frmChoosePanel(PanelAdder panelAdder, WindowList windowList)
{
InitializeComponent();
_panelAdder = new PanelAdder();
_panelAdder = panelAdder.ThrowIfNull(nameof(panelAdder));
_windowList = windowList.ThrowIfNull(nameof(windowList));
InitializeComponent();
}
public string Panel
{
@@ -48,9 +50,9 @@ namespace mRemoteNG.UI.Forms
{
cbPanels.Items.Clear();
for (var i = 0; i <= Runtime.WindowList.Count - 1; i++)
for (int i = 0; i <= _windowList.Count - 1; i++)
{
cbPanels.Items.Add(Runtime.WindowList[i].Text.Replace("&&", "&"));
cbPanels.Items.Add(_windowList[i].Text.Replace("&&", "&"));
}
if (cbPanels.Items.Count > 0)

View File

@@ -27,7 +27,6 @@ namespace mRemoteNG.UI.Forms
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
mRemoteNG.Connection.ConnectionInitiator connectionInitiator1 = new mRemoteNG.Connection.ConnectionInitiator();
this.pnlDock = new WeifenLuo.WinFormsUI.Docking.DockPanel();
this.msMain = new System.Windows.Forms.MenuStrip();
this.fileMenu = new mRemoteNG.UI.Menu.MainFileMenu();
@@ -144,7 +143,7 @@ namespace mRemoteNG.UI.Forms
// _quickConnectToolStrip
//
this._quickConnectToolStrip.BackColor = System.Drawing.SystemColors.Control;
this._quickConnectToolStrip.ConnectionInitiator = connectionInitiator1;
this._quickConnectToolStrip.ConnectionInitiator = null;
this._quickConnectToolStrip.Dock = System.Windows.Forms.DockStyle.None;
this._quickConnectToolStrip.ForeColor = System.Drawing.SystemColors.ControlText;
this._quickConnectToolStrip.Location = new System.Drawing.Point(3, 0);

View File

@@ -1,3 +1,28 @@
using Microsoft.Win32;
using mRemoteNG.App;
using mRemoteNG.App.Info;
using mRemoteNG.App.Initialization;
using mRemoteNG.App.Update;
using mRemoteNG.Config;
using mRemoteNG.Config.Connections;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Putty;
using mRemoteNG.Config.Settings;
using mRemoteNG.Connection;
using mRemoteNG.Connection.Protocol;
using mRemoteNG.Credential;
using mRemoteNG.Credential.Repositories;
using mRemoteNG.Messages;
using mRemoteNG.Messages.MessageWriters;
using mRemoteNG.Themes;
using mRemoteNG.Tools;
using mRemoteNG.UI.Controls;
using mRemoteNG.UI.Controls.Adapters;
using mRemoteNG.UI.Menu;
using mRemoteNG.UI.Panels;
using mRemoteNG.UI.TaskDialog;
using mRemoteNG.UI.Window;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@@ -6,26 +31,9 @@ using System.Drawing;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;
using mRemoteNG.App;
using mRemoteNG.App.Info;
using mRemoteNG.App.Initialization;
using mRemoteNG.Config;
using mRemoteNG.Config.Connections;
using mRemoteNG.Config.DataProviders;
using mRemoteNG.Config.Putty;
using mRemoteNG.Config.Settings;
using mRemoteNG.Connection;
using mRemoteNG.Messages;
using mRemoteNG.Messages.MessageWriters;
using mRemoteNG.Themes;
using mRemoteNG.Tools;
using mRemoteNG.UI.Menu;
using mRemoteNG.UI.Panels;
using mRemoteNG.UI.TaskDialog;
using mRemoteNG.UI.Window;
using WeifenLuo.WinFormsUI.Docking;
// ReSharper disable MemberCanBePrivate.Global
@@ -34,8 +42,6 @@ namespace mRemoteNG.UI.Forms
{
public partial class FrmMain
{
public static FrmMain Default { get; } = new FrmMain();
private static ClipboardchangeEventHandler _clipboardChangedEvent;
private bool _inSizeMove;
private bool _inMouseActivate;
@@ -47,17 +53,96 @@ namespace mRemoteNG.UI.Forms
private ConnectionInfo _selectedConnection;
private readonly IList<IMessageWriter> _messageWriters = new List<IMessageWriter>();
private readonly ThemeManager _themeManager;
private readonly FileBackupPruner _backupPruner = new FileBackupPruner();
private readonly ConnectionInitiator _connectionInitiator;
private readonly PanelAdder _panelAdder;
private readonly WebHelper _webHelper;
private readonly WindowList _windowList;
private readonly Windows _windows;
private readonly Startup _startup;
private readonly Export _export;
private readonly SettingsLoader _settingsLoader;
private readonly SettingsSaver _settingsSaver;
private readonly Shutdown _shutdown;
private readonly ICredentialRepositoryList _credentialRepositoryList;
private readonly Func<NotificationAreaIcon> _notificationAreaIconBuilder;
private readonly IConnectionsService _connectionsService;
private readonly Import _import;
private readonly AppUpdater _appUpdater;
private readonly DatabaseConnectorFactory _databaseConnectorFactory;
private readonly Screens _screens;
private readonly FileBackupPruner _backupPruner;
private readonly MessageCollector _messageCollector = Runtime.MessageCollector;
private SaveConnectionsOnEdit _saveConnectionsOnEdit;
internal FullscreenHandler Fullscreen { get; set; }
//Added theming support
private readonly ToolStripRenderer _toolStripProfessionalRenderer = new ToolStripProfessionalRenderer();
private FrmMain()
public FrmMain()
{
_showFullPathInTitle = Settings.Default.ShowCompleteConsPathInTitle;
InitializeComponent();
InitializeComponent();
_windowList = new WindowList();
_credentialRepositoryList = new CredentialRepositoryList();
var externalToolsService = new ExternalToolsService();
_import = new Import(this);
_connectionsService = new ConnectionsService(PuttySessionsManager.Instance, _import, this);
_backupPruner = new FileBackupPruner();
_import.ConnectionsService = _connectionsService;
Func<SecureString> encryptionKeySelectionFunc = () => _connectionsService.EncryptionKey;
_appUpdater = new AppUpdater(encryptionKeySelectionFunc);
ExternalToolsTypeConverter.ExternalToolsService = externalToolsService;
_export = new Export(_credentialRepositoryList, _connectionsService, this);
var protocolFactory = new ProtocolFactory(externalToolsService, this, _connectionsService);
_connectionInitiator = new ConnectionInitiator(_windowList, externalToolsService, protocolFactory, this);
_webHelper = new WebHelper(_connectionInitiator);
var configWindow = new ConfigWindow(new DockContent(), _connectionsService);
var sshTransferWindow = new SSHTransferWindow(pnlDock);
var connectionTreeWindow = new ConnectionTreeWindow(new DockContent(), _connectionInitiator, _connectionsService);
var connectionTree = connectionTreeWindow.ConnectionTree;
connectionTree.SelectedNodeChanged += configWindow.HandleConnectionTreeSelectionChanged;
var connectionTreeContextMenu = new ConnectionContextMenu(connectionTree, _connectionInitiator,
sshTransferWindow, _export, externalToolsService, _import, _connectionsService);
connectionTree.ConnectionContextMenu = connectionTreeContextMenu;
connectionTreeWindow.ConnectionTreeContextMenu = connectionTreeContextMenu;
var errorAndInfoWindow = new ErrorAndInfoWindow(new DockContent(), pnlDock, connectionTreeWindow);
var screenshotManagerWindow = new ScreenshotManagerWindow(new DockContent(), pnlDock);
_settingsSaver = new SettingsSaver(externalToolsService);
_shutdown = new Shutdown(_settingsSaver, _connectionsService, this);
Func<UpdateWindow> updateWindowBuilder = () => new UpdateWindow(new DockContent(), _shutdown, _appUpdater);
_notificationAreaIconBuilder = () => new NotificationAreaIcon(this, _connectionInitiator, _shutdown, _connectionsService);
Func<ExternalToolsWindow> externalToolsWindowBuilder = () =>
new ExternalToolsWindow(_connectionInitiator, externalToolsService, () => connectionTree.SelectedNode, this, _connectionsService);
Func<PortScanWindow> portScanWindowBuilder = () => new PortScanWindow(connectionTreeWindow, _import);
Func<ActiveDirectoryImportWindow> activeDirectoryImportWindowBuilder = () =>
new ActiveDirectoryImportWindow(() => connectionTreeWindow.SelectedNode, _import, _connectionsService);
_databaseConnectorFactory = new DatabaseConnectorFactory(encryptionKeySelectionFunc);
_windows = new Windows(_connectionInitiator, connectionTreeWindow, configWindow, errorAndInfoWindow, screenshotManagerWindow,
sshTransferWindow, updateWindowBuilder, _notificationAreaIconBuilder, externalToolsWindowBuilder, _connectionsService,
portScanWindowBuilder, activeDirectoryImportWindowBuilder, _appUpdater, _databaseConnectorFactory, this);
Func<ConnectionWindow> connectionWindowBuilder = () =>
new ConnectionWindow(new DockContent(), _connectionInitiator, _windows, externalToolsService, this);
_screens = new Screens(this);
_panelAdder = new PanelAdder(_windowList, connectionWindowBuilder, _screens, pnlDock);
_showFullPathInTitle = Settings.Default.ShowCompleteConsPathInTitle;
_connectionInitiator.Adder = _panelAdder;
_connectionsService.DatabaseConnectorFactory = _databaseConnectorFactory;
var compatibilityChecker = new CompatibilityChecker(_messageCollector, this);
_startup = new Startup(this, _windows, _connectionsService, _appUpdater, _databaseConnectorFactory, compatibilityChecker);
connectionTreeContextMenu.ShowWindowAction = _windows.Show;
var externalAppsLoader = new ExternalAppsLoader(Runtime.MessageCollector, _externalToolsToolStrip,
_connectionInitiator, externalToolsService, _connectionsService);
_settingsLoader = new SettingsLoader(this, Runtime.MessageCollector, _quickConnectToolStrip, _externalToolsToolStrip,
_multiSshToolStrip, externalAppsLoader, _notificationAreaIconBuilder, msMain);
_externalToolsToolStrip.ExternalToolsService = externalToolsService;
_externalToolsToolStrip.GetSelectedConnectionFunc = () => SelectedConnection;
_quickConnectToolStrip.ConnectionInitiator = _connectionInitiator;
_quickConnectToolStrip.ConnectionsService = _connectionsService;
CredentialRecordTypeConverter.CredentialRepositoryList = _credentialRepositoryList;
CredentialRecordListAdaptor.CredentialRepositoryList = _credentialRepositoryList;
Fullscreen = new FullscreenHandler(this);
//Theming support
@@ -133,19 +218,17 @@ namespace mRemoteNG.UI.Forms
#region Startup & Shutdown
private void frmMain_Load(object sender, EventArgs e)
{
var messageCollector = Runtime.MessageCollector;
MessageCollectorSetup.SetupMessageCollector(messageCollector, _messageWriters);
MessageCollectorSetup.BuildMessageWritersFromSettings(_messageWriters);
MessageCollectorSetup.SetupMessageCollector(_messageCollector, _messageWriters);
MessageCollectorSetup.BuildMessageWritersFromSettings(_messageWriters, this, _windows.ErrorsForm);
Startup.Instance.InitializeProgram(messageCollector);
msMain.Location = Point.Empty;
var settingsLoader = new SettingsLoader(this, messageCollector, _quickConnectToolStrip, _externalToolsToolStrip, _multiSshToolStrip, msMain);
settingsLoader.LoadSettings();
_startup.InitializeProgram(_messageCollector);
SetMenuDependencies();
var uiLoader = new DockPanelLayoutLoader(this, messageCollector);
msMain.Location = Point.Empty;
_settingsLoader.LoadSettings();
var uiLoader = new DockPanelLayoutLoader(this, _messageCollector, _windows);
uiLoader.LoadPanelsFromXml();
LockToolbarPositions(Settings.Default.LockToolbars);
@@ -155,23 +238,23 @@ namespace mRemoteNG.UI.Forms
_fpChainedWindowHandle = NativeMethods.SetClipboardViewer(Handle);
Runtime.WindowList = new WindowList();
if (Settings.Default.ResetPanels)
SetDefaultLayout();
Runtime.ConnectionsService.ConnectionsLoaded += ConnectionsServiceOnConnectionsLoaded;
Runtime.ConnectionsService.ConnectionsSaved += ConnectionsServiceOnConnectionsSaved;
var credsAndConsSetup = new CredsAndConsSetup();
_connectionsService.ConnectionsLoaded += ConnectionsServiceOnConnectionsLoaded;
_connectionsService.ConnectionsSaved += ConnectionsServiceOnConnectionsSaved;
_saveConnectionsOnEdit = new SaveConnectionsOnEdit(_connectionsService);
var credsAndConsSetup = new CredsAndConsSetup(_connectionsService);
credsAndConsSetup.LoadCredsAndCons();
Windows.TreeForm.Focus();
_windows.TreeForm.Focus();
PuttySessionsManager.Instance.StartWatcher();
if (Settings.Default.StartupComponentsCheck)
Windows.Show(WindowType.ComponentsCheck);
_windows.Show(WindowType.ComponentsCheck);
Startup.Instance.CreateConnectionsProvider(messageCollector);
_startup.CreateConnectionsProvider(_messageCollector);
_screenSystemMenu.BuildScreenList();
SystemEvents.DisplaySettingsChanged += _screenSystemMenu.OnDisplayChanged;
@@ -185,9 +268,8 @@ namespace mRemoteNG.UI.Forms
? Settings.Default.StartUpPanelName
: Language.strNewPanel;
var panelAdder = new PanelAdder();
if (!panelAdder.DoesPanelExist(panelName))
panelAdder.AddPanel(panelName);
if (!_panelAdder.DoesPanelExist(panelName))
_panelAdder.AddPanel(panelName);
}
}
@@ -233,20 +315,31 @@ namespace mRemoteNG.UI.Forms
private void SetMenuDependencies()
{
var connectionInitiator = new ConnectionInitiator();
fileMenu.TreeWindow = Windows.TreeForm;
fileMenu.ConnectionInitiator = connectionInitiator;
fileMenu.TreeWindow = _windows.TreeForm;
fileMenu.ConnectionInitiator = _connectionInitiator;
fileMenu.WindowList = _windowList;
fileMenu.Windows = _windows;
fileMenu.Export = _export;
fileMenu.Shutdown = _shutdown;
fileMenu.Import = _import;
fileMenu.ConnectionsService = _connectionsService;
fileMenu.DialogWindowParent = this;
viewMenu.TsExternalTools = _externalToolsToolStrip;
viewMenu.TsQuickConnect = _quickConnectToolStrip;
viewMenu.TsMultiSsh = _multiSshToolStrip;
viewMenu.TsMultiSsh = _multiSshToolStrip;
viewMenu.FullscreenHandler = Fullscreen;
viewMenu.Adder = _panelAdder;
viewMenu.WindowList = _windowList;
viewMenu.Windows = _windows;
viewMenu.MainForm = this;
toolsMenu.MainForm = this;
toolsMenu.CredentialProviderCatalog = Runtime.CredentialProviderCatalog;
toolsMenu.CredentialProviderCatalog = _credentialRepositoryList;
toolsMenu.Windows = _windows;
_quickConnectToolStrip.ConnectionInitiator = connectionInitiator;
helpMenu.WebHelper = _webHelper;
helpMenu.Windows = _windows;
}
//Theming support
@@ -308,7 +401,7 @@ namespace mRemoteNG.UI.Forms
if (CTaskDialog.CommandButtonResult != 1) return;
using (var optionsForm = new frmOptions(Language.strTabUpdates))
using (var optionsForm = new frmOptions(_connectionInitiator, _windows.Show, _notificationAreaIconBuilder, _connectionsService, _appUpdater, _databaseConnectorFactory, Language.strTabUpdates, this))
{
optionsForm.ShowDialog(this);
}
@@ -325,15 +418,15 @@ namespace mRemoteNG.UI.Forms
if (!Settings.Default.UpdatePending && DateTime.UtcNow <= nextUpdateCheck) return;
if (!IsHandleCreated) CreateHandle(); // Make sure the handle is created so that InvokeRequired returns the correct result
Startup.Instance.CheckForUpdate();
_startup.CheckForUpdate();
}
private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
{
if (!(Runtime.WindowList == null || Runtime.WindowList.Count == 0))
if (!(_windowList == null || _windowList.Count == 0))
{
var openConnections = 0;
foreach (BaseWindow window in Runtime.WindowList)
foreach (BaseWindow window in _windowList)
{
var connectionWindow = window as ConnectionWindow;
if (connectionWindow != null)
@@ -355,19 +448,20 @@ namespace mRemoteNG.UI.Forms
}
}
Shutdown.Cleanup(_quickConnectToolStrip, _externalToolsToolStrip, _multiSshToolStrip, this);
_shutdown.Cleanup(_quickConnectToolStrip, _externalToolsToolStrip, _multiSshToolStrip, this);
IsClosing = true;
_saveConnectionsOnEdit.Enabled = false;
if (Runtime.WindowList != null)
if (_windowList != null)
{
foreach (BaseWindow window in Runtime.WindowList)
foreach (BaseWindow window in _windowList)
{
window.Close();
}
}
Shutdown.StartUpdate();
_shutdown.StartUpdate();
Debug.Print("[END] - " + Convert.ToString(DateTime.Now, CultureInfo.InvariantCulture));
}
@@ -377,7 +471,7 @@ namespace mRemoteNG.UI.Forms
private void tmrAutoSave_Tick(object sender, EventArgs e)
{
Runtime.MessageCollector.AddMessage(MessageClass.DebugMsg, "Doing AutoSave");
Runtime.ConnectionsService.SaveConnectionsAsync();
_connectionsService.SaveConnectionsAsync();
}
#endregion
@@ -394,7 +488,7 @@ namespace mRemoteNG.UI.Forms
if (!Settings.Default.MinimizeToTray) return;
if (Runtime.NotificationAreaIcon == null)
{
Runtime.NotificationAreaIcon = new NotificationAreaIcon();
Runtime.NotificationAreaIcon = new NotificationAreaIcon(this, _connectionInitiator, _shutdown, _connectionsService);
}
Hide();
}
@@ -468,7 +562,7 @@ namespace mRemoteNG.UI.Forms
case NativeMethods.WM_SYSCOMMAND:
var screen = _screenSystemMenu.GetScreenById(m.WParam.ToInt32());
if (screen != null)
Screens.SendFormToScreen(screen);
_screens.SendFormToScreen(screen);
break;
case NativeMethods.WM_DRAWCLIPBOARD:
NativeMethods.SendMessage(_fpChainedWindowHandle, m.Msg, m.LParam, m.WParam);
@@ -530,21 +624,21 @@ namespace mRemoteNG.UI.Forms
var titleBuilder = new StringBuilder(Application.ProductName);
const string separator = " - ";
if (Runtime.ConnectionsService.IsConnectionsFileLoaded)
if (_connectionsService.IsConnectionsFileLoaded)
{
if (Runtime.ConnectionsService.UsingDatabase)
if (_connectionsService.UsingDatabase)
{
titleBuilder.Append(separator);
titleBuilder.Append(Language.strSQLServer.TrimEnd(':'));
}
else
{
if (!string.IsNullOrEmpty(Runtime.ConnectionsService.ConnectionFileName))
if (!string.IsNullOrEmpty(_connectionsService.ConnectionFileName))
{
titleBuilder.Append(separator);
titleBuilder.Append(Settings.Default.ShowCompleteConsPathInTitle
? Runtime.ConnectionsService.ConnectionFileName
: Path.GetFileName(Runtime.ConnectionsService.ConnectionFileName));
? _connectionsService.ConnectionFileName
: Path.GetFileName(_connectionsService.ConnectionFileName));
}
}
}
@@ -625,11 +719,11 @@ namespace mRemoteNG.UI.Forms
pnlDock.DockTopPortion = pnlDock.Height * 0.25;
pnlDock.DockBottomPortion = pnlDock.Height * 0.25;
Windows.TreeForm.Show(pnlDock, DockState.DockLeft);
Windows.ConfigForm.Show(pnlDock);
Windows.ConfigForm.DockTo(Windows.TreeForm.Pane, DockStyle.Bottom, -1);
Windows.ErrorsForm.Show( pnlDock, DockState.DockBottomAutoHide );
Windows.ScreenshotForm.Hide();
_windows.TreeForm.Show(pnlDock, DockState.DockLeft);
_windows.ConfigForm.Show(pnlDock);
_windows.ConfigForm.DockTo(_windows.TreeForm.Pane, DockStyle.Bottom, -1);
_windows.ErrorsForm.Show( pnlDock, DockState.DockBottomAutoHide );
_windows.ScreenshotForm.Hide();
pnlDock.Visible = true;
}
@@ -654,4 +748,4 @@ namespace mRemoteNG.UI.Forms
fileMenu.mMenFile_DropDownOpening(sender, e);
}
}
}
}

View File

@@ -1,28 +1,47 @@
using mRemoteNG.UI.Forms.OptionsPages;
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;
using mRemoteNG.App.Update;
using mRemoteNG.Config.DatabaseConnectors;
using mRemoteNG.Connection;
using mRemoteNG.Tools;
using mRemoteNG.UI.Forms.OptionsPages;
namespace mRemoteNG.UI.Forms
{
public partial class frmOptions : Form
public partial class frmOptions : Form
{
private Dictionary<string, OptionsPage> _pages;
private ImageList _pageIconImageList;
private readonly string _pageName;
private readonly IConnectionInitiator _connectionInitiator;
private readonly Action<WindowType> _showWindowAction;
private readonly Func<NotificationAreaIcon> _notificationAreaIconBuilder;
private readonly IConnectionsService _connectionsService;
private readonly AppUpdater _appUpdater;
private readonly DatabaseConnectorFactory _databaseConnectorFactory;
private readonly FrmMain _frmMain;
public frmOptions()
public frmOptions(IConnectionInitiator connectionInitiator, Action<WindowType> showWindowAction, Func<NotificationAreaIcon> notificationAreaIconBuilder,
IConnectionsService connectionsService, AppUpdater appUpdater, DatabaseConnectorFactory databaseConnectorFactory, FrmMain frmMain)
: this(connectionInitiator, showWindowAction, notificationAreaIconBuilder, connectionsService, appUpdater, databaseConnectorFactory, Language.strStartupExit, frmMain)
{
InitializeComponent();
_pageName = Language.strStartupExit;
}
public frmOptions(string pn)
public frmOptions(IConnectionInitiator connectionInitiator, Action<WindowType> showWindowAction, Func<NotificationAreaIcon> notificationAreaIconBuilder,
IConnectionsService connectionsService, AppUpdater appUpdater, DatabaseConnectorFactory databaseConnectorFactory, string pageName, FrmMain frmMain)
{
InitializeComponent();
_pageName = pn;
_connectionInitiator = connectionInitiator.ThrowIfNull(nameof(connectionInitiator));
_showWindowAction = showWindowAction.ThrowIfNull(nameof(showWindowAction));
_notificationAreaIconBuilder = notificationAreaIconBuilder;
_frmMain = frmMain.ThrowIfNull(nameof(frmMain));
_databaseConnectorFactory = databaseConnectorFactory.ThrowIfNull(nameof(databaseConnectorFactory));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
_appUpdater = appUpdater.ThrowIfNull(nameof(appUpdater));
_pageName = pageName.ThrowIfNull(nameof(pageName));
InitializeComponent();
}
private void frmOptions_Load(object sender, EventArgs e)
@@ -38,6 +57,7 @@ namespace mRemoteNG.UI.Forms
lstOptionPages.SelectedIndexChanged += LstOptionPages_SelectedIndexChanged;
lstOptionPages.SelectedIndex = 0;
}
private void ApplyTheme()
{
if (!Themes.ThemeManager.getInstance().ThemingActive) return;
@@ -59,13 +79,13 @@ namespace mRemoteNG.UI.Forms
_pages = new Dictionary<string, OptionsPage>
{
{typeof(StartupExitPage).Name, new StartupExitPage()},
{typeof(AppearancePage).Name, new AppearancePage()},
{typeof(TabsPanelsPage).Name, new TabsPanelsPage()},
{typeof(AppearancePage).Name, new AppearancePage(_connectionInitiator, _notificationAreaIconBuilder, _frmMain)},
{typeof(TabsPanelsPage).Name, new TabsPanelsPage(_frmMain)},
{typeof(NotificationsPage).Name, new NotificationsPage()},
{typeof(ConnectionsPage).Name, new ConnectionsPage()},
{typeof(CredentialsPage).Name, new CredentialsPage()},
{typeof(SqlServerPage).Name, new SqlServerPage()},
{typeof(UpdatesPage).Name, new UpdatesPage()},
{typeof(ConnectionsPage).Name, new ConnectionsPage(_frmMain)},
{typeof(CredentialsPage).Name, new CredentialsPage(_connectionsService)},
{typeof(SqlServerPage).Name, new SqlServerPage(_connectionsService, _databaseConnectorFactory)},
{typeof(UpdatesPage).Name, new UpdatesPage(_appUpdater, _showWindowAction, _connectionsService)},
{typeof(ThemePage).Name, new ThemePage()},
{typeof(SecurityPage).Name, new SecurityPage()},
{typeof(AdvancedPage).Name, new AdvancedPage()}

View File

@@ -6,7 +6,7 @@ using mRemoteNG.Connection;
namespace mRemoteNG.UI.Menu
{
public class HelpMenu : ToolStripMenuItem
public class HelpMenu : ToolStripMenuItem
{
private ToolStripMenuItem _mMenInfoHelp;
private ToolStripMenuItem _mMenInfoWebsite;
@@ -19,7 +19,10 @@ namespace mRemoteNG.UI.Menu
private ToolStripSeparator _toolStripSeparator2;
private ToolStripMenuItem _mMenInfoForum;
public HelpMenu()
public Windows Windows { get; set; }
public WebHelper WebHelper { get; set; }
public HelpMenu()
{
Initialize();
}

View File

@@ -7,7 +7,6 @@ using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Security;
using mRemoteNG.Tree;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.Window;
namespace mRemoteNG.UI.Menu
@@ -36,8 +35,15 @@ namespace mRemoteNG.UI.Menu
private ToolStripMenuItem _mMenFileImport;
private ToolStripMenuItem _mMenReconnectAll;
public ConnectionTreeWindow TreeWindow { get; set; }
public WindowList WindowList { get; set; }
public Windows Windows { get; set; }
public ConnectionTreeWindow TreeWindow { get; set; }
public IConnectionInitiator ConnectionInitiator { get; set; }
public Export Export { get; set; }
public Shutdown Shutdown { get; set; }
public Import Import { get; set; }
public IConnectionsService ConnectionsService { get; set; }
public IWin32Window DialogWindowParent { get; set; }
public MainFileMenu()
{
@@ -374,46 +380,46 @@ namespace mRemoteNG.UI.Menu
return;
}
Runtime.ConnectionsService.NewConnectionsFile(saveFileDialog.FileName);
ConnectionsService.NewConnectionsFile(saveFileDialog.FileName);
}
}
private void mMenFileLoad_Click(object sender, EventArgs e)
{
if (Runtime.ConnectionsService.IsConnectionsFileLoaded)
if (ConnectionsService.IsConnectionsFileLoaded)
{
var msgBoxResult = MessageBox.Show(Language.strSaveConnectionsFileBeforeOpeningAnother, Language.strSave, MessageBoxButtons.YesNoCancel);
// ReSharper disable once SwitchStatementMissingSomeCases
switch (msgBoxResult)
{
case DialogResult.Yes:
Runtime.ConnectionsService.SaveConnections();
ConnectionsService.SaveConnections();
break;
case DialogResult.Cancel:
return;
}
}
Runtime.LoadConnections(true);
ConnectionsService.LoadConnections(true);
}
private void mMenFileSave_Click(object sender, EventArgs e)
{
Runtime.ConnectionsService.SaveConnectionsAsync();
ConnectionsService.SaveConnectionsAsync();
}
private void mMenFileSaveAs_Click(object sender, EventArgs e)
{
using (var saveFileDialog = DialogFactory.ConnectionsSaveAsDialog())
{
if (saveFileDialog.ShowDialog(FrmMain.Default) != DialogResult.OK)
if (saveFileDialog.ShowDialog(DialogWindowParent) != DialogResult.OK)
return;
var newFileName = saveFileDialog.FileName;
Runtime.ConnectionsService.SaveConnections(Runtime.ConnectionsService.ConnectionTreeModel, false, new SaveFilter(), newFileName);
ConnectionsService.SaveConnections(ConnectionsService.ConnectionTreeModel, false, new SaveFilter(), newFileName);
if (newFileName == Runtime.ConnectionsService.GetDefaultStartupConnectionFileName())
if (newFileName == ConnectionsService.GetDefaultStartupConnectionFileName())
{
Settings.Default.LoadConsFromCustomLocation = false;
}
@@ -442,8 +448,9 @@ namespace mRemoteNG.UI.Menu
private void mMenReconnectAll_Click(object sender, EventArgs e)
{
if (Runtime.WindowList == null || Runtime.WindowList.Count == 0) return;
foreach (BaseWindow window in Runtime.WindowList)
if (WindowList.Count == 0)
return;
foreach (BaseWindow window in WindowList)
{
var connectionWindow = window as ConnectionWindow;
if (connectionWindow == null)
@@ -476,7 +483,7 @@ namespace mRemoteNG.UI.Menu
var selectedNode = TreeWindow.SelectedNode;
ContainerInfo importDestination;
if (selectedNode == null)
importDestination = Runtime.ConnectionsService.ConnectionTreeModel.RootNodes.First();
importDestination = ConnectionsService.ConnectionTreeModel.RootNodes.First();
else
importDestination = selectedNode as ContainerInfo ?? selectedNode.Parent;
Import.ImportFromFile(importDestination);
@@ -494,7 +501,7 @@ namespace mRemoteNG.UI.Menu
private void mMenFileExport_Click(object sender, EventArgs e)
{
Export.ExportToFile(Windows.TreeForm.SelectedNode, Runtime.ConnectionsService.ConnectionTreeModel);
Export.ExportToFile(Windows.TreeForm.SelectedNode, ConnectionsService.ConnectionTreeModel);
}
private void mMenFileExit_Click(object sender, EventArgs e)

View File

@@ -15,12 +15,13 @@ namespace mRemoteNG.UI.Menu
private ToolStripMenuItem _mMenToolsUvncsc;
private ToolStripMenuItem _mMenToolsComponentsCheck;
public Form MainForm { get; set; }
public Windows Windows { get; set; }
public Form MainForm { get; set; }
public ICredentialRepositoryList CredentialProviderCatalog { get; set; }
public ToolsMenu()
{
Initialize();
Initialize();
}
private void Initialize()
@@ -116,32 +117,32 @@ namespace mRemoteNG.UI.Menu
#region Tools
private void mMenToolsSSHTransfer_Click(object sender, EventArgs e)
{
Windows.Show(WindowType.SSHTransfer);
Windows.Show(WindowType.SSHTransfer);
}
private void mMenToolsUVNCSC_Click(object sender, EventArgs e)
{
Windows.Show(WindowType.UltraVNCSC);
Windows.Show(WindowType.UltraVNCSC);
}
private void mMenToolsExternalApps_Click(object sender, EventArgs e)
{
Windows.Show(WindowType.ExternalApps);
Windows.Show(WindowType.ExternalApps);
}
private void mMenToolsPortScan_Click(object sender, EventArgs e)
{
Windows.Show(WindowType.PortScan);
Windows.Show(WindowType.PortScan);
}
private void mMenToolsComponentsCheck_Click(object sender, EventArgs e)
{
Windows.Show(WindowType.ComponentsCheck);
Windows.Show(WindowType.ComponentsCheck);
}
private void mMenToolsOptions_Click(object sender, EventArgs e)
{
Windows.Show(WindowType.Options);
Windows.Show(WindowType.Options);
}
#endregion
}

View File

@@ -28,10 +28,11 @@ namespace mRemoteNG.UI.Menu
private ToolStripMenuItem _mMenViewResetLayout;
private ToolStripMenuItem _mMenViewLockToolbars;
private ToolStripSeparator _toolStripSeparator1;
private readonly PanelAdder _panelAdder;
public ToolStrip TsExternalTools { get; set; }
public PanelAdder Adder { get; set; }
public WindowList WindowList { get; set; }
public Windows Windows { get; set; }
public ToolStrip TsExternalTools { get; set; }
public ToolStrip TsQuickConnect { get; set; }
public ToolStrip TsMultiSsh { get; set; }
public FullscreenHandler FullscreenHandler { get; set; }
@@ -41,7 +42,7 @@ namespace mRemoteNG.UI.Menu
public ViewMenu()
{
Initialize();
_panelAdder = new PanelAdder();
ApplyLanguage();
}
private void Initialize()
@@ -283,11 +284,11 @@ namespace mRemoteNG.UI.Menu
_mMenViewConnectionPanels.DropDownItems.Clear();
for (var i = 0; i <= Runtime.WindowList.Count - 1; i++)
for (var i = 0; i <= WindowList.Count - 1; i++)
{
var tItem = new ToolStripMenuItem(Runtime.WindowList[i].Text,
Runtime.WindowList[i].Icon.ToBitmap(), ConnectionPanelMenuItem_Click)
{ Tag = Runtime.WindowList[i] };
var tItem = new ToolStripMenuItem(WindowList[i].Text,
WindowList[i].Icon.ToBitmap(), ConnectionPanelMenuItem_Click)
{ Tag = WindowList[i] };
_mMenViewConnectionPanels.DropDownItems.Add(tItem);
}
@@ -399,7 +400,7 @@ namespace mRemoteNG.UI.Menu
private void mMenViewAddConnectionPanel_Click(object sender, EventArgs e)
{
_panelAdder.AddPanel();
Adder.AddPanel();
}
private void mMenViewExtAppsToolbar_Click(object sender, EventArgs e)

View File

@@ -1,23 +1,36 @@
using System;
using mRemoteNG.App;
using mRemoteNG.Messages;
using mRemoteNG.Tools;
using mRemoteNG.UI.Forms.Input;
using mRemoteNG.UI.Window;
using System;
using System.Collections;
using System.Linq;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.Messages;
using mRemoteNG.UI.Forms;
using mRemoteNG.UI.Forms.Input;
using mRemoteNG.UI.Window;
using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNG.UI.Panels
{
public class PanelAdder
{
private readonly WindowList _windowList;
private readonly Screens _screens;
private readonly Func<ConnectionWindow> _connectionWindowBuilder;
private readonly DockPanel _dockPanel;
public PanelAdder(WindowList windowList, Func<ConnectionWindow> connectionWindowBuilder, Screens screens, DockPanel dockPanel)
{
_connectionWindowBuilder = connectionWindowBuilder;
_screens = screens.ThrowIfNull(nameof(screens));
_windowList = windowList.ThrowIfNull(nameof(windowList));
_dockPanel = dockPanel.ThrowIfNull(nameof(dockPanel));
}
public Form AddPanel(string title = "", bool noTabber = false)
{
try
{
var connectionForm = new ConnectionWindow(new DockContent());
var connectionForm = _connectionWindowBuilder();
BuildConnectionWindowContextMenu(connectionForm);
SetConnectionWindowTitle(title, connectionForm);
ShowConnectionWindow(connectionForm);
@@ -33,21 +46,22 @@ namespace mRemoteNG.UI.Panels
public bool DoesPanelExist(string panelName)
{
return Runtime.WindowList?.OfType<ConnectionWindow>().Any(w => w.TabText == panelName)
?? false;
return _windowList
.OfType<ConnectionWindow>()
.Any(w => w.TabText == panelName);
}
private static void ShowConnectionWindow(ConnectionWindow connectionForm)
private void ShowConnectionWindow(ConnectionWindow connectionForm)
{
connectionForm.Show(FrmMain.Default.pnlDock, DockState.Document);
connectionForm.Show(_dockPanel, DockState.Document);
}
private static void PrepareTabControllerSupport(bool noTabber, ConnectionWindow connectionForm)
private void PrepareTabControllerSupport(bool noTabber, ConnectionWindow connectionForm)
{
if (noTabber)
connectionForm.TabController.Dispose();
else
Runtime.WindowList.Add(connectionForm);
_windowList.Add(connectionForm);
}
private static void SetConnectionWindowTitle(string title, ConnectionWindow connectionForm)
@@ -57,7 +71,7 @@ namespace mRemoteNG.UI.Panels
connectionForm.SetFormText(title.Replace("&", "&&"));
}
private static void BuildConnectionWindowContextMenu(DockContent pnlcForm)
private void BuildConnectionWindowContextMenu(DockContent pnlcForm)
{
var cMen = new ContextMenuStrip();
var cMenRen = CreateRenameMenuItem(pnlcForm);
@@ -66,7 +80,7 @@ namespace mRemoteNG.UI.Panels
pnlcForm.TabPageContextMenuStrip = cMen;
}
private static ToolStripMenuItem CreateScreensMenuItem(DockContent pnlcForm)
private ToolStripMenuItem CreateScreensMenuItem(DockContent pnlcForm)
{
var cMenScreens = new ToolStripMenuItem
{
@@ -111,7 +125,7 @@ namespace mRemoteNG.UI.Panels
}
}
private static void cMenConnectionPanelScreens_DropDownOpening(object sender, EventArgs e)
private void cMenConnectionPanelScreens_DropDownOpening(object sender, EventArgs e)
{
try
{
@@ -137,7 +151,7 @@ namespace mRemoteNG.UI.Panels
}
}
private static void cMenConnectionPanelScreen_Click(object sender, EventArgs e)
private void cMenConnectionPanelScreen_Click(object sender, EventArgs e)
{
Screen screen = null;
DockContent panel = null;
@@ -157,7 +171,7 @@ namespace mRemoteNG.UI.Panels
panel = (DockContent)obj;
}
}
Screens.SendPanelToScreen(panel, screen);
_screens.SendPanelToScreen(panel, screen);
}
catch (Exception ex)
{

View File

@@ -3,16 +3,24 @@ using System.Linq;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using mRemoteNG.App;
using mRemoteNG.Connection;
using mRemoteNG.Container;
using mRemoteNG.Tools;
namespace mRemoteNG.UI.Window
{
public partial class ActiveDirectoryImportWindow
{
private readonly Func<ConnectionInfo> _getSelectedNodeFunc;
private readonly Import _import;
private readonly IConnectionsService _connectionsService;
private string _currentDomain;
public ActiveDirectoryImportWindow()
public ActiveDirectoryImportWindow(Func<ConnectionInfo> getSelectedNodeFunc, Import import, IConnectionsService connectionsService)
{
_getSelectedNodeFunc = getSelectedNodeFunc;
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
_import = import.ThrowIfNull(nameof(import));
InitializeComponent();
FontOverrider.FontOverride(this);
WindowType = WindowType.ActiveDirectoryImport;
@@ -44,14 +52,14 @@ namespace mRemoteNG.UI.Window
private void btnImport_Click(object sender, EventArgs e)
{
var selectedNode = Windows.TreeForm.SelectedNode;
var selectedNode = _getSelectedNodeFunc();
ContainerInfo importDestination;
if (selectedNode != null)
importDestination = selectedNode as ContainerInfo ?? selectedNode.Parent;
else
importDestination = Runtime.ConnectionsService.ConnectionTreeModel.RootNodes.First();
importDestination = _connectionsService.ConnectionTreeModel.RootNodes.First();
Import.ImportFromActiveDirectory(ActiveDirectoryTree.ADPath, importDestination, chkSubOU.Checked);
_import.ImportFromActiveDirectory(ActiveDirectoryTree.ADPath, importDestination, chkSubOU.Checked);
}
/*

View File

@@ -42,6 +42,7 @@ namespace mRemoteNG.UI.Window
private ToolStripSeparator _toolStripSeparator1;
private FilteredPropertyGrid _pGrid;
private ThemeManager _themeManager;
private readonly IConnectionsService _connectionsService;
private AbstractConnectionRecord _selectedTreeNode;
public AbstractConnectionRecord SelectedTreeNode
@@ -272,19 +273,13 @@ namespace mRemoteNG.UI.Window
public IEnumerable<string> VisibleObjectProperties => _pGrid.VisibleProperties;
#endregion
#region Constructors
public ConfigWindow() : this(new DockContent())
{
}
public ConfigWindow(DockContent panel)
public ConfigWindow(DockContent panel, IConnectionsService connectionsService)
{
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
WindowType = WindowType.Config;
DockPnl = panel;
InitializeComponent();
}
#endregion
#region Public Methods
@@ -759,7 +754,7 @@ namespace mRemoteNG.UI.Window
{
var passwordName = Settings.Default.UseSQLServer
? Language.strSQLServer.TrimEnd(':')
: Path.GetFileName(Runtime.ConnectionsService.GetStartupConnectionFileName());
: Path.GetFileName(_connectionsService.GetStartupConnectionFileName());
var password = MiscTools.PasswordDialog(passwordName);
@@ -1568,8 +1563,8 @@ namespace mRemoteNG.UI.Window
connectionInfo.Icon = iconName;
_pGrid.Refresh();
Runtime.ConnectionsService.SaveConnectionsAsync();
_connectionsService.SaveConnectionsAsync();
}
catch (Exception ex)
{
@@ -1648,10 +1643,22 @@ namespace mRemoteNG.UI.Window
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConfigPropertyGridSetHostStatusFailed + Environment.NewLine + ex.Message, true);
}
}
#endregion
#endregion
#region Event Handlers
private void propertyGridContextMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
#region Event Handlers
public void HandleConnectionTreeSelectionChanged(object sender, ConnectionInfo selectedNode)
{
try
{
SelectedTreeNode = selectedNode;
}
catch (Exception ex)
{
Runtime.MessageCollector.AddExceptionStackTrace("tvConnections_AfterSelect (UI.Window.ConnectionTreeWindow) failed", ex);
}
}
private void propertyGridContextMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
{
try
{
@@ -1693,4 +1700,4 @@ namespace mRemoteNG.UI.Window
}
#endregion
}
}
}

View File

@@ -1,16 +1,17 @@
using mRemoteNG.App;
using mRemoteNG.Config.Connections;
using mRemoteNG.Connection;
using mRemoteNG.Themes;
using mRemoteNG.Tools;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using mRemoteNG.UI.Controls;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.Config.Connections;
using mRemoteNG.Connection;
using mRemoteNG.Themes;
using mRemoteNG.Tree;
using mRemoteNG.Tree.Root;
using mRemoteNG.UI.Controls;
using WeifenLuo.WinFormsUI.Docking;
// ReSharper disable ArrangeAccessorOwnerBody
@@ -18,9 +19,17 @@ namespace mRemoteNG.UI.Window
{
public partial class ConnectionTreeWindow
{
private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator();
private readonly IConnectionInitiator _connectionInitiator;
private readonly IConnectionsService _connectionsService;
private ThemeManager _themeManager;
private readonly ConnectionTreeSearchTextFilter _connectionTreeSearchTextFilter = new ConnectionTreeSearchTextFilter();
public ConnectionContextMenu ConnectionTreeContextMenu
{
get { return olvConnections.ContextMenuStrip as ConnectionContextMenu;}
set { olvConnections.ContextMenuStrip = value; }
}
public ConnectionInfo SelectedNode => olvConnections.SelectedNode;
public ConnectionTree ConnectionTree
@@ -29,19 +38,19 @@ namespace mRemoteNG.UI.Window
set { olvConnections = value; }
}
public ConnectionTreeWindow() : this(new DockContent())
{
}
public ConnectionTreeWindow(DockContent panel)
public ConnectionTreeWindow(DockContent panel, IConnectionInitiator connectionInitiator, IConnectionsService connectionsService)
{
WindowType = WindowType.Tree;
DockPnl = panel;
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
WindowType = WindowType.Tree;
DockPnl = panel.ThrowIfNull(nameof(panel));
_connectionInitiator = connectionInitiator.ThrowIfNull(nameof(connectionInitiator));
InitializeComponent();
SetMenuEventHandlers();
SetConnectionTreeEventHandlers();
Settings.Default.PropertyChanged += OnAppSettingsChanged;
}
olvConnections.ModelFilter = _connectionTreeSearchTextFilter;
olvConnections.ConnectionsService = connectionsService;
}
private void OnAppSettingsChanged(object o, PropertyChangedEventArgs propertyChangedEventArgs)
{
@@ -50,7 +59,7 @@ namespace mRemoteNG.UI.Window
ConnectionTree.UseFiltering = Settings.Default.UseFilterSearch;
ApplyFiltering();
}
SetConnectionTreeEventHandlers();
}
@@ -89,7 +98,7 @@ namespace mRemoteNG.UI.Window
{
if (!_themeManager.ThemingActive) return;
vsToolStripExtender.SetStyle(msMain, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
vsToolStripExtender.SetStyle(olvConnections.ContextMenuStrip, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
vsToolStripExtender.SetStyle(ConnectionTreeContextMenu, _themeManager.ActiveTheme.Version, _themeManager.ActiveTheme.Theme);
//Treelistview need to be manually themed
olvConnections.BackColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TreeView_Background");
olvConnections.ForeColor = _themeManager.ActiveTheme.ExtendedPalette.getColor("TreeView_Foreground");
@@ -112,7 +121,7 @@ namespace mRemoteNG.UI.Window
SetTreePostSetupActions();
SetConnectionTreeDoubleClickHandlers();
SetConnectionTreeSingleClickHandlers();
Runtime.ConnectionsService.ConnectionsLoaded += ConnectionsServiceOnConnectionsLoaded;
_connectionsService.ConnectionsLoaded += ConnectionsServiceOnConnectionsLoaded;
}
private void SetTreePostSetupActions()
@@ -321,4 +330,4 @@ namespace mRemoteNG.UI.Window
}
#endregion
}
}
}

View File

@@ -27,20 +27,27 @@ namespace mRemoteNG.UI.Window
public partial class ConnectionWindow : BaseWindow
{
public TabControl TabController;
private readonly IConnectionInitiator _connectionInitiator = new ConnectionInitiator();
private readonly IConnectionInitiator _connectionInitiator;
private VisualStudioToolStripExtender vsToolStripExtender;
private readonly ToolStripRenderer _toolStripProfessionalRenderer = new ToolStripProfessionalRenderer();
private readonly Windows _windows;
private readonly ExternalToolsService _externalToolsService;
private readonly FrmMain _frmMain;
#region Public Methods
public ConnectionWindow(DockContent panel, string formText = "")
public ConnectionWindow(DockContent panel, IConnectionInitiator connectionInitiator,
Windows windows, ExternalToolsService externalToolsService, FrmMain frmMain, string formText = "")
{
if (formText == "")
DockPnl = panel.ThrowIfNull(nameof(panel));
_connectionInitiator = connectionInitiator.ThrowIfNull(nameof(connectionInitiator));
_windows = windows.ThrowIfNull(nameof(windows));
_externalToolsService = externalToolsService.ThrowIfNull(nameof(externalToolsService));
_frmMain = frmMain.ThrowIfNull(nameof(frmMain));
if (formText == "")
{
formText = Language.strNewPanel;
}
WindowType = WindowType.Connection;
DockPnl = panel;
InitializeComponent();
SetEventHandlers();
// ReSharper disable once VirtualMemberCallInConstructor
@@ -48,6 +55,7 @@ namespace mRemoteNG.UI.Window
TabText = formText;
}
#region Public Methods
private void SetEventHandlers()
{
SetFormEventHandlers();
@@ -157,12 +165,12 @@ namespace mRemoteNG.UI.Window
{
if (TabController.SelectedTab == null)
{
FrmMain.Default.SelectedConnection = null;
_frmMain.SelectedConnection = null;
}
else
{
var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl;
FrmMain.Default.SelectedConnection = interfaceControl?.Info;
_frmMain.SelectedConnection = interfaceControl?.Info;
}
}
#endregion
@@ -197,8 +205,8 @@ namespace mRemoteNG.UI.Window
{
if (_documentHandlersAdded)
{
FrmMain.Default.ResizeBegin -= Connection_ResizeBegin;
FrmMain.Default.ResizeEnd -= Connection_ResizeEnd;
_frmMain.ResizeBegin -= Connection_ResizeBegin;
_frmMain.ResizeEnd -= Connection_ResizeEnd;
_documentHandlersAdded = false;
}
DockHandler.FloatPane.FloatWindow.ResizeBegin += Connection_ResizeBegin;
@@ -213,8 +221,8 @@ namespace mRemoteNG.UI.Window
DockHandler.FloatPane.FloatWindow.ResizeEnd -= Connection_ResizeEnd;
_floatHandlersAdded = false;
}
FrmMain.Default.ResizeBegin += Connection_ResizeBegin;
FrmMain.Default.ResizeEnd += Connection_ResizeEnd;
_frmMain.ResizeBegin += Connection_ResizeBegin;
_frmMain.ResizeEnd += Connection_ResizeEnd;
_documentHandlersAdded = true;
}
}
@@ -243,7 +251,7 @@ namespace mRemoteNG.UI.Window
private void Connection_FormClosing(object sender, FormClosingEventArgs e)
{
if (!FrmMain.Default.IsClosing &&
if (!_frmMain.IsClosing &&
(Settings.Default.ConfirmCloseConnection == (int)ConfirmCloseEnum.All & TabController.TabPages.Count > 0 ||
Settings.Default.ConfirmCloseConnection == (int)ConfirmCloseEnum.Multiple & TabController.TabPages.Count > 1))
{
@@ -490,13 +498,13 @@ namespace mRemoteNG.UI.Window
var interfaceControl = TabController.SelectedTab?.Tag as InterfaceControl;
if (interfaceControl == null) return;
Windows.Show(WindowType.SSHTransfer);
_windows.Show(WindowType.SSHTransfer);
var connectionInfo = interfaceControl.Info;
Windows.SshtransferForm.Hostname = connectionInfo.Hostname;
Windows.SshtransferForm.Username = connectionInfo.Username;
Windows.SshtransferForm.Password = connectionInfo.Password;
Windows.SshtransferForm.Port = Convert.ToString(connectionInfo.Port);
_windows.SshtransferForm.Hostname = connectionInfo.Hostname;
_windows.SshtransferForm.Username = connectionInfo.Username;
_windows.SshtransferForm.Password = connectionInfo.Password;
_windows.SshtransferForm.Port = Convert.ToString(connectionInfo.Port);
}
catch (Exception ex)
{
@@ -617,7 +625,7 @@ namespace mRemoteNG.UI.Window
}
//add ext apps
foreach (ExternalTool externalTool in Runtime.ExternalToolsService.ExternalTools)
foreach (var externalTool in _externalToolsService.ExternalTools)
{
var nItem = new ToolStripMenuItem
{
@@ -799,7 +807,7 @@ namespace mRemoteNG.UI.Window
{
cmenTab.Close();
Application.DoEvents();
Windows.ScreenshotForm.AddScreenshot(MiscTools.TakeScreenshot(this));
_windows.ScreenshotForm.AddScreenshot(MiscTools.TakeScreenshot(this));
}
#endregion
@@ -875,7 +883,7 @@ namespace mRemoteNG.UI.Window
{
try
{
if (!(NativeMethods.GetForegroundWindow() == FrmMain.Default.Handle) && !_ignoreChangeSelectedTabClick)
if (!(NativeMethods.GetForegroundWindow() == _frmMain.Handle) && !_ignoreChangeSelectedTabClick)
{
var clickedTab = TabController.TabPageFromPoint(e.Location);
if (clickedTab != null && TabController.SelectedTab != clickedTab)

View File

@@ -1,14 +1,14 @@
using System;
using System.Drawing;
using System.Collections;
using System.Drawing;
using System.Globalization;
using System.Windows.Forms;
using System.Text;
using WeifenLuo.WinFormsUI.Docking;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.Messages;
using mRemoteNG.UI.Forms;
using mRemoteNG.Themes;
using mRemoteNG.Tools;
using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNG.UI.Window
{
@@ -16,17 +16,17 @@ namespace mRemoteNG.UI.Window
{
private ControlLayout _layout = ControlLayout.Vertical;
private readonly ThemeManager _themeManager;
private readonly ConnectionTreeWindow _connectionTreeWindow;
private readonly DockPanel _dockPanel;
public DockContent PreviousActiveForm { get; set; }
public ErrorAndInfoWindow() : this(new DockContent())
{
}
public ErrorAndInfoWindow(DockContent panel)
public ErrorAndInfoWindow(DockContent dockContent, DockPanel dockPanel, ConnectionTreeWindow connectionTreeWindow)
{
_connectionTreeWindow = connectionTreeWindow;
WindowType = WindowType.ErrorsAndInfos;
DockPnl = panel;
DockPnl = dockContent;
_dockPanel = dockPanel.ThrowIfNull(nameof(dockPanel));
InitializeComponent();
_themeManager = ThemeManager.getInstance();
ApplyTheme();
@@ -155,9 +155,9 @@ namespace mRemoteNG.UI.Window
try
{
if (PreviousActiveForm != null)
PreviousActiveForm.Show(FrmMain.Default.pnlDock);
PreviousActiveForm.Show(_dockPanel);
else
Windows.TreeForm.Show(FrmMain.Default.pnlDock);
_connectionTreeWindow.Show(_dockPanel);
}
catch (Exception)
{

View File

@@ -4,6 +4,7 @@ using System.Windows.Forms;
using BrightIdeasSoftware;
using mRemoteNG.App;
using mRemoteNG.Config.Settings;
using mRemoteNG.Connection;
using mRemoteNG.Tools;
using WeifenLuo.WinFormsUI.Docking;
using mRemoteNG.UI.Forms;
@@ -17,10 +18,21 @@ namespace mRemoteNG.UI.Window
private readonly ExternalAppsSaver _externalAppsSaver;
private readonly ThemeManager _themeManager;
private readonly FullyObservableCollection<ExternalTool> _currentlySelectedExternalTools;
private readonly IConnectionInitiator _connectionInitiator;
private readonly ExternalToolsService _externalToolsService;
private readonly Func<Optional<ConnectionInfo>> _getCurrentlySelectedConnection;
private readonly IWin32Window _dialogWindowParent;
private readonly IConnectionsService _connectionsService;
public ExternalToolsWindow()
{
InitializeComponent();
public ExternalToolsWindow(IConnectionInitiator connectionInitiator, ExternalToolsService externalToolsService,
Func<Optional<ConnectionInfo>> getCurrentlySelectedConnection, IWin32Window dialogWindowParent, IConnectionsService connectionsService)
{
_connectionInitiator = connectionInitiator.ThrowIfNull(nameof(connectionInitiator));
_externalToolsService = externalToolsService.ThrowIfNull(nameof(externalToolsService));
_getCurrentlySelectedConnection = getCurrentlySelectedConnection.ThrowIfNull(nameof(getCurrentlySelectedConnection));
_dialogWindowParent = dialogWindowParent.ThrowIfNull(nameof(dialogWindowParent));
_connectionsService = connectionsService.ThrowIfNull(nameof(connectionsService));
InitializeComponent();
WindowType = WindowType.ExternalApps;
DockPnl = new DockContent();
_themeManager = ThemeManager.getInstance();
@@ -95,7 +107,7 @@ namespace mRemoteNG.UI.Window
try
{
ToolsListObjView.BeginUpdate();
ToolsListObjView.SetObjects(Runtime.ExternalToolsService.ExternalTools, true);
ToolsListObjView.SetObjects(_externalToolsService.ExternalTools, true);
ToolsListObjView.AutoResizeColumns();
ToolsListObjView.EndUpdate();
}
@@ -109,9 +121,11 @@ namespace mRemoteNG.UI.Window
{
try
{
foreach (var externalTool in _currentlySelectedExternalTools)
var selectedConnection = _getCurrentlySelectedConnection();
foreach (var externalTool in _currentlySelectedExternalTools)
{
externalTool.Start();
externalTool.Start(selectedConnection);
}
}
catch (Exception ex)
@@ -157,7 +171,7 @@ namespace mRemoteNG.UI.Window
private void ExternalTools_FormClosed(object sender, FormClosedEventArgs e)
{
_externalAppsSaver.Save(Runtime.ExternalToolsService.ExternalTools);
_externalAppsSaver.Save(_externalToolsService.ExternalTools);
_themeManager.ThemeChanged -= ApplyTheme;
_currentlySelectedExternalTools.CollectionUpdated -= CurrentlySelectedExternalToolsOnCollectionUpdated;
}
@@ -166,8 +180,8 @@ namespace mRemoteNG.UI.Window
{
try
{
var externalTool = new ExternalTool(Language.strExternalToolDefaultName);
Runtime.ExternalToolsService.ExternalTools.Add(externalTool);
var externalTool = new ExternalTool(_connectionInitiator, _connectionsService) { DisplayName = Language.strExternalToolDefaultName };
_externalToolsService.ExternalTools.Add(externalTool);
UpdateToolsListObjView();
ToolsListObjView.SelectedObject = externalTool;
DisplayNameTextBox.Focus();
@@ -190,12 +204,12 @@ namespace mRemoteNG.UI.Window
else
return;
if (MessageBox.Show(FrmMain.Default, message, "Question?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
if (MessageBox.Show(_dialogWindowParent, message, "Question?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
return;
foreach (var externalTool in _currentlySelectedExternalTools)
{
Runtime.ExternalToolsService.ExternalTools.Remove(externalTool);
_externalToolsService.ExternalTools.Remove(externalTool);
}
var firstDeletedNode = _currentlySelectedExternalTools.FirstOrDefault();
var oldSelectedIndex = ToolsListObjView.IndexOf(firstDeletedNode);

View File

@@ -14,10 +14,15 @@ namespace mRemoteNG.UI.Window
{
public partial class PortScanWindow
{
private readonly ConnectionTreeWindow _connectionTreeWindow;
private readonly Import _import;
#region Constructors
public PortScanWindow()
public PortScanWindow(ConnectionTreeWindow connectionTreeWindow, Import import)
{
InitializeComponent();
_connectionTreeWindow = connectionTreeWindow.ThrowIfNull(nameof(connectionTreeWindow));
_import = import.ThrowIfNull(nameof(import));
InitializeComponent();
WindowType = WindowType.PortScan;
DockPnl = new DockContent();
@@ -258,7 +263,7 @@ namespace mRemoteNG.UI.Window
}
var destinationContainer = GetDestinationContainerForImportedHosts();
Import.ImportFromPortScan(hosts, protocol, destinationContainer);
_import.ImportFromPortScan(hosts, protocol, destinationContainer);
}
/// <summary>
@@ -267,16 +272,15 @@ namespace mRemoteNG.UI.Window
/// </summary>
private ContainerInfo GetDestinationContainerForImportedHosts()
{
var selectedNode = Windows.TreeForm.SelectedNode
?? Windows.TreeForm.ConnectionTree.ConnectionTreeModel.RootNodes.OfType<RootNodeInfo>().First();
var selectedNode = _connectionTreeWindow.SelectedNode
?? _connectionTreeWindow.ConnectionTree.ConnectionTreeModel.RootNodes.OfType<RootNodeInfo>().First();
// if a putty node is selected, place imported connections in the root connection node
if (selectedNode is RootPuttySessionsNodeInfo || selectedNode is PuttySessionInfo)
selectedNode = Windows.TreeForm.ConnectionTree.ConnectionTreeModel.RootNodes.OfType<RootNodeInfo>().First();
selectedNode = _connectionTreeWindow.ConnectionTree.ConnectionTreeModel.RootNodes.OfType<RootNodeInfo>().First();
// if the selected node is a connection, use its parent container
var selectedTreeNodeAsContainer = selectedNode as ContainerInfo ?? selectedNode.Parent;
return selectedTreeNodeAsContainer;
}

View File

@@ -293,6 +293,7 @@ namespace mRemoteNG.UI.Window
#region Private Properties
private readonly OpenFileDialog oDlg;
private readonly IWin32Window _dialogParentWindow;
#endregion
#region Public Properties
@@ -473,7 +474,7 @@ namespace mRemoteNG.UI.Window
{
if (txtPassword.Text == "")
{
if (MessageBox.Show(FrmMain.Default, Language.strEmptyPasswordContinue, @"Question?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
if (MessageBox.Show(_dialogParentWindow, Language.strEmptyPasswordContinue, @"Question?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
{
return false;
}
@@ -550,8 +551,15 @@ namespace mRemoteNG.UI.Window
#endregion
#region Public Methods
public SSHTransferWindow()
: this(null)
{
}
public SSHTransferWindow(IWin32Window dialogParentWindow)
{
_dialogParentWindow = dialogParentWindow;
WindowType = WindowType.SSHTransfer;
DockPnl = new DockContent();
InitializeComponent();

View File

@@ -1,11 +1,12 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using mRemoteNG.App;
using System.IO;
using mRemoteNG.UI.Forms;
using System.Windows.Forms;
using mRemoteNG.App;
using mRemoteNG.Themes;
using mRemoteNG.Tools;
using mRemoteNG.UI.Forms;
using WeifenLuo.WinFormsUI.Docking;
namespace mRemoteNG.UI.Window
{
@@ -174,15 +175,19 @@ namespace mRemoteNG.UI.Window
#region Public Methods
public ScreenshotManagerWindow() : this(new DockContent())
private readonly DockPanel _dockPanel;
public ScreenshotManagerWindow()
: this(new DockContent(), new DockPanel())
{
}
internal ScreenshotManagerWindow(DockContent panel)
public ScreenshotManagerWindow(DockContent dockContent, DockPanel dockPanel)
{
WindowType = WindowType.ScreenshotManager;
DockPnl = panel;
InitializeComponent();
DockPnl = dockContent;
_dockPanel = dockPanel.ThrowIfNull(nameof(dockPanel));
InitializeComponent();
}
public void AddScreenshot(Image Screenshot)
@@ -209,8 +214,8 @@ namespace mRemoteNG.UI.Window
nBtn.Size = new Size(22, 22);
nBtn.Location = new Point(nPB.Width - nBtn.Width, -1);
nBtn.Show();
Show(FrmMain.Default.pnlDock);
Show(_dockPanel);
}
catch (Exception ex)
{

View File

@@ -1,5 +1,6 @@
using System;
using mRemoteNG.App;
using mRemoteNG.Tools;
using WeifenLuo.WinFormsUI.Docking;
@@ -7,6 +8,8 @@ namespace mRemoteNG.UI.Window
{
public class UltraVNCWindow : BaseWindow
{
private readonly Action<WindowType> _showWindowAction;
#region Form Init
internal System.Windows.Forms.ToolStrip tsMain;
internal System.Windows.Forms.Panel pnlContainer;
@@ -69,18 +72,13 @@ namespace mRemoteNG.UI.Window
}
#endregion
#region Declarations
//Private WithEvents vnc As AxCSC_ViewerXControl
#endregion
#region Public Methods
public UltraVNCWindow()
public UltraVNCWindow(Action<WindowType> showWindowAction)
{
this.WindowType = WindowType.UltraVNCSC;
this.DockPnl = new DockContent();
this.InitializeComponent();
_showWindowAction = showWindowAction.ThrowIfNull(nameof(showWindowAction));
WindowType = WindowType.UltraVNCSC;
DockPnl = new DockContent();
InitializeComponent();
}
#endregion
#region Private Methods
private void UltraVNCSC_Load(object sender, System.EventArgs e)
@@ -151,7 +149,7 @@ namespace mRemoteNG.UI.Window
{
//vnc.Dispose()
Dispose();
Windows.Show(WindowType.UltraVNCSC);
_showWindowAction(WindowType.UltraVNCSC);
}
#endregion
}

Some files were not shown because too many files have changed in this diff Show More