Compare commits

...

14 Commits

Author SHA1 Message Date
David Sparer
f10e54e47b bumped assembly version to 1.76.8 2018-08-25 10:31:35 -05:00
David Sparer
704e0c1dc1 updated changelog 2018-08-25 10:29:43 -05:00
David Sparer
0c79a9acde fixes #1088 2018-08-24 14:43:08 -05:00
David Sparer
ebfc2715e7 updated changelog 2018-08-24 13:24:23 -05:00
David Sparer
b0dbc9dc18 only delete reg key value if the value exists 2018-08-24 13:23:52 -05:00
David Sparer
507cdf75a5 fixes #1087 2018-08-24 13:23:02 -05:00
David Sparer
8f8492b0be xml deserializer now gives connections an ID if the ID string in xml is empty
fixes #1082
2018-08-24 10:37:54 -05:00
David Sparer
457e715188 set assembly version to 1.76.7 and set release date in changelog 2018-08-22 10:59:45 -05:00
David Sparer
1724521ebf added some null guards to methods 2018-08-22 07:06:44 -05:00
David Sparer
b0fb3596aa added some safety checks around accessing putty registry settings 2018-08-22 07:06:16 -05:00
David Sparer
fb228d72b1 resolved bug #1076 2018-08-19 11:44:43 -05:00
David Sparer
916361a3be update changelog 2018-08-11 20:03:27 -05:00
David Sparer
408c40f699 fixed a few toolbar location loading edge cases
related to #1068
2018-08-11 10:02:07 -05:00
David Sparer
4173f6d775 swapped direct calls to Monitor with a lock statement and added a few method comments 2018-08-11 06:47:31 -05:00
14 changed files with 144 additions and 44 deletions

View File

@@ -1,3 +1,20 @@
1.76.8 (2018-08-25):
Fixes:
------
#1088: Delete and Launch buttons are not disabled when last external tool deleted
#1087: 'Save connections after every edit' setting not honored
#1082: Connections not given GUID if Id is empty in connection xml
1.76.7 (2018-08-22):
Fixes:
------
#1076: Wrong object selected when duplicating connection then switching between properties and inheritance in config window
#1068: Fixed some toolbar positioning bugs
1.76.6 (2018-08-03):
Fixes:

View File

@@ -43,6 +43,20 @@ namespace mRemoteNGTests.Connection
Assert.That(clonedConnection.Parent, Is.Null);
}
[Test]
public void CloneAlsoCopiesInheritanceObject()
{
var clonedConnection = _connectionInfo.Clone();
Assert.That(clonedConnection.Inheritance, Is.Not.EqualTo(_connectionInfo.Inheritance));
}
[Test]
public void CloneCorrectlySetsParentOfInheritanceObject()
{
var clonedConnection = _connectionInfo.Clone();
Assert.That(clonedConnection.Inheritance.Parent, Is.EqualTo(clonedConnection));
}
[Test]
public void CopyFromCopiesProperties()
{

View File

@@ -1,4 +1,6 @@
using System.Linq;
using System;
using System.Linq;
using System.Xml.Linq;
using mRemoteNG.Config.Serializers;
using mRemoteNG.Config.Serializers.Xml;
using mRemoteNG.Connection;
@@ -29,20 +31,19 @@ namespace mRemoteNGTests.IntegrationTests
_originalModel.RootNodes.OfType<RootNodeInfo>().First().PasswordString.ConvertToSecureString(),
new SaveFilter());
_serializer = new XmlConnectionsSerializer(cryptoProvider, nodeSerializer);
_deserializer = new XmlConnectionsDeserializer();
}
[TearDown]
public void Teardown()
{
_serializer = null;
_deserializer = null;
}
[Test]
public void SerializeThenDeserialize()
{
var serializedContent = _serializer.Serialize(_originalModel);
_deserializer = new XmlConnectionsDeserializer();
var deserializedModel = _deserializer.Deserialize(serializedContent);
var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name);
var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name);
@@ -54,7 +55,6 @@ namespace mRemoteNGTests.IntegrationTests
{
_serializer.UseFullEncryption = true;
var serializedContent = _serializer.Serialize(_originalModel);
_deserializer = new XmlConnectionsDeserializer();
var deserializedModel = _deserializer.Deserialize(serializedContent);
var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name);
var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name);
@@ -66,7 +66,6 @@ namespace mRemoteNGTests.IntegrationTests
{
var originalConnectionInfo = new ConnectionInfo {Name = "con1", Description = "£°úg¶┬ä" };
var serializedContent = _serializer.Serialize(originalConnectionInfo);
_deserializer = new XmlConnectionsDeserializer();
var deserializedModel = _deserializer.Deserialize(serializedContent);
var deserializedConnectionInfo = deserializedModel.GetRecursiveChildList().First(node => node.Name == originalConnectionInfo.Name);
Assert.That(deserializedConnectionInfo.Description, Is.EqualTo(originalConnectionInfo.Description));
@@ -84,13 +83,26 @@ namespace mRemoteNGTests.IntegrationTests
new SaveFilter());
_serializer = new XmlConnectionsSerializer(cryptoProvider, nodeSerializer);
var serializedContent = _serializer.Serialize(_originalModel);
_deserializer = new XmlConnectionsDeserializer();
var deserializedModel = _deserializer.Deserialize(serializedContent);
var nodeNamesFromDeserializedModel = deserializedModel.GetRecursiveChildList().Select(node => node.Name);
var nodeNamesFromOriginalModel = _originalModel.GetRecursiveChildList().Select(node => node.Name);
Assert.That(nodeNamesFromDeserializedModel, Is.EquivalentTo(nodeNamesFromOriginalModel));
}
[Test]
public void GuidCreatedIfNonExistedInXml()
{
var originalConnectionInfo = new ConnectionInfo { Name = "con1" };
var serializedContent = _serializer.Serialize(originalConnectionInfo);
// remove GUID from connection xml
serializedContent = serializedContent.Replace(originalConnectionInfo.ConstantID, "");
var deserializedModel = _deserializer.Deserialize(serializedContent);
var deserializedConnectionInfo = deserializedModel.GetRecursiveChildList().First(node => node.Name == originalConnectionInfo.Name);
Assert.That(Guid.TryParse(deserializedConnectionInfo.ConstantID, out var guid));
}
private ConnectionTreeModel SetupConnectionTreeModel()
{

View File

@@ -1,13 +1,13 @@
using mRemoteNG.Tools;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using mRemoteNG.Tools;
using mRemoteNG.Tree.Root;
// ReSharper disable ArrangeAccessorOwnerBody
namespace mRemoteNG.Config.Putty
{
public class PuttySessionsManager
public class PuttySessionsManager
{
public static PuttySessionsManager Instance { get; } = new PuttySessionsManager();
@@ -35,10 +35,12 @@ namespace mRemoteNG.Config.Putty
}
}
private void AddSessionsFromProvider(AbstractPuttySessionsProvider provider)
private void AddSessionsFromProvider(AbstractPuttySessionsProvider puttySessionProvider)
{
var rootTreeNode = provider.RootInfo;
provider.GetSessions();
puttySessionProvider.ThrowIfNull(nameof(puttySessionProvider));
var rootTreeNode = puttySessionProvider.RootInfo;
puttySessionProvider.GetSessions();
if (!RootPuttySessionsNodes.Contains(rootTreeNode) && rootTreeNode.HasChildren())
RootPuttySessionsNodes.Add(rootTreeNode);

View File

@@ -53,13 +53,14 @@ namespace mRemoteNG.Config.Putty
{
PuttySession = sessionName,
Name = sessionName,
Hostname = sessionKey.GetValue("HostName").ToString(),
Username = sessionKey.GetValue("UserName").ToString()
Hostname = sessionKey.GetValue("HostName")?.ToString() ?? "",
Username = sessionKey.GetValue("UserName")?.ToString() ?? ""
};
var protocol = string.IsNullOrEmpty(sessionKey.GetValue("Protocol").ToString())
? sessionKey.GetValue("Protocol").ToString()
: "ssh";
var protocol = string.IsNullOrEmpty(sessionKey.GetValue("Protocol")?.ToString())
? "ssh"
: sessionKey.GetValue("Protocol").ToString();
switch (protocol.ToLowerInvariant())
{
@@ -72,7 +73,7 @@ namespace mRemoteNG.Config.Putty
case "serial":
return null;
case "ssh":
int.TryParse(sessionKey.GetValue("SshProt").ToString(), out var sshVersion);
int.TryParse(sessionKey.GetValue("SshProt")?.ToString(), out var sshVersion);
/* Per PUTTY.H in PuTTYNG & PuTTYNG Upstream (PuTTY proper currently)
* expect 0 for SSH1, 3 for SSH2 ONLY
* 1 for SSH1 with a 2 fallback
@@ -88,7 +89,12 @@ namespace mRemoteNG.Config.Putty
default:
return null;
}
sessionInfo.Port = Convert.ToInt32(sessionKey.GetValue("PortNumber"));
int.TryParse(sessionKey.GetValue("PortNumber")?.ToString(), out var portNumber);
if (portNumber == default(int))
sessionInfo.SetDefaultPort();
else
sessionInfo.Port = portNumber;
return sessionInfo;
}

View File

@@ -205,7 +205,9 @@ namespace mRemoteNG.Config.Serializers.Xml
{
if (xmlnode.Attributes == null) return null;
var connectionId = xmlnode.Attributes["Id"]?.Value ?? Guid.NewGuid().ToString();
var connectionId = xmlnode.Attributes["Id"]?.Value;
if (string.IsNullOrWhiteSpace(connectionId))
connectionId = Guid.NewGuid().ToString();
var connectionInfo = new ConnectionInfo(connectionId);
try

View File

@@ -19,6 +19,7 @@ namespace mRemoteNG.Config.Settings
{
private readonly ExternalAppsLoader _externalAppsLoader;
private readonly MessageCollector _messageCollector;
private readonly MenuStrip _mainMenu;
private readonly QuickConnectToolStrip _quickConnectToolStrip;
private readonly ExternalToolsToolStrip _externalToolsToolStrip;
private readonly MultiSshToolStrip _multiSshToolStrip;
@@ -31,7 +32,8 @@ namespace mRemoteNG.Config.Settings
MessageCollector messageCollector,
QuickConnectToolStrip quickConnectToolStrip,
ExternalToolsToolStrip externalToolsToolStrip,
MultiSshToolStrip multiSshToolStrip)
MultiSshToolStrip multiSshToolStrip,
MenuStrip mainMenu)
{
if (mainForm == null)
throw new ArgumentNullException(nameof(mainForm));
@@ -43,13 +45,16 @@ namespace mRemoteNG.Config.Settings
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;
_externalAppsLoader = new ExternalAppsLoader(MainForm, messageCollector, _externalToolsToolStrip);
_mainMenu = mainMenu;
_externalAppsLoader = new ExternalAppsLoader(MainForm, messageCollector, _externalToolsToolStrip);
}
#region Public Methods
@@ -197,6 +202,7 @@ namespace mRemoteNG.Config.Settings
private void LoadToolbarsFromSettings()
{
ResetAllToolbarLocations();
AddMainMenuPanel();
AddExternalAppsPanel();
AddQuickConnectPanel();
AddMultiSshPanel();
@@ -210,31 +216,49 @@ namespace mRemoteNG.Config.Settings
private void ResetAllToolbarLocations()
{
var tempToolStrip = new ToolStripPanel();
tempToolStrip.Join(_mainMenu);
tempToolStrip.Join(_quickConnectToolStrip);
tempToolStrip.Join(_externalToolsToolStrip);
tempToolStrip.Join(_multiSshToolStrip);
}
private void AddMainMenuPanel()
{
SetToolstripGripStyle(_mainMenu);
var toolStripPanel = ToolStripPanelFromString("top");
toolStripPanel.Join(_mainMenu, new Point(3, 0));
}
private void AddQuickConnectPanel()
{
SetToolstripGripStyle(_quickConnectToolStrip);
_quickConnectToolStrip.Visible = mRemoteNG.Settings.Default.QuickyTBVisible;
var toolStripPanel = ToolStripPanelFromString(mRemoteNG.Settings.Default.QuickyTBParentDock);
toolStripPanel.Join(_quickConnectToolStrip, mRemoteNG.Settings.Default.QuickyTBLocation);
_quickConnectToolStrip.Visible = mRemoteNG.Settings.Default.QuickyTBVisible;
}
private void AddExternalAppsPanel()
{
var toolStripPanel = ToolStripPanelFromString(mRemoteNG.Settings.Default.ExtAppsTBParentDock);
toolStripPanel.Join(_externalToolsToolStrip, mRemoteNG.Settings.Default.ExtAppsTBLocation);
SetToolstripGripStyle(_externalToolsToolStrip);
_externalToolsToolStrip.Visible = mRemoteNG.Settings.Default.ExtAppsTBVisible;
var toolStripPanel = ToolStripPanelFromString(mRemoteNG.Settings.Default.ExtAppsTBParentDock);
toolStripPanel.Join(_externalToolsToolStrip, mRemoteNG.Settings.Default.ExtAppsTBLocation);
}
private void AddMultiSshPanel()
{
var toolStripPanel = ToolStripPanelFromString(mRemoteNG.Settings.Default.ExtAppsTBParentDock);
toolStripPanel.Join(_multiSshToolStrip, mRemoteNG.Settings.Default.MultiSshToolbarLocation);
SetToolstripGripStyle(_multiSshToolStrip);
_multiSshToolStrip.Visible = mRemoteNG.Settings.Default.MultiSshToolbarVisible;
var toolStripPanel = ToolStripPanelFromString(mRemoteNG.Settings.Default.MultiSshToolbarParentDock);
toolStripPanel.Join(_multiSshToolStrip, mRemoteNG.Settings.Default.MultiSshToolbarLocation);
}
private void SetToolstripGripStyle(ToolStrip toolbar)
{
toolbar.GripStyle = mRemoteNG.Settings.Default.LockToolbars
? ToolStripGripStyle.Hidden
: ToolStripGripStyle.Visible;
}
private ToolStripPanel ToolStripPanelFromString(string panel)
{

View File

@@ -78,7 +78,8 @@ namespace mRemoteNG.Connection
var newConnectionInfo = new ConnectionInfo();
newConnectionInfo.CopyFrom(this);
newConnectionInfo.Inheritance = Inheritance.Clone();
return newConnectionInfo;
newConnectionInfo.Inheritance.Parent = newConnectionInfo;
return newConnectionInfo;
}
public void CopyFrom(ConnectionInfo sourceConnectionInfo)

View File

@@ -45,6 +45,7 @@ namespace mRemoteNG.Connection
{
try
{
filename.ThrowIfNullOrEmpty(nameof(filename));
var newConnectionsModel = new ConnectionTreeModel();
newConnectionsModel.AddRootNode(new RootNodeInfo(RootNodeType.Connection));
SaveConnections(newConnectionsModel, false, new SaveFilter(), filename, true);
@@ -130,11 +131,22 @@ namespace mRemoteNG.Connection
RaiseConnectionsLoadedEvent(oldConnectionTreeModel, newConnectionTreeModel, oldIsUsingDatabaseValue, useDatabase, connectionFileName);
}
/// <summary>
/// When turned on, calls to <see cref="SaveConnections()"/> or
/// <see cref="SaveConnectionsAsync"/> will not immediately execute.
/// Instead, they will be deferred until <see cref="EndBatchingSaves"/>
/// is called.
/// </summary>
public void BeginBatchingSaves()
{
_batchingSaves = true;
}
/// <summary>
/// Immediately executes a single <see cref="SaveConnections()"/> or
/// <see cref="SaveConnectionsAsync"/> if one has been requested
/// since calling <see cref="BeginBatchingSaves"/>.
/// </summary>
public void EndBatchingSaves()
{
_batchingSaves = false;
@@ -221,9 +233,10 @@ namespace mRemoteNG.Connection
private void SaveConnectionsBGd()
{
Monitor.Enter(SaveLock);
SaveConnections();
Monitor.Exit(SaveLock);
lock (SaveLock)
{
SaveConnections();
}
}
public string GetStartupConnectionFileName()

View File

@@ -33,5 +33,5 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
// <Assembly: AssemblyVersion("1.0.*")>
[assembly: AssemblyVersion("1.76.6.*")]
[assembly: AssemblyVersion("1.76.8.*")]
[assembly: NeutralResourcesLanguage("en")]

View File

@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using Microsoft.Win32;
using mRemoteNG.App;
@@ -38,14 +39,16 @@ namespace mRemoteNG.Tools
{
using (var key = Registry.CurrentUser.OpenSubKey(string.Concat("Software\\Wow6432Node\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\", feature), RegistryKeyPermissionCheck.ReadWriteSubTree))
{
key?.DeleteValue(appName);
if (key?.GetValueNames().Contains(appName) ?? false)
key.DeleteValue(appName);
}
}
using (var key = Registry.CurrentUser.CreateSubKey(string.Concat("Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\", feature), RegistryKeyPermissionCheck.ReadWriteSubTree))
{
key?.DeleteValue(appName);
if (key?.GetValueNames().Contains(appName) ?? false)
key.DeleteValue(appName);
}
}
#endif

View File

@@ -140,7 +140,7 @@ namespace mRemoteNG.UI.Forms
Startup.Instance.InitializeProgram(messageCollector);
msMain.Location = Point.Empty;
var settingsLoader = new SettingsLoader(this, messageCollector, _quickConnectToolStrip, _externalToolsToolStrip, _multiSshToolStrip);
var settingsLoader = new SettingsLoader(this, messageCollector, _quickConnectToolStrip, _externalToolsToolStrip, _multiSshToolStrip, msMain);
settingsLoader.LoadSettings();
SetMenuDependencies();

View File

@@ -706,7 +706,6 @@ namespace mRemoteNG.UI.Window
UpdateRootInfoNode(e);
UpdateInheritanceNode();
ShowHideGridItems();
Runtime.ConnectionsService.SaveConnectionsAsync();
}
catch (Exception ex)
{

View File

@@ -134,6 +134,19 @@ namespace mRemoteNG.UI.Window
RunElevatedCheckBox.Checked = selectedTool?.RunElevated ?? false;
WaitForExitCheckBox.Enabled = !TryToIntegrateCheckBox.Checked;
}
private void UpdateToolstipControls()
{
_currentlySelectedExternalTools.Clear();
_currentlySelectedExternalTools.AddRange(ToolsListObjView.SelectedObjects.OfType<ExternalTool>());
PropertiesGroupBox.Enabled = _currentlySelectedExternalTools.Count == 1;
var atleastOneToolSelected = _currentlySelectedExternalTools.Count > 0;
DeleteToolMenuItem.Enabled = atleastOneToolSelected;
DeleteToolToolstripButton.Enabled = atleastOneToolSelected;
LaunchToolMenuItem.Enabled = atleastOneToolSelected;
LaunchToolToolstripButton.Enabled = atleastOneToolSelected;
}
#endregion
#region Event Handlers
@@ -193,6 +206,8 @@ namespace mRemoteNG.UI.Window
ToolsListObjView.SelectedIndex = oldSelectedIndex <= maxIndex
? oldSelectedIndex
: maxIndex;
UpdateToolstipControls();
}
catch (Exception ex)
{
@@ -209,15 +224,7 @@ namespace mRemoteNG.UI.Window
{
try
{
_currentlySelectedExternalTools.Clear();
_currentlySelectedExternalTools.AddRange(ToolsListObjView.SelectedObjects.OfType<ExternalTool>());
PropertiesGroupBox.Enabled = _currentlySelectedExternalTools.Count == 1;
var atleastOneToolSelected = _currentlySelectedExternalTools.Count > 0;
DeleteToolMenuItem.Enabled = atleastOneToolSelected;
DeleteToolToolstripButton.Enabled = atleastOneToolSelected;
LaunchToolMenuItem.Enabled = atleastOneToolSelected;
LaunchToolToolstripButton.Enabled = atleastOneToolSelected;
UpdateToolstipControls();
}
catch (Exception ex)
{