mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-25 19:38:37 +08:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e70dce626 | ||
|
|
52d1b9a270 | ||
|
|
068f5942e7 | ||
|
|
703cefaf19 | ||
|
|
3d32557177 | ||
|
|
ea1f72b8b7 | ||
|
|
993b6759cc | ||
|
|
c0b07307f5 | ||
|
|
15f23769d6 | ||
|
|
2d175fd575 | ||
|
|
bdeb4b4dcc | ||
|
|
bdfbb57504 | ||
|
|
38d1c756f3 | ||
|
|
6c89913bc6 | ||
|
|
efa72cb697 | ||
|
|
a31fec5fb9 | ||
|
|
ed81030976 | ||
|
|
54322ca949 | ||
|
|
738b159e95 | ||
|
|
e8f2e4f50c | ||
|
|
5cd201440e | ||
|
|
5c6c76b898 | ||
|
|
4847ce054b | ||
|
|
ec42fe7d7d | ||
|
|
07a20ed5ad | ||
|
|
8ab221e5a8 | ||
|
|
d1a7a37909 |
@@ -1,3 +1,57 @@
|
|||||||
|
1.76.20 (2019-04-12):
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
------
|
||||||
|
#1401: Connections corrupted when importing RDC Manager files that are missing certain fields
|
||||||
|
|
||||||
|
|
||||||
|
1.76.19 (2019-04-04):
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
------
|
||||||
|
#1374: Vertical Scroll Bar missing in PuTTYNG after 0.70.0.1 & 0.71 updates
|
||||||
|
|
||||||
|
|
||||||
|
1.76.18 (2019-03-20):
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
------
|
||||||
|
#1365: PuTTY window not centered after 0.71 update
|
||||||
|
|
||||||
|
|
||||||
|
1.76.17 (2019-03-20):
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
------
|
||||||
|
#1362: Updated PuTTYNG to 0.71
|
||||||
|
|
||||||
|
|
||||||
|
1.76.16 (2019-03-14):
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
------
|
||||||
|
#1347: Remote Desktop Gateway username field encrypted instead of password
|
||||||
|
|
||||||
|
|
||||||
|
1.76.15 (2019-03-09):
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
------
|
||||||
|
#1303: Exception on first connection with new SQL server database
|
||||||
|
#1304: Resolved several issues with importing multiple RDP Manager v2.7 files
|
||||||
|
|
||||||
|
Features/Enhancements:
|
||||||
|
----------------------
|
||||||
|
Importing multiple files now only causes 1 save event, rather than 1 per file imported.
|
||||||
|
|
||||||
|
|
||||||
|
1.76.14 (2019-02-08):
|
||||||
|
|
||||||
|
Features/Enhancements:
|
||||||
|
----------------------
|
||||||
|
#222: Allow FIPS to be enabled
|
||||||
|
|
||||||
|
|
||||||
1.76.13 (2018-12-22):
|
1.76.13 (2018-12-22):
|
||||||
|
|
||||||
Changes:
|
Changes:
|
||||||
|
|||||||
47
mRemoteNGTests/App/ImportTests.cs
Normal file
47
mRemoteNGTests/App/ImportTests.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using System.IO;
|
||||||
|
using mRemoteNG.App;
|
||||||
|
using mRemoteNG.Config.Putty;
|
||||||
|
using mRemoteNG.Connection;
|
||||||
|
using mRemoteNG.Container;
|
||||||
|
using mRemoteNGTests.Properties;
|
||||||
|
using mRemoteNGTests.TestHelpers;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace mRemoteNGTests.App
|
||||||
|
{
|
||||||
|
public class ImportTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void ErrorHandlerCalledWhenUnsupportedFileExtensionFound()
|
||||||
|
{
|
||||||
|
using (FileTestHelpers.DisposableTempFile(out var file, ".blah"))
|
||||||
|
{
|
||||||
|
var conService = new ConnectionsService(PuttySessionsManager.Instance);
|
||||||
|
var container = new ContainerInfo();
|
||||||
|
var exceptionOccurred = false;
|
||||||
|
|
||||||
|
Import.HeadlessFileImport(new []{file}, container, conService, s => exceptionOccurred = true);
|
||||||
|
|
||||||
|
Assert.That(exceptionOccurred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void AnErrorInOneFileDoNotPreventOtherFilesFromProcessing()
|
||||||
|
{
|
||||||
|
using (FileTestHelpers.DisposableTempFile(out var badFile, ".blah"))
|
||||||
|
using (FileTestHelpers.DisposableTempFile(out var rdpFile, ".rdp"))
|
||||||
|
{
|
||||||
|
File.AppendAllText(rdpFile, Resources.test_remotedesktopconnection_rdp);
|
||||||
|
var conService = new ConnectionsService(PuttySessionsManager.Instance);
|
||||||
|
var container = new ContainerInfo();
|
||||||
|
var exceptionCount = 0;
|
||||||
|
|
||||||
|
Import.HeadlessFileImport(new[] { badFile, rdpFile }, container, conService, s => exceptionCount++);
|
||||||
|
|
||||||
|
Assert.That(exceptionCount, Is.EqualTo(1));
|
||||||
|
Assert.That(container.Children, Has.One.Items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +1,21 @@
|
|||||||
using System.IO;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using mRemoteNG.Config.Serializers;
|
using mRemoteNG.Config.Serializers;
|
||||||
|
using mRemoteNG.Connection;
|
||||||
using mRemoteNG.Connection.Protocol;
|
using mRemoteNG.Connection.Protocol;
|
||||||
using mRemoteNG.Connection.Protocol.RDP;
|
using mRemoteNG.Connection.Protocol.RDP;
|
||||||
using mRemoteNG.Container;
|
using mRemoteNG.Container;
|
||||||
using mRemoteNG.Tree;
|
|
||||||
using mRemoteNGTests.Properties;
|
using mRemoteNGTests.Properties;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace mRemoteNGTests.Config.Serializers.MiscSerializers
|
namespace mRemoteNGTests.Config.Serializers.MiscSerializers
|
||||||
{
|
{
|
||||||
public class RemoteDesktopConnectionManager27DeserializerTests
|
public class RemoteDesktopConnectionManager27DeserializerTests
|
||||||
{
|
{
|
||||||
private string _connectionFileContents;
|
private string _connectionFileContents;
|
||||||
private RemoteDesktopConnectionManagerDeserializer _deserializer;
|
private RemoteDesktopConnectionManagerDeserializer _deserializer;
|
||||||
private ConnectionTreeModel _connectionTreeModel;
|
|
||||||
private const string ExpectedName = "server1_displayname";
|
private const string ExpectedName = "server1_displayname";
|
||||||
private const string ExpectedHostname = "server1";
|
private const string ExpectedHostname = "server1";
|
||||||
private const string ExpectedDescription = "Comment text here";
|
private const string ExpectedDescription = "Comment text here";
|
||||||
@@ -44,265 +45,80 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
|
|||||||
{
|
{
|
||||||
_connectionFileContents = Resources.test_rdcman_v2_7_schema3;
|
_connectionFileContents = Resources.test_rdcman_v2_7_schema3;
|
||||||
_deserializer = new RemoteDesktopConnectionManagerDeserializer();
|
_deserializer = new RemoteDesktopConnectionManagerDeserializer();
|
||||||
_connectionTreeModel = _deserializer.Deserialize(_connectionFileContents);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ConnectionTreeModelHasARootNode()
|
public void ConnectionTreeModelHasARootNode()
|
||||||
{
|
{
|
||||||
var numberOfRootNodes = _connectionTreeModel.RootNodes.Count;
|
var connectionTreeModel = _deserializer.Deserialize(_connectionFileContents);
|
||||||
|
var numberOfRootNodes = connectionTreeModel.RootNodes.Count;
|
||||||
Assert.That(numberOfRootNodes, Is.GreaterThan(0));
|
Assert.That(numberOfRootNodes, Is.GreaterThan(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void RootNodeHasContents()
|
public void RootNodeHasContents()
|
||||||
{
|
{
|
||||||
var rootNodeContents = _connectionTreeModel.RootNodes.First().Children;
|
var connectionTreeModel = _deserializer.Deserialize(_connectionFileContents);
|
||||||
|
var rootNodeContents = connectionTreeModel.RootNodes.First().Children;
|
||||||
Assert.That(rootNodeContents, Is.Not.Empty);
|
Assert.That(rootNodeContents, Is.Not.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void AllSubRootFoldersImported()
|
public void AllSubRootFoldersImported()
|
||||||
{
|
{
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
var connectionTreeModel = _deserializer.Deserialize(_connectionFileContents);
|
||||||
|
var rootNode = connectionTreeModel.RootNodes.First();
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
||||||
var rootNodeContents = importedRdcmanRootNode.Children.Count(node => node.Name == "Group1" || node.Name == "Group2");
|
var rootNodeContents = importedRdcmanRootNode.Children.Count(node => node.Name == "Group1" || node.Name == "Group2");
|
||||||
Assert.That(rootNodeContents, Is.EqualTo(2));
|
Assert.That(rootNodeContents, Is.EqualTo(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[TestCaseSource(nameof(ExpectedPropertyValues))]
|
||||||
public void ConnectionDisplayNameImported()
|
public void PropertiesWithValuesAreCorrectlyImported(Func<ConnectionInfo, object> propSelector, object expectedValue)
|
||||||
{
|
{
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
var connectionTreeModel = _deserializer.Deserialize(_connectionFileContents);
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
var connection = connectionTreeModel
|
||||||
var connection = group1.Children.First();
|
.GetRecursiveChildList()
|
||||||
Assert.That(connection.Name, Is.EqualTo(ExpectedName));
|
.OfType<ContainerInfo>()
|
||||||
|
.First(node => node.Name == "Group1")
|
||||||
|
.Children
|
||||||
|
.First();
|
||||||
|
|
||||||
|
Assert.That(propSelector(connection), Is.EqualTo(expectedValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[TestCaseSource(nameof(NullPropertyValues))]
|
||||||
public void ConnectionHostnameImported()
|
public void PropertiesWithoutValuesAreIgnored(Func<ConnectionInfo, object> propSelector)
|
||||||
{
|
{
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
var connectionTreeModel = _deserializer.Deserialize(Resources.test_rdcman_v2_7_schema3_empty_values);
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
var importedConnection = connectionTreeModel
|
||||||
var connection = group1.Children.First();
|
.GetRecursiveChildList()
|
||||||
Assert.That(connection.Hostname, Is.EqualTo(ExpectedHostname));
|
.OfType<ContainerInfo>()
|
||||||
|
.First(node => node.Name == "Group1")
|
||||||
|
.Children
|
||||||
|
.First();
|
||||||
|
|
||||||
|
Assert.That(propSelector(importedConnection), Is.EqualTo(propSelector(new ConnectionInfo())));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[TestCaseSource(nameof(NullPropertyValues))]
|
||||||
public void ConnectionDescriptionImported()
|
public void NonExistantPropertiesAreIgnored(Func<ConnectionInfo, object> propSelector)
|
||||||
{
|
{
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
var connectionTreeModel = _deserializer.Deserialize(Resources.test_rdcman_v2_7_schema3_null_values);
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
var importedConnection = connectionTreeModel
|
||||||
var connection = group1.Children.First();
|
.GetRecursiveChildList()
|
||||||
Assert.That(connection.Description, Is.EqualTo(ExpectedDescription));
|
.OfType<ContainerInfo>()
|
||||||
|
.First(node => node.Name == "Group1")
|
||||||
|
.Children
|
||||||
|
.First();
|
||||||
|
|
||||||
|
Assert.That(propSelector(importedConnection), Is.EqualTo(propSelector(new ConnectionInfo())));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ConnectionUsernameImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.Username, Is.EqualTo(ExpectedUsername));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionDomainImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.Domain, Is.EqualTo(ExpectedDomain));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since password is encrypted with a machine key, cant test decryption on another machine
|
|
||||||
//[Test]
|
|
||||||
//public void ConnectionPasswordImported()
|
|
||||||
//{
|
|
||||||
// var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
// var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
// var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
// var connection = group1.Children.First();
|
|
||||||
// Assert.That(connection.Password, Is.EqualTo(ExpectedPassword));
|
|
||||||
//}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionProtocolSetToRdp()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.Protocol, Is.EqualTo(ProtocolType.RDP));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionUseConsoleSessionImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.UseConsoleSession, Is.EqualTo(ExpectedUseConsoleSession));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionPortImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.Port, Is.EqualTo(ExpectedPort));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionGatewayUsageMethodImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.RDGatewayUsageMethod, Is.EqualTo(ExpectedGatewayUsageMethod));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionGatewayHostnameImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.RDGatewayHostname, Is.EqualTo(ExpectedGatewayHostname));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionGatewayUsernameImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.RDGatewayUsername, Is.EqualTo(ExpectedGatewayUsername));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since password is encrypted with a machine key, cant test decryption on another machine
|
|
||||||
//[Test]
|
|
||||||
//public void ConnectionGatewayPasswordImported()
|
|
||||||
//{
|
|
||||||
// var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
// var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
// var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
// var connection = group1.Children.First();
|
|
||||||
// Assert.That(connection.RDGatewayPassword, Is.EqualTo(ExpectedGatewayPassword));
|
|
||||||
//}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionGatewayDomainImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.RDGatewayDomain, Is.EqualTo(ExpectedGatewayDomain));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionResolutionImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.Resolution, Is.EqualTo(ExpectedRdpResolution));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionColorDepthImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.Colors, Is.EqualTo(ExpectedRdpColorDepth));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionAudioRedirectionImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.RedirectSound, Is.EqualTo(ExpectedAudioRedirection));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionKeyRedirectionImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.RedirectKeys, Is.EqualTo(ExpectedKeyRedirection));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionDriveRedirectionImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.RedirectDiskDrives, Is.EqualTo(ExpectedDriveRedirection));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionPortRedirectionImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.RedirectPorts, Is.EqualTo(ExpectedPortRedirection));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionPrinterRedirectionImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.RedirectPrinters, Is.EqualTo(ExpectedPrinterRedirection));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionSmartcardRedirectionImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.RedirectSmartCards, Is.EqualTo(ExpectedSmartcardRedirection));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ConnectionauthenticationLevelImported()
|
|
||||||
{
|
|
||||||
var rootNode = _connectionTreeModel.RootNodes.First();
|
|
||||||
var importedRdcmanRootNode = rootNode.Children.OfType<ContainerInfo>().First();
|
|
||||||
var group1 = importedRdcmanRootNode.Children.OfType<ContainerInfo>().First(node => node.Name == "Group1");
|
|
||||||
var connection = group1.Children.First();
|
|
||||||
Assert.That(connection.RDPAuthenticationLevel, Is.EqualTo(ExpectedAuthLevel));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void ExceptionThrownOnBadSchemaVersion()
|
public void ExceptionThrownOnBadSchemaVersion()
|
||||||
{
|
{
|
||||||
var badFileContents = Resources.test_rdcman_v2_2_badschemaversion;
|
var badFileContents = Resources.test_rdcman_v2_2_badschemaversion;
|
||||||
@@ -322,5 +138,61 @@ namespace mRemoteNGTests.Config.Serializers.MiscSerializers
|
|||||||
var badFileContents = Resources.test_rdcman_noversion;
|
var badFileContents = Resources.test_rdcman_noversion;
|
||||||
Assert.That(() => _deserializer.Deserialize(badFileContents), Throws.TypeOf<FileFormatException>());
|
Assert.That(() => _deserializer.Deserialize(badFileContents), Throws.TypeOf<FileFormatException>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<TestCaseData> ExpectedPropertyValues()
|
||||||
|
{
|
||||||
|
return new[]
|
||||||
|
{
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Name), ExpectedName).SetName(nameof(ConnectionInfo.Name)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Hostname), ExpectedHostname).SetName(nameof(ConnectionInfo.Hostname)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Description), ExpectedDescription).SetName(nameof(ConnectionInfo.Description)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Username), ExpectedUsername).SetName(nameof(ConnectionInfo.Username)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Domain), ExpectedDomain).SetName(nameof(ConnectionInfo.Domain)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Protocol), ProtocolType.RDP).SetName(nameof(ConnectionInfo.Protocol)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.UseConsoleSession), ExpectedUseConsoleSession).SetName(nameof(ConnectionInfo.UseConsoleSession)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Port), ExpectedPort).SetName(nameof(ConnectionInfo.Port)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RDGatewayUsageMethod), ExpectedGatewayUsageMethod).SetName(nameof(ConnectionInfo.RDGatewayUsageMethod)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RDGatewayHostname), ExpectedGatewayHostname).SetName(nameof(ConnectionInfo.RDGatewayHostname)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RDGatewayUsername), ExpectedGatewayUsername).SetName(nameof(ConnectionInfo.RDGatewayUsername)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RDGatewayDomain), ExpectedGatewayDomain).SetName(nameof(ConnectionInfo.RDGatewayDomain)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Resolution), ExpectedRdpResolution).SetName(nameof(ConnectionInfo.Resolution)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Colors), ExpectedRdpColorDepth).SetName(nameof(ConnectionInfo.Colors)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RedirectSound), ExpectedAudioRedirection).SetName(nameof(ConnectionInfo.RedirectSound)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RedirectKeys), ExpectedKeyRedirection).SetName(nameof(ConnectionInfo.RedirectKeys)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RDPAuthenticationLevel), ExpectedAuthLevel).SetName(nameof(ConnectionInfo.RDPAuthenticationLevel)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RedirectSmartCards), ExpectedSmartcardRedirection).SetName(nameof(ConnectionInfo.RedirectSmartCards)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RedirectPrinters), ExpectedPrinterRedirection).SetName(nameof(ConnectionInfo.RedirectPrinters)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RedirectPorts), ExpectedPortRedirection).SetName(nameof(ConnectionInfo.RedirectPorts)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RedirectDiskDrives), ExpectedDriveRedirection).SetName(nameof(ConnectionInfo.RedirectDiskDrives)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<TestCaseData> NullPropertyValues()
|
||||||
|
{
|
||||||
|
return new[]
|
||||||
|
{
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Name)).SetName(nameof(ConnectionInfo.Name)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Hostname)).SetName(nameof(ConnectionInfo.Hostname)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Description)).SetName(nameof(ConnectionInfo.Description)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Username)).SetName(nameof(ConnectionInfo.Username)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Domain)).SetName(nameof(ConnectionInfo.Domain)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Protocol)).SetName(nameof(ConnectionInfo.Protocol)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.UseConsoleSession)).SetName(nameof(ConnectionInfo.UseConsoleSession)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Port)).SetName(nameof(ConnectionInfo.Port)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RDGatewayUsageMethod)).SetName(nameof(ConnectionInfo.RDGatewayUsageMethod)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RDGatewayHostname)).SetName(nameof(ConnectionInfo.RDGatewayHostname)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RDGatewayUsername)).SetName(nameof(ConnectionInfo.RDGatewayUsername)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RDGatewayDomain)).SetName(nameof(ConnectionInfo.RDGatewayDomain)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Resolution)).SetName(nameof(ConnectionInfo.Resolution)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.Colors)).SetName(nameof(ConnectionInfo.Colors)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RedirectSound)).SetName(nameof(ConnectionInfo.RedirectSound)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RedirectKeys)).SetName(nameof(ConnectionInfo.RedirectKeys)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RDPAuthenticationLevel)).SetName(nameof(ConnectionInfo.RDPAuthenticationLevel)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RedirectSmartCards)).SetName(nameof(ConnectionInfo.RedirectSmartCards)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RedirectPrinters)).SetName(nameof(ConnectionInfo.RedirectPrinters)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RedirectPorts)).SetName(nameof(ConnectionInfo.RedirectPorts)),
|
||||||
|
new TestCaseData((Func<ConnectionInfo,object>)(con => con.RedirectDiskDrives)).SetName(nameof(ConnectionInfo.RedirectDiskDrives)),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
52
mRemoteNGTests/Properties/Resources.Designer.cs
generated
52
mRemoteNGTests/Properties/Resources.Designer.cs
generated
@@ -298,6 +298,58 @@ namespace mRemoteNGTests.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?>
|
||||||
|
///<RDCMan programVersion="2.7" schemaVersion="3">
|
||||||
|
/// <file>
|
||||||
|
/// <credentialsProfiles />
|
||||||
|
/// <properties>
|
||||||
|
/// <expanded>True</expanded>
|
||||||
|
/// <name>test_RDCMan_connections</name>
|
||||||
|
/// </properties>
|
||||||
|
/// <smartGroup>
|
||||||
|
/// <properties>
|
||||||
|
/// <expanded>False</expanded>
|
||||||
|
/// <name>AllServers</name>
|
||||||
|
/// </properties>
|
||||||
|
/// <ruleGroup operator="All">
|
||||||
|
/// <rule>
|
||||||
|
/// <property>DisplayName</property>
|
||||||
|
/// <operator>Matches</operator>
|
||||||
|
/// [rest of string was truncated]";.
|
||||||
|
/// </summary>
|
||||||
|
internal static string test_rdcman_v2_7_schema3_empty_values {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("test_rdcman_v2_7_schema3_empty_values", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?>
|
||||||
|
///<RDCMan programVersion="2.7" schemaVersion="3">
|
||||||
|
/// <file>
|
||||||
|
/// <credentialsProfiles />
|
||||||
|
/// <properties>
|
||||||
|
/// <expanded>True</expanded>
|
||||||
|
/// <name>test_RDCMan_connections</name>
|
||||||
|
/// </properties>
|
||||||
|
/// <smartGroup>
|
||||||
|
/// <properties>
|
||||||
|
/// <expanded>False</expanded>
|
||||||
|
/// <name>AllServers</name>
|
||||||
|
/// </properties>
|
||||||
|
/// <ruleGroup operator="All">
|
||||||
|
/// <rule>
|
||||||
|
/// <property>DisplayName</property>
|
||||||
|
/// <operator>Matches</operator>
|
||||||
|
/// [rest of string was truncated]";.
|
||||||
|
/// </summary>
|
||||||
|
internal static string test_rdcman_v2_7_schema3_null_values {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("test_rdcman_v2_7_schema3_null_values", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to screen mode id:i:1
|
/// Looks up a localized string similar to screen mode id:i:1
|
||||||
///use multimon:i:0
|
///use multimon:i:0
|
||||||
|
|||||||
@@ -172,6 +172,12 @@
|
|||||||
<data name="test_rdcman_v2_7_schema3" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="test_rdcman_v2_7_schema3" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Resources\test_RDCMan_v2_7_schema3.rdg;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
<value>..\Resources\test_RDCMan_v2_7_schema3.rdg;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="test_rdcman_v2_7_schema3_empty_values" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Resources\test_rdcman_v2_7_schema3_empty_values.rdg;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||||
|
</data>
|
||||||
|
<data name="test_rdcman_v2_7_schema3_null_values" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Resources\test_rdcman_v2_7_schema3_null_values.rdg;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||||
|
</data>
|
||||||
<data name="test_remotedesktopconnection_rdp" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="test_remotedesktopconnection_rdp" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Resources\test_remotedesktopconnection.rdp;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-16</value>
|
<value>..\Resources\test_remotedesktopconnection.rdp;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-16</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RDCMan programVersion="2.7" schemaVersion="3">
|
||||||
|
<file>
|
||||||
|
<credentialsProfiles />
|
||||||
|
<properties>
|
||||||
|
<expanded>True</expanded>
|
||||||
|
<name>test_RDCMan_connections</name>
|
||||||
|
</properties>
|
||||||
|
<smartGroup>
|
||||||
|
<properties>
|
||||||
|
<expanded>False</expanded>
|
||||||
|
<name>AllServers</name>
|
||||||
|
</properties>
|
||||||
|
<ruleGroup operator="All">
|
||||||
|
<rule>
|
||||||
|
<property>DisplayName</property>
|
||||||
|
<operator>Matches</operator>
|
||||||
|
<value>server</value>
|
||||||
|
</rule>
|
||||||
|
</ruleGroup>
|
||||||
|
</smartGroup>
|
||||||
|
<group>
|
||||||
|
<properties>
|
||||||
|
<expanded>True</expanded>
|
||||||
|
<name>Group1</name>
|
||||||
|
</properties>
|
||||||
|
<server>
|
||||||
|
<properties>
|
||||||
|
<displayName></displayName>
|
||||||
|
<name></name>
|
||||||
|
<comment></comment>
|
||||||
|
</properties>
|
||||||
|
<logonCredentials inherit="None">
|
||||||
|
<profileName scope="Local"></profileName>
|
||||||
|
<userName></userName>
|
||||||
|
<password></password>
|
||||||
|
<domain></domain>
|
||||||
|
</logonCredentials>
|
||||||
|
<connectionSettings inherit="None">
|
||||||
|
<connectToConsole></connectToConsole>
|
||||||
|
<startProgram />
|
||||||
|
<workingDir />
|
||||||
|
<port></port>
|
||||||
|
<loadBalanceInfo />
|
||||||
|
</connectionSettings>
|
||||||
|
<gatewaySettings inherit="None">
|
||||||
|
<enabled></enabled>
|
||||||
|
<hostName></hostName>
|
||||||
|
<logonMethod></logonMethod>
|
||||||
|
<localBypass></localBypass>
|
||||||
|
<credSharing></credSharing>
|
||||||
|
<profileName scope="Local"></profileName>
|
||||||
|
<userName></userName>
|
||||||
|
<password />
|
||||||
|
<domain></domain>
|
||||||
|
</gatewaySettings>
|
||||||
|
<remoteDesktop inherit="None">
|
||||||
|
<sameSizeAsClientArea></sameSizeAsClientArea>
|
||||||
|
<fullScreen></fullScreen>
|
||||||
|
<colorDepth></colorDepth>
|
||||||
|
</remoteDesktop>
|
||||||
|
<localResources inherit="None">
|
||||||
|
<audioRedirection></audioRedirection>
|
||||||
|
<audioRedirectionQuality></audioRedirectionQuality>
|
||||||
|
<audioCaptureRedirection></audioCaptureRedirection>
|
||||||
|
<keyboardHook></keyboardHook>
|
||||||
|
<redirectClipboard></redirectClipboard>
|
||||||
|
<redirectDrives></redirectDrives>
|
||||||
|
<redirectDrivesList>
|
||||||
|
<item></item>
|
||||||
|
<item></item>
|
||||||
|
<item></item>
|
||||||
|
<item></item>
|
||||||
|
<item></item>
|
||||||
|
</redirectDrivesList>
|
||||||
|
<redirectPrinters></redirectPrinters>
|
||||||
|
<redirectPorts></redirectPorts>
|
||||||
|
<redirectSmartCards></redirectSmartCards>
|
||||||
|
<redirectPnpDevices></redirectPnpDevices>
|
||||||
|
</localResources>
|
||||||
|
<displaySettings inherit="None">
|
||||||
|
<thumbnailScale></thumbnailScale>
|
||||||
|
<smartSizeDockedWindows></smartSizeDockedWindows>
|
||||||
|
<smartSizeUndockedWindows></smartSizeUndockedWindows>
|
||||||
|
</displaySettings>
|
||||||
|
<securitySettings inherit="None">
|
||||||
|
<authentication></authentication>
|
||||||
|
</securitySettings>
|
||||||
|
</server>
|
||||||
|
</group>
|
||||||
|
</file>
|
||||||
|
<connected />
|
||||||
|
<favorites />
|
||||||
|
<recentlyUsed />
|
||||||
|
</RDCMan>
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RDCMan programVersion="2.7" schemaVersion="3">
|
||||||
|
<file>
|
||||||
|
<credentialsProfiles />
|
||||||
|
<properties>
|
||||||
|
<expanded>True</expanded>
|
||||||
|
<name>test_RDCMan_connections</name>
|
||||||
|
</properties>
|
||||||
|
<smartGroup>
|
||||||
|
<properties>
|
||||||
|
<expanded>False</expanded>
|
||||||
|
<name>AllServers</name>
|
||||||
|
</properties>
|
||||||
|
<ruleGroup operator="All">
|
||||||
|
<rule>
|
||||||
|
<property>DisplayName</property>
|
||||||
|
<operator>Matches</operator>
|
||||||
|
<value>server</value>
|
||||||
|
</rule>
|
||||||
|
</ruleGroup>
|
||||||
|
</smartGroup>
|
||||||
|
<group>
|
||||||
|
<properties>
|
||||||
|
<expanded>True</expanded>
|
||||||
|
<name>Group1</name>
|
||||||
|
</properties>
|
||||||
|
<server>
|
||||||
|
<properties>
|
||||||
|
</properties>
|
||||||
|
<logonCredentials inherit="None">
|
||||||
|
</logonCredentials>
|
||||||
|
<connectionSettings inherit="None">
|
||||||
|
</connectionSettings>
|
||||||
|
<gatewaySettings inherit="None">
|
||||||
|
</gatewaySettings>
|
||||||
|
<remoteDesktop inherit="None">
|
||||||
|
</remoteDesktop>
|
||||||
|
<localResources inherit="None">
|
||||||
|
</localResources>
|
||||||
|
<displaySettings inherit="None">
|
||||||
|
</displaySettings>
|
||||||
|
<securitySettings inherit="None">
|
||||||
|
</securitySettings>
|
||||||
|
</server>
|
||||||
|
</group>
|
||||||
|
</file>
|
||||||
|
<connected />
|
||||||
|
<favorites />
|
||||||
|
<recentlyUsed />
|
||||||
|
</RDCMan>
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
|
using mRemoteNG.Tools;
|
||||||
|
|
||||||
namespace mRemoteNGTests.TestHelpers
|
namespace mRemoteNGTests.TestHelpers
|
||||||
{
|
{
|
||||||
@@ -18,9 +19,17 @@ namespace mRemoteNGTests.TestHelpers
|
|||||||
File.Delete(file);
|
File.Delete(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string NewTempFilePath()
|
public static void DeleteDirectory(string directory)
|
||||||
|
{
|
||||||
|
if (Directory.Exists(directory))
|
||||||
|
Directory.Delete(directory, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string NewTempFilePath(string extension = "")
|
||||||
{
|
{
|
||||||
var newPath = Path.Combine(GetTestSpecificTempDirectory(), Path.GetRandomFileName());
|
var newPath = Path.Combine(GetTestSpecificTempDirectory(), Path.GetRandomFileName());
|
||||||
|
if (!string.IsNullOrWhiteSpace(extension))
|
||||||
|
newPath = newPath + extension;
|
||||||
var folderPath = Path.GetDirectoryName(newPath);
|
var folderPath = Path.GetDirectoryName(newPath);
|
||||||
if (!Directory.Exists(folderPath))
|
if (!Directory.Exists(folderPath))
|
||||||
Directory.CreateDirectory(folderPath);
|
Directory.CreateDirectory(folderPath);
|
||||||
@@ -35,5 +44,15 @@ namespace mRemoteNGTests.TestHelpers
|
|||||||
{
|
{
|
||||||
return Path.Combine(Path.GetTempPath(), "mRemoteNGTests", Path.GetRandomFileName());
|
return Path.Combine(Path.GetTempPath(), "mRemoteNGTests", Path.GetRandomFileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static DisposableAction DisposableTempFile(out string filePath, string extension = "")
|
||||||
|
{
|
||||||
|
var file = NewTempFilePath(extension);
|
||||||
|
filePath = file;
|
||||||
|
File.AppendAllText(file, "");
|
||||||
|
return new DisposableAction(
|
||||||
|
() => {},
|
||||||
|
() => DeleteDirectory(Path.GetDirectoryName(file)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
42
mRemoteNGTests/Tools/DisposableActionTests.cs
Normal file
42
mRemoteNGTests/Tools/DisposableActionTests.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
using mRemoteNG.Tools;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace mRemoteNGTests.Tools
|
||||||
|
{
|
||||||
|
public class DisposableActionTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void InitializerActionRunsWhenObjectIsCreated()
|
||||||
|
{
|
||||||
|
var initializerRan = false;
|
||||||
|
new DisposableAction(() => initializerRan = true, () => { });
|
||||||
|
|
||||||
|
Assert.That(initializerRan);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void DisposalActionRunsWhenDisposeIsCalled()
|
||||||
|
{
|
||||||
|
var disposeActionRan = false;
|
||||||
|
var action = new DisposableAction(() => {}, () => disposeActionRan = true);
|
||||||
|
|
||||||
|
Assert.That(disposeActionRan, Is.False);
|
||||||
|
action.Dispose();
|
||||||
|
Assert.That(disposeActionRan, Is.True);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void DisposeActionOnlyExecutedOnceWhenCallingDisposeMultipleTimes()
|
||||||
|
{
|
||||||
|
var invokeCount = 0;
|
||||||
|
var action = new DisposableAction(() => { }, () => invokeCount++);
|
||||||
|
|
||||||
|
action.Dispose();
|
||||||
|
action.Dispose();
|
||||||
|
action.Dispose();
|
||||||
|
action.Dispose();
|
||||||
|
action.Dispose();
|
||||||
|
Assert.That(invokeCount, Is.EqualTo(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -108,6 +108,7 @@
|
|||||||
</Otherwise>
|
</Otherwise>
|
||||||
</Choose>
|
</Choose>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="App\ImportTests.cs" />
|
||||||
<Compile Include="App\UpdaterTests.cs" />
|
<Compile Include="App\UpdaterTests.cs" />
|
||||||
<Compile Include="BinaryFileTests.cs" />
|
<Compile Include="BinaryFileTests.cs" />
|
||||||
<Compile Include="Config\Connections\Multiuser\ConnectionsUpdateAvailableEventArgsTests.cs" />
|
<Compile Include="Config\Connections\Multiuser\ConnectionsUpdateAvailableEventArgsTests.cs" />
|
||||||
@@ -175,6 +176,7 @@
|
|||||||
<Compile Include="Security\XmlCryptoProviderBuilderTests.cs" />
|
<Compile Include="Security\XmlCryptoProviderBuilderTests.cs" />
|
||||||
<Compile Include="TestHelpers\FileTestHelpers.cs" />
|
<Compile Include="TestHelpers\FileTestHelpers.cs" />
|
||||||
<Compile Include="TestHelpers\SerializableConnectionInfoAllPropertiesOfType.cs" />
|
<Compile Include="TestHelpers\SerializableConnectionInfoAllPropertiesOfType.cs" />
|
||||||
|
<Compile Include="Tools\DisposableActionTests.cs" />
|
||||||
<Compile Include="Tools\ExternalToolsArgumentParserTests.cs" />
|
<Compile Include="Tools\ExternalToolsArgumentParserTests.cs" />
|
||||||
<Compile Include="Tools\FullyObservableCollectionTests.cs" />
|
<Compile Include="Tools\FullyObservableCollectionTests.cs" />
|
||||||
<Compile Include="Tools\OptionalTests.cs" />
|
<Compile Include="Tools\OptionalTests.cs" />
|
||||||
@@ -265,6 +267,8 @@
|
|||||||
<None Include="Resources\test_rdcman_v2_2_badschemaversion.rdg" />
|
<None Include="Resources\test_rdcman_v2_2_badschemaversion.rdg" />
|
||||||
<None Include="Resources\test_rdcman_v2_2_schema1.rdg" />
|
<None Include="Resources\test_rdcman_v2_2_schema1.rdg" />
|
||||||
<None Include="Resources\test_RDCMan_v2_7_schema3.rdg" />
|
<None Include="Resources\test_RDCMan_v2_7_schema3.rdg" />
|
||||||
|
<None Include="Resources\test_rdcman_v2_7_schema3_empty_values.rdg" />
|
||||||
|
<None Include="Resources\test_rdcman_v2_7_schema3_null_values.rdg" />
|
||||||
<None Include="Resources\test_remotedesktopconnection.rdp" />
|
<None Include="Resources\test_remotedesktopconnection.rdp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using mRemoteNG.Config.Import;
|
using mRemoteNG.Config.Import;
|
||||||
|
using mRemoteNG.Connection;
|
||||||
using mRemoteNG.Connection.Protocol;
|
using mRemoteNG.Connection.Protocol;
|
||||||
using mRemoteNG.Container;
|
using mRemoteNG.Container;
|
||||||
using mRemoteNG.Tools;
|
using mRemoteNG.Tools;
|
||||||
|
|
||||||
namespace mRemoteNG.App
|
namespace mRemoteNG.App
|
||||||
{
|
{
|
||||||
public static class Import
|
public static class Import
|
||||||
{
|
{
|
||||||
public static void ImportFromFile(ContainerInfo importDestinationContainer)
|
public static void ImportFromFile(ContainerInfo importDestinationContainer)
|
||||||
{
|
{
|
||||||
@@ -35,22 +36,12 @@ namespace mRemoteNG.App
|
|||||||
if (openFileDialog.ShowDialog() != DialogResult.OK)
|
if (openFileDialog.ShowDialog() != DialogResult.OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (var fileName in openFileDialog.FileNames)
|
HeadlessFileImport(
|
||||||
{
|
openFileDialog.FileNames,
|
||||||
try
|
importDestinationContainer,
|
||||||
{
|
Runtime.ConnectionsService,
|
||||||
var importer = BuildConnectionImporterFromFileExtension(fileName);
|
fileName => MessageBox.Show(string.Format(Language.strImportFileFailedContent, fileName), Language.strImportFileFailedMainInstruction,
|
||||||
importer.Import(fileName, importDestinationContainer);
|
MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1));
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show(string.Format(Language.strImportFileFailedContent, fileName), Language.strImportFileFailedMainInstruction,
|
|
||||||
MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
|
|
||||||
Runtime.MessageCollector.AddExceptionMessage("Unable to import file.", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Runtime.ConnectionsService.SaveConnectionsAsync();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -59,12 +50,38 @@ namespace mRemoteNG.App
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void HeadlessFileImport(
|
||||||
|
IEnumerable<string> filePaths,
|
||||||
|
ContainerInfo importDestinationContainer,
|
||||||
|
ConnectionsService connectionsService,
|
||||||
|
Action<string> exceptionAction = null)
|
||||||
|
{
|
||||||
|
using (connectionsService.BatchedSavingContext())
|
||||||
|
{
|
||||||
|
foreach (var fileName in filePaths)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var importer = BuildConnectionImporterFromFileExtension(fileName);
|
||||||
|
importer.Import(fileName, importDestinationContainer);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
exceptionAction?.Invoke(fileName);
|
||||||
|
Runtime.MessageCollector.AddExceptionMessage($"Error occurred while importing file '{fileName}'.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void ImportFromActiveDirectory(string ldapPath, ContainerInfo importDestinationContainer, bool importSubOu)
|
public static void ImportFromActiveDirectory(string ldapPath, ContainerInfo importDestinationContainer, bool importSubOu)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ActiveDirectoryImporter.Import(ldapPath, importDestinationContainer, importSubOu);
|
using (Runtime.ConnectionsService.BatchedSavingContext())
|
||||||
Runtime.ConnectionsService.SaveConnectionsAsync();
|
{
|
||||||
|
ActiveDirectoryImporter.Import(ldapPath, importDestinationContainer, importSubOu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -76,9 +93,11 @@ namespace mRemoteNG.App
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var importer = new PortScanImporter(protocol);
|
using (Runtime.ConnectionsService.BatchedSavingContext())
|
||||||
importer.Import(hosts, importDestinationContainer);
|
{
|
||||||
Runtime.ConnectionsService.SaveConnectionsAsync();
|
var importer = new PortScanImporter(protocol);
|
||||||
|
importer.Import(hosts, importDestinationContainer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security;
|
||||||
using mRemoteNG.Config.DatabaseConnectors;
|
using mRemoteNG.Config.DatabaseConnectors;
|
||||||
using mRemoteNG.Config.DataProviders;
|
using mRemoteNG.Config.DataProviders;
|
||||||
using mRemoteNG.Config.Serializers;
|
using mRemoteNG.Config.Serializers;
|
||||||
using mRemoteNG.Config.Serializers.MsSql;
|
using mRemoteNG.Config.Serializers.MsSql;
|
||||||
using mRemoteNG.Config.Serializers.Versioning;
|
using mRemoteNG.Config.Serializers.Versioning;
|
||||||
using mRemoteNG.Container;
|
using mRemoteNG.Container;
|
||||||
using mRemoteNG.Tools;
|
|
||||||
using mRemoteNG.Tree;
|
|
||||||
using mRemoteNG.Tree.Root;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Security;
|
|
||||||
using mRemoteNG.Security;
|
using mRemoteNG.Security;
|
||||||
using mRemoteNG.Security.Authentication;
|
using mRemoteNG.Security.Authentication;
|
||||||
using mRemoteNG.Security.SymmetricEncryption;
|
using mRemoteNG.Security.SymmetricEncryption;
|
||||||
|
using mRemoteNG.Tools;
|
||||||
|
using mRemoteNG.Tree;
|
||||||
|
using mRemoteNG.Tree.Root;
|
||||||
|
|
||||||
namespace mRemoteNG.Config.Connections
|
namespace mRemoteNG.Config.Connections
|
||||||
{
|
{
|
||||||
public class SqlConnectionsLoader : IConnectionsLoader
|
public class SqlConnectionsLoader : IConnectionsLoader
|
||||||
{
|
{
|
||||||
private readonly IDeserializer<string, IEnumerable<LocalConnectionPropertiesModel>> _localConnectionPropertiesDeserializer;
|
private readonly IDeserializer<string, IEnumerable<LocalConnectionPropertiesModel>> _localConnectionPropertiesDeserializer;
|
||||||
private readonly IDataProvider<string> _dataProvider;
|
private readonly IDataProvider<string> _dataProvider;
|
||||||
@@ -41,7 +41,8 @@ namespace mRemoteNG.Config.Connections
|
|||||||
var databaseVersionVerifier = new SqlDatabaseVersionVerifier(connector);
|
var databaseVersionVerifier = new SqlDatabaseVersionVerifier(connector);
|
||||||
var cryptoProvider = new LegacyRijndaelCryptographyProvider();
|
var cryptoProvider = new LegacyRijndaelCryptographyProvider();
|
||||||
|
|
||||||
var metaData = metaDataRetriever.GetDatabaseMetaData(connector);
|
var metaData = metaDataRetriever.GetDatabaseMetaData(connector) ??
|
||||||
|
HandleFirstRun(metaDataRetriever, connector);
|
||||||
var decryptionKey = GetDecryptionKey(metaData);
|
var decryptionKey = GetDecryptionKey(metaData);
|
||||||
|
|
||||||
if (!decryptionKey.Any())
|
if (!decryptionKey.Any())
|
||||||
@@ -85,5 +86,11 @@ namespace mRemoteNG.Config.Connections
|
|||||||
container.IsExpanded = x.LocalProperties.Expanded;
|
container.IsExpanded = x.LocalProperties.Expanded;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SqlConnectionListMetaData HandleFirstRun(SqlDatabaseMetaDataRetriever metaDataRetriever, SqlDatabaseConnector connector)
|
||||||
|
{
|
||||||
|
metaDataRetriever.WriteDatabaseMetaData(new RootNodeInfo(RootNodeType.Connection), connector);
|
||||||
|
return metaDataRetriever.GetDatabaseMetaData(connector);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,16 @@
|
|||||||
using mRemoteNG.App;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using mRemoteNG.App;
|
||||||
using mRemoteNG.App.Info;
|
using mRemoteNG.App.Info;
|
||||||
using mRemoteNG.Config.DatabaseConnectors;
|
using mRemoteNG.Config.DatabaseConnectors;
|
||||||
using mRemoteNG.Config.DataProviders;
|
using mRemoteNG.Config.DataProviders;
|
||||||
using mRemoteNG.Config.Serializers;
|
using mRemoteNG.Config.Serializers;
|
||||||
using mRemoteNG.Config.Serializers.MsSql;
|
using mRemoteNG.Config.Serializers.MsSql;
|
||||||
using mRemoteNG.Config.Serializers.Versioning;
|
using mRemoteNG.Config.Serializers.Versioning;
|
||||||
|
using mRemoteNG.Connection;
|
||||||
using mRemoteNG.Container;
|
using mRemoteNG.Container;
|
||||||
using mRemoteNG.Messages;
|
using mRemoteNG.Messages;
|
||||||
using mRemoteNG.Security;
|
using mRemoteNG.Security;
|
||||||
@@ -12,19 +18,11 @@ using mRemoteNG.Security.SymmetricEncryption;
|
|||||||
using mRemoteNG.Tools;
|
using mRemoteNG.Tools;
|
||||||
using mRemoteNG.Tree;
|
using mRemoteNG.Tree;
|
||||||
using mRemoteNG.Tree.Root;
|
using mRemoteNG.Tree.Root;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Data.SqlClient;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Security;
|
|
||||||
using mRemoteNG.Connection;
|
|
||||||
|
|
||||||
namespace mRemoteNG.Config.Connections
|
namespace mRemoteNG.Config.Connections
|
||||||
{
|
{
|
||||||
public class SqlConnectionsSaver : ISaver<ConnectionTreeModel>
|
public class SqlConnectionsSaver : ISaver<ConnectionTreeModel>
|
||||||
{
|
{
|
||||||
private SecureString _password = Runtime.EncryptionKey;
|
|
||||||
private readonly SaveFilter _saveFilter;
|
private readonly SaveFilter _saveFilter;
|
||||||
private readonly ISerializer<IEnumerable<LocalConnectionPropertiesModel>, string> _localPropertiesSerializer;
|
private readonly ISerializer<IEnumerable<LocalConnectionPropertiesModel>, string> _localPropertiesSerializer;
|
||||||
private readonly IDataProvider<string> _dataProvider;
|
private readonly IDataProvider<string> _dataProvider;
|
||||||
@@ -73,7 +71,7 @@ namespace mRemoteNG.Config.Connections
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateRootNodeTable(rootTreeNode, sqlConnector);
|
metaDataRetriever.WriteDatabaseMetaData(rootTreeNode, sqlConnector);
|
||||||
UpdateConnectionsTable(rootTreeNode, sqlConnector);
|
UpdateConnectionsTable(rootTreeNode, sqlConnector);
|
||||||
UpdateUpdatesTable(sqlConnector);
|
UpdateUpdatesTable(sqlConnector);
|
||||||
}
|
}
|
||||||
@@ -117,17 +115,17 @@ namespace mRemoteNG.Config.Connections
|
|||||||
{
|
{
|
||||||
if (rootTreeNode.Password)
|
if (rootTreeNode.Password)
|
||||||
{
|
{
|
||||||
_password = rootTreeNode.PasswordString.ConvertToSecureString();
|
var password = rootTreeNode.PasswordString.ConvertToSecureString();
|
||||||
strProtected = cryptographyProvider.Encrypt("ThisIsProtected", _password);
|
strProtected = cryptographyProvider.Encrypt("ThisIsProtected", password);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _password);
|
strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", Runtime.EncryptionKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _password);
|
strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", Runtime.EncryptionKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
var sqlQuery = new SqlCommand("DELETE FROM tblRoot", sqlDatabaseConnector.SqlConnection);
|
var sqlQuery = new SqlCommand("DELETE FROM tblRoot", sqlDatabaseConnector.SqlConnection);
|
||||||
|
|||||||
@@ -266,8 +266,8 @@ namespace mRemoteNG.Config.Serializers.MsSql
|
|||||||
dataRow["RDGatewayUsageMethod"] = connectionInfo.RDGatewayUsageMethod;
|
dataRow["RDGatewayUsageMethod"] = connectionInfo.RDGatewayUsageMethod;
|
||||||
dataRow["RDGatewayHostname"] = connectionInfo.RDGatewayHostname;
|
dataRow["RDGatewayHostname"] = connectionInfo.RDGatewayHostname;
|
||||||
dataRow["RDGatewayUseConnectionCredentials"] = connectionInfo.RDGatewayUseConnectionCredentials;
|
dataRow["RDGatewayUseConnectionCredentials"] = connectionInfo.RDGatewayUseConnectionCredentials;
|
||||||
dataRow["RDGatewayUsername"] = _cryptographyProvider.Encrypt(connectionInfo.RDGatewayUsername, _encryptionKey);
|
dataRow["RDGatewayUsername"] = connectionInfo.RDGatewayUsername;
|
||||||
dataRow["RDGatewayPassword"] = connectionInfo.RDGatewayPassword;
|
dataRow["RDGatewayPassword"] = _cryptographyProvider.Encrypt(connectionInfo.RDGatewayPassword, _encryptionKey);
|
||||||
dataRow["RDGatewayDomain"] = connectionInfo.RDGatewayDomain;
|
dataRow["RDGatewayDomain"] = connectionInfo.RDGatewayDomain;
|
||||||
if (_saveFilter.SaveInheritance)
|
if (_saveFilter.SaveInheritance)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,12 +2,17 @@
|
|||||||
using System.Data.SqlClient;
|
using System.Data.SqlClient;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using mRemoteNG.App;
|
using mRemoteNG.App;
|
||||||
|
using mRemoteNG.App.Info;
|
||||||
using mRemoteNG.Config.DatabaseConnectors;
|
using mRemoteNG.Config.DatabaseConnectors;
|
||||||
using mRemoteNG.Messages;
|
using mRemoteNG.Messages;
|
||||||
|
using mRemoteNG.Security;
|
||||||
|
using mRemoteNG.Security.SymmetricEncryption;
|
||||||
|
using mRemoteNG.Tools;
|
||||||
|
using mRemoteNG.Tree.Root;
|
||||||
|
|
||||||
namespace mRemoteNG.Config.Serializers.MsSql
|
namespace mRemoteNG.Config.Serializers.MsSql
|
||||||
{
|
{
|
||||||
public class SqlDatabaseMetaDataRetriever
|
public class SqlDatabaseMetaDataRetriever
|
||||||
{
|
{
|
||||||
public SqlConnectionListMetaData GetDatabaseMetaData(SqlDatabaseConnector sqlDatabaseConnector)
|
public SqlConnectionListMetaData GetDatabaseMetaData(SqlDatabaseConnector sqlDatabaseConnector)
|
||||||
{
|
{
|
||||||
@@ -44,5 +49,45 @@ namespace mRemoteNG.Config.Serializers.MsSql
|
|||||||
}
|
}
|
||||||
return metaData;
|
return metaData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void WriteDatabaseMetaData(RootNodeInfo rootTreeNode, SqlDatabaseConnector sqlDatabaseConnector)
|
||||||
|
{
|
||||||
|
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
|
||||||
|
string strProtected;
|
||||||
|
if (rootTreeNode != null)
|
||||||
|
{
|
||||||
|
if (rootTreeNode.Password)
|
||||||
|
{
|
||||||
|
var password = rootTreeNode.PasswordString.ConvertToSecureString();
|
||||||
|
strProtected = cryptographyProvider.Encrypt("ThisIsProtected", password);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", Runtime.EncryptionKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", Runtime.EncryptionKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
var sqlQuery = new SqlCommand("DELETE FROM tblRoot", sqlDatabaseConnector.SqlConnection);
|
||||||
|
sqlQuery.ExecuteNonQuery();
|
||||||
|
|
||||||
|
if (rootTreeNode != null)
|
||||||
|
{
|
||||||
|
sqlQuery =
|
||||||
|
new SqlCommand(
|
||||||
|
"INSERT INTO tblRoot (Name, Export, Protected, ConfVersion) VALUES(\'" +
|
||||||
|
MiscTools.PrepareValueForDB(rootTreeNode.Name) + "\', 0, \'" + strProtected + "\'," +
|
||||||
|
ConnectionsFileInfo.ConnectionFileVersion.ToString(CultureInfo.InvariantCulture) + ")",
|
||||||
|
sqlDatabaseConnector.SqlConnection);
|
||||||
|
sqlQuery.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, $"UpdateRootNodeTable: rootTreeNode was null. Could not insert!");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,7 @@ using mRemoteNG.Tree.Root;
|
|||||||
|
|
||||||
namespace mRemoteNG.Config.Serializers
|
namespace mRemoteNG.Config.Serializers
|
||||||
{
|
{
|
||||||
public class RemoteDesktopConnectionManagerDeserializer : IDeserializer<string, ConnectionTreeModel>
|
public class RemoteDesktopConnectionManagerDeserializer : IDeserializer<string, ConnectionTreeModel>
|
||||||
{
|
{
|
||||||
private static int _schemaVersion; /* 1 = RDCMan v2.2
|
private static int _schemaVersion; /* 1 = RDCMan v2.2
|
||||||
3 = RDCMan v2.7 */
|
3 = RDCMan v2.7 */
|
||||||
@@ -40,11 +40,15 @@ namespace mRemoteNG.Config.Serializers
|
|||||||
|
|
||||||
private static void VerifySchemaVersion(XmlNode rdcManNode)
|
private static void VerifySchemaVersion(XmlNode rdcManNode)
|
||||||
{
|
{
|
||||||
_schemaVersion = Convert.ToInt32(rdcManNode?.Attributes?["schemaVersion"].Value);
|
if (!int.TryParse(rdcManNode?.Attributes?["schemaVersion"]?.Value, out var version))
|
||||||
if (_schemaVersion != 1 && _schemaVersion != 3)
|
throw new FileFormatException("Could not find schema version attribute.");
|
||||||
|
|
||||||
|
if (version != 1 && version != 3)
|
||||||
{
|
{
|
||||||
throw (new FileFormatException($"Unsupported schema version ({_schemaVersion})."));
|
throw new FileFormatException($"Unsupported schema version ({version}).");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_schemaVersion = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void VerifyFileVersion(XmlNode rdcManNode)
|
private static void VerifyFileVersion(XmlNode rdcManNode)
|
||||||
@@ -114,7 +118,8 @@ namespace mRemoteNG.Config.Serializers
|
|||||||
containerPropertiesNode = containerPropertiesNode.SelectSingleNode("./properties");
|
containerPropertiesNode = containerPropertiesNode.SelectSingleNode("./properties");
|
||||||
}
|
}
|
||||||
newContainer.Name = containerPropertiesNode?.SelectSingleNode("./name")?.InnerText ?? Language.strNewFolder;
|
newContainer.Name = containerPropertiesNode?.SelectSingleNode("./name")?.InnerText ?? Language.strNewFolder;
|
||||||
newContainer.IsExpanded = bool.Parse(containerPropertiesNode?.SelectSingleNode("./expanded")?.InnerText ?? "false");
|
if (bool.TryParse(containerPropertiesNode?.SelectSingleNode("./expanded")?.InnerText, out var expanded))
|
||||||
|
newContainer.IsExpanded = expanded;
|
||||||
parentContainer.AddChild(newContainer);
|
parentContainer.AddChild(newContainer);
|
||||||
return newContainer;
|
return newContainer;
|
||||||
}
|
}
|
||||||
@@ -129,17 +134,25 @@ namespace mRemoteNG.Config.Serializers
|
|||||||
{
|
{
|
||||||
var connectionInfo = new ConnectionInfo {Protocol = ProtocolType.RDP};
|
var connectionInfo = new ConnectionInfo {Protocol = ProtocolType.RDP};
|
||||||
|
|
||||||
|
|
||||||
var propertiesNode = xmlNode.SelectSingleNode("./properties");
|
var propertiesNode = xmlNode.SelectSingleNode("./properties");
|
||||||
if (_schemaVersion == 1) propertiesNode = xmlNode; // Version 2.2 defines the container name at the root instead
|
if (_schemaVersion == 1)
|
||||||
|
propertiesNode = xmlNode; // Version 2.2 defines the container name at the root instead
|
||||||
|
|
||||||
connectionInfo.Hostname = propertiesNode?.SelectSingleNode("./name")?.InnerText ?? "";
|
connectionInfo.Hostname = propertiesNode?.SelectSingleNode("./name")?.InnerText ?? "";
|
||||||
connectionInfo.Name = propertiesNode?.SelectSingleNode("./displayName")?.InnerText ?? connectionInfo.Hostname;
|
|
||||||
|
var connectionDisplayName = propertiesNode?.SelectSingleNode("./displayName")?.InnerText;
|
||||||
|
connectionInfo.Name = !string.IsNullOrWhiteSpace(connectionDisplayName)
|
||||||
|
? connectionDisplayName
|
||||||
|
: string.IsNullOrWhiteSpace(connectionInfo.Hostname)
|
||||||
|
? connectionInfo.Name
|
||||||
|
: connectionInfo.Hostname;
|
||||||
|
|
||||||
connectionInfo.Description = propertiesNode?.SelectSingleNode("./comment")?.InnerText ?? string.Empty;
|
connectionInfo.Description = propertiesNode?.SelectSingleNode("./comment")?.InnerText ?? string.Empty;
|
||||||
|
|
||||||
var logonCredentialsNode = xmlNode.SelectSingleNode("./logonCredentials");
|
var logonCredentialsNode = xmlNode.SelectSingleNode("./logonCredentials");
|
||||||
if (logonCredentialsNode?.Attributes?["inherit"]?.Value == "None")
|
if (logonCredentialsNode?.Attributes?["inherit"]?.Value == "None")
|
||||||
{
|
{
|
||||||
connectionInfo.Username = logonCredentialsNode.SelectSingleNode("userName")?.InnerText;
|
connectionInfo.Username = logonCredentialsNode.SelectSingleNode("userName")?.InnerText ?? string.Empty;
|
||||||
|
|
||||||
var passwordNode = logonCredentialsNode.SelectSingleNode("./password");
|
var passwordNode = logonCredentialsNode.SelectSingleNode("./password");
|
||||||
if (_schemaVersion == 1) // Version 2.2 allows clear text passwords
|
if (_schemaVersion == 1) // Version 2.2 allows clear text passwords
|
||||||
@@ -153,7 +166,7 @@ namespace mRemoteNG.Config.Serializers
|
|||||||
connectionInfo.Password = DecryptRdcManPassword(passwordNode?.InnerText);
|
connectionInfo.Password = DecryptRdcManPassword(passwordNode?.InnerText);
|
||||||
}
|
}
|
||||||
|
|
||||||
connectionInfo.Domain = logonCredentialsNode.SelectSingleNode("./domain")?.InnerText;
|
connectionInfo.Domain = logonCredentialsNode.SelectSingleNode("./domain")?.InnerText ?? string.Empty;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -165,10 +178,12 @@ namespace mRemoteNG.Config.Serializers
|
|||||||
var connectionSettingsNode = xmlNode.SelectSingleNode("./connectionSettings");
|
var connectionSettingsNode = xmlNode.SelectSingleNode("./connectionSettings");
|
||||||
if (connectionSettingsNode?.Attributes?["inherit"]?.Value == "None")
|
if (connectionSettingsNode?.Attributes?["inherit"]?.Value == "None")
|
||||||
{
|
{
|
||||||
connectionInfo.UseConsoleSession = bool.Parse(connectionSettingsNode.SelectSingleNode("./connectToConsole")?.InnerText ?? "false");
|
if (bool.TryParse(connectionSettingsNode.SelectSingleNode("./connectToConsole")?.InnerText, out var useConsole))
|
||||||
|
connectionInfo.UseConsoleSession = useConsole;
|
||||||
// ./startProgram
|
// ./startProgram
|
||||||
// ./workingDir
|
// ./workingDir
|
||||||
connectionInfo.Port = Convert.ToInt32(connectionSettingsNode.SelectSingleNode("./port")?.InnerText);
|
if (int.TryParse(connectionSettingsNode.SelectSingleNode("./port")?.InnerText, out var port))
|
||||||
|
connectionInfo.Port = port;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -179,14 +194,18 @@ namespace mRemoteNG.Config.Serializers
|
|||||||
var gatewaySettingsNode = xmlNode.SelectSingleNode("./gatewaySettings");
|
var gatewaySettingsNode = xmlNode.SelectSingleNode("./gatewaySettings");
|
||||||
if (gatewaySettingsNode?.Attributes?["inherit"]?.Value == "None")
|
if (gatewaySettingsNode?.Attributes?["inherit"]?.Value == "None")
|
||||||
{
|
{
|
||||||
connectionInfo.RDGatewayUsageMethod = gatewaySettingsNode.SelectSingleNode("./enabled")?.InnerText == "True" ? RdpProtocol.RDGatewayUsageMethod.Always : RdpProtocol.RDGatewayUsageMethod.Never;
|
connectionInfo.RDGatewayUsageMethod = gatewaySettingsNode.SelectSingleNode("./enabled")?.InnerText == "True"
|
||||||
connectionInfo.RDGatewayHostname = gatewaySettingsNode.SelectSingleNode("./hostName")?.InnerText;
|
? RdpProtocol.RDGatewayUsageMethod.Always
|
||||||
connectionInfo.RDGatewayUsername = gatewaySettingsNode.SelectSingleNode("./userName")?.InnerText;
|
: RdpProtocol.RDGatewayUsageMethod.Never;
|
||||||
|
connectionInfo.RDGatewayHostname = gatewaySettingsNode.SelectSingleNode("./hostName")?.InnerText ?? string.Empty;
|
||||||
|
connectionInfo.RDGatewayUsername = gatewaySettingsNode.SelectSingleNode("./userName")?.InnerText ?? string.Empty;
|
||||||
|
|
||||||
var passwordNode = gatewaySettingsNode.SelectSingleNode("./password");
|
var passwordNode = gatewaySettingsNode.SelectSingleNode("./password");
|
||||||
connectionInfo.RDGatewayPassword = passwordNode?.Attributes?["storeAsClearText"]?.Value == "True" ? passwordNode.InnerText : DecryptRdcManPassword(passwordNode?.InnerText);
|
connectionInfo.RDGatewayPassword = passwordNode?.Attributes?["storeAsClearText"]?.Value == "True"
|
||||||
|
? passwordNode.InnerText
|
||||||
|
: DecryptRdcManPassword(passwordNode?.InnerText);
|
||||||
|
|
||||||
connectionInfo.RDGatewayDomain = gatewaySettingsNode.SelectSingleNode("./domain")?.InnerText;
|
connectionInfo.RDGatewayDomain = gatewaySettingsNode.SelectSingleNode("./domain")?.InnerText ?? string.Empty;
|
||||||
// ./logonMethod
|
// ./logonMethod
|
||||||
// ./localBypass
|
// ./localBypass
|
||||||
// ./credSharing
|
// ./credSharing
|
||||||
@@ -203,15 +222,10 @@ namespace mRemoteNG.Config.Serializers
|
|||||||
var remoteDesktopNode = xmlNode.SelectSingleNode("./remoteDesktop");
|
var remoteDesktopNode = xmlNode.SelectSingleNode("./remoteDesktop");
|
||||||
if (remoteDesktopNode?.Attributes?["inherit"]?.Value == "None")
|
if (remoteDesktopNode?.Attributes?["inherit"]?.Value == "None")
|
||||||
{
|
{
|
||||||
var resolutionString = remoteDesktopNode.SelectSingleNode("./size")?.InnerText.Replace(" ", "");
|
connectionInfo.Resolution =
|
||||||
try
|
Enum.TryParse<RdpProtocol.RDPResolutions>(remoteDesktopNode.SelectSingleNode("./size")?.InnerText.Replace(" ", ""), true, out var rdpResolution)
|
||||||
{
|
? rdpResolution
|
||||||
connectionInfo.Resolution = (RdpProtocol.RDPResolutions)Enum.Parse(typeof(RdpProtocol.RDPResolutions), "Res" + resolutionString);
|
: RdpProtocol.RDPResolutions.FitToWindow;
|
||||||
}
|
|
||||||
catch (ArgumentException)
|
|
||||||
{
|
|
||||||
connectionInfo.Resolution = RdpProtocol.RDPResolutions.FitToWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remoteDesktopNode.SelectSingleNode("./sameSizeAsClientArea")?.InnerText == "True")
|
if (remoteDesktopNode.SelectSingleNode("./sameSizeAsClientArea")?.InnerText == "True")
|
||||||
{
|
{
|
||||||
@@ -223,9 +237,8 @@ namespace mRemoteNG.Config.Serializers
|
|||||||
connectionInfo.Resolution = RdpProtocol.RDPResolutions.Fullscreen;
|
connectionInfo.Resolution = RdpProtocol.RDPResolutions.Fullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
var colorDepth = remoteDesktopNode.SelectSingleNode("./colorDepth")?.InnerText;
|
if (Enum.TryParse<RdpProtocol.RDPColors>(remoteDesktopNode.SelectSingleNode("./colorDepth")?.InnerText, true, out var rdpColors))
|
||||||
if (colorDepth != null)
|
connectionInfo.Colors = rdpColors;
|
||||||
connectionInfo.Colors = (RdpProtocol.RDPColors)Enum.Parse(typeof(RdpProtocol.RDPColors), colorDepth);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -274,10 +287,17 @@ namespace mRemoteNG.Config.Serializers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ./redirectClipboard
|
// ./redirectClipboard
|
||||||
connectionInfo.RedirectDiskDrives = bool.Parse(localResourcesNode?.SelectSingleNode("./redirectDrives")?.InnerText ?? "false");
|
if (bool.TryParse(localResourcesNode?.SelectSingleNode("./redirectDrives")?.InnerText, out var redirectDisks))
|
||||||
connectionInfo.RedirectPorts = bool.Parse(localResourcesNode?.SelectSingleNode("./redirectPorts")?.InnerText ?? "false");
|
connectionInfo.RedirectDiskDrives = redirectDisks;
|
||||||
connectionInfo.RedirectPrinters = bool.Parse(localResourcesNode?.SelectSingleNode("./redirectPrinters")?.InnerText ?? "false");
|
|
||||||
connectionInfo.RedirectSmartCards = bool.Parse(localResourcesNode?.SelectSingleNode("./redirectSmartCards")?.InnerText ?? "false");
|
if (bool.TryParse(localResourcesNode?.SelectSingleNode("./redirectPorts")?.InnerText, out var redirectPorts))
|
||||||
|
connectionInfo.RedirectPorts = redirectPorts;
|
||||||
|
|
||||||
|
if (bool.TryParse(localResourcesNode?.SelectSingleNode("./redirectPrinters")?.InnerText, out var redirectPrinters))
|
||||||
|
connectionInfo.RedirectPrinters = redirectPrinters;
|
||||||
|
|
||||||
|
if (bool.TryParse(localResourcesNode?.SelectSingleNode("./redirectSmartCards")?.InnerText, out var redirectSmartCards))
|
||||||
|
connectionInfo.RedirectSmartCards = redirectSmartCards;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
using mRemoteNG.App;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using mRemoteNG.App;
|
||||||
using mRemoteNG.App.Info;
|
using mRemoteNG.App.Info;
|
||||||
|
using mRemoteNG.Config;
|
||||||
using mRemoteNG.Config.Connections;
|
using mRemoteNG.Config.Connections;
|
||||||
using mRemoteNG.Config.Connections.Multiuser;
|
using mRemoteNG.Config.Connections.Multiuser;
|
||||||
using mRemoteNG.Config.DataProviders;
|
using mRemoteNG.Config.DataProviders;
|
||||||
@@ -12,15 +17,10 @@ using mRemoteNG.Tools;
|
|||||||
using mRemoteNG.Tree;
|
using mRemoteNG.Tree;
|
||||||
using mRemoteNG.Tree.Root;
|
using mRemoteNG.Tree.Root;
|
||||||
using mRemoteNG.UI;
|
using mRemoteNG.UI;
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
using mRemoteNG.Config;
|
|
||||||
|
|
||||||
namespace mRemoteNG.Connection
|
namespace mRemoteNG.Connection
|
||||||
{
|
{
|
||||||
public class ConnectionsService
|
public class ConnectionsService
|
||||||
{
|
{
|
||||||
private static readonly object SaveLock = new object();
|
private static readonly object SaveLock = new object();
|
||||||
private readonly PuttySessionsManager _puttySessionsManager;
|
private readonly PuttySessionsManager _puttySessionsManager;
|
||||||
@@ -171,6 +171,19 @@ namespace mRemoteNG.Connection
|
|||||||
SaveConnections();
|
SaveConnections();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// All calls to <see cref="SaveConnections()"/> or <see cref="SaveConnectionsAsync"/>
|
||||||
|
/// will be deferred until the returned <see cref="DisposableAction"/> is disposed.
|
||||||
|
/// Once disposed, this will immediately executes a single <see cref="SaveConnections()"/>
|
||||||
|
/// or <see cref="SaveConnectionsAsync"/> if one has been requested.
|
||||||
|
/// Place this call in a 'using' block to represent a batched saving context.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public DisposableAction BatchedSavingContext()
|
||||||
|
{
|
||||||
|
return new DisposableAction(BeginBatchingSaves, EndBatchingSaves);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves the currently loaded <see cref="ConnectionTreeModel"/> with
|
/// Saves the currently loaded <see cref="ConnectionTreeModel"/> with
|
||||||
/// no <see cref="SaveFilter"/>.
|
/// no <see cref="SaveFilter"/>.
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ using mRemoteNG.Tools.Cmdline;
|
|||||||
namespace mRemoteNG.Connection.Protocol
|
namespace mRemoteNG.Connection.Protocol
|
||||||
{
|
{
|
||||||
public class PuttyBase : ProtocolBase
|
public class PuttyBase : ProtocolBase
|
||||||
{
|
{
|
||||||
private const int IDM_RECONF = 0x50; // PuTTY Settings Menu ID
|
private const int IDM_RECONF = 0x50; // PuTTY Settings Menu ID
|
||||||
private bool _isPuttyNg;
|
private bool _isPuttyNg;
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ namespace mRemoteNG.Connection.Protocol
|
|||||||
Event_Closed(this);
|
Event_Closed(this);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Public Methods
|
#region Public Methods
|
||||||
public override bool Connect()
|
public override bool Connect()
|
||||||
{
|
{
|
||||||
@@ -62,11 +62,11 @@ namespace mRemoteNG.Connection.Protocol
|
|||||||
var arguments = new CommandLineArguments {EscapeForShell = false};
|
var arguments = new CommandLineArguments {EscapeForShell = false};
|
||||||
|
|
||||||
arguments.Add("-load", InterfaceControl.Info.PuttySession);
|
arguments.Add("-load", InterfaceControl.Info.PuttySession);
|
||||||
|
|
||||||
if (!(InterfaceControl.Info is PuttySessionInfo))
|
if (!(InterfaceControl.Info is PuttySessionInfo))
|
||||||
{
|
{
|
||||||
arguments.Add("-" + PuttyProtocol);
|
arguments.Add("-" + PuttyProtocol);
|
||||||
|
|
||||||
if (PuttyProtocol == Putty_Protocol.ssh)
|
if (PuttyProtocol == Putty_Protocol.ssh)
|
||||||
{
|
{
|
||||||
var username = "";
|
var username = "";
|
||||||
@@ -89,7 +89,7 @@ namespace mRemoteNG.Connection.Protocol
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(InterfaceControl.Info?.Password))
|
if (!string.IsNullOrEmpty(InterfaceControl.Info?.Password))
|
||||||
{
|
{
|
||||||
password = InterfaceControl.Info.Password;
|
password = InterfaceControl.Info.Password;
|
||||||
@@ -102,9 +102,9 @@ namespace mRemoteNG.Connection.Protocol
|
|||||||
password = cryptographyProvider.Decrypt(Settings.Default.DefaultPassword, Runtime.EncryptionKey);
|
password = cryptographyProvider.Decrypt(Settings.Default.DefaultPassword, Runtime.EncryptionKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
arguments.Add("-" + (int)PuttySSHVersion);
|
arguments.Add("-" + (int)PuttySSHVersion);
|
||||||
|
|
||||||
if (((int)Force & (int)ConnectionInfo.Force.NoCredentials) != (int)ConnectionInfo.Force.NoCredentials)
|
if (((int)Force & (int)ConnectionInfo.Force.NoCredentials) != (int)ConnectionInfo.Force.NoCredentials)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(username))
|
if (!string.IsNullOrEmpty(username))
|
||||||
@@ -117,24 +117,24 @@ namespace mRemoteNG.Connection.Protocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
arguments.Add("-P", InterfaceControl.Info.Port.ToString());
|
arguments.Add("-P", InterfaceControl.Info.Port.ToString());
|
||||||
arguments.Add(InterfaceControl.Info.Hostname);
|
arguments.Add(InterfaceControl.Info.Hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_isPuttyNg)
|
if (_isPuttyNg)
|
||||||
{
|
{
|
||||||
arguments.Add("-hwndparent", InterfaceControl.Handle.ToString());
|
arguments.Add("-hwndparent", InterfaceControl.Handle.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
PuttyProcess.StartInfo.Arguments = arguments.ToString();
|
PuttyProcess.StartInfo.Arguments = arguments.ToString();
|
||||||
|
|
||||||
PuttyProcess.EnableRaisingEvents = true;
|
PuttyProcess.EnableRaisingEvents = true;
|
||||||
PuttyProcess.Exited += ProcessExited;
|
PuttyProcess.Exited += ProcessExited;
|
||||||
|
|
||||||
PuttyProcess.Start();
|
PuttyProcess.Start();
|
||||||
PuttyProcess.WaitForInputIdle(Settings.Default.MaxPuttyWaitTime * 1000);
|
PuttyProcess.WaitForInputIdle(Settings.Default.MaxPuttyWaitTime * 1000);
|
||||||
|
|
||||||
var startTicks = Environment.TickCount;
|
var startTicks = Environment.TickCount;
|
||||||
while (PuttyHandle.ToInt32() == 0 & Environment.TickCount < startTicks + Settings.Default.MaxPuttyWaitTime * 1000)
|
while (PuttyHandle.ToInt32() == 0 & Environment.TickCount < startTicks + Settings.Default.MaxPuttyWaitTime * 1000)
|
||||||
{
|
{
|
||||||
@@ -153,17 +153,17 @@ namespace mRemoteNG.Connection.Protocol
|
|||||||
Thread.Sleep(0);
|
Thread.Sleep(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_isPuttyNg)
|
if (!_isPuttyNg)
|
||||||
{
|
{
|
||||||
NativeMethods.SetParent(PuttyHandle, InterfaceControl.Handle);
|
NativeMethods.SetParent(PuttyHandle, InterfaceControl.Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strPuttyStuff, true);
|
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, Language.strPuttyStuff, true);
|
||||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strPuttyHandle, PuttyHandle), true);
|
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strPuttyHandle, PuttyHandle), true);
|
||||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strPuttyTitle, PuttyProcess.MainWindowTitle), true);
|
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strPuttyTitle, PuttyProcess.MainWindowTitle), true);
|
||||||
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strPuttyParentHandle, InterfaceControl.Parent.Handle), true);
|
Runtime.MessageCollector.AddMessage(MessageClass.InformationMsg, string.Format(Language.strPuttyParentHandle, InterfaceControl.Parent.Handle), true);
|
||||||
|
|
||||||
Resize(this, new EventArgs());
|
Resize(this, new EventArgs());
|
||||||
base.Connect();
|
base.Connect();
|
||||||
return true;
|
return true;
|
||||||
@@ -174,7 +174,7 @@ namespace mRemoteNG.Connection.Protocol
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Focus()
|
public override void Focus()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -190,7 +190,7 @@ namespace mRemoteNG.Connection.Protocol
|
|||||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strPuttyFocusFailed + Environment.NewLine + ex.Message, true);
|
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strPuttyFocusFailed + Environment.NewLine + ex.Message, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Resize(object sender, EventArgs e)
|
public override void Resize(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -200,20 +200,28 @@ namespace mRemoteNG.Connection.Protocol
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var left = -(SystemInformation.FrameBorderSize.Width + SystemInformation.HorizontalResizeBorderThickness);
|
if (_isPuttyNg)
|
||||||
var top = -(SystemInformation.CaptionHeight + SystemInformation.FrameBorderSize.Height + SystemInformation.VerticalResizeBorderThickness);
|
{
|
||||||
var width = InterfaceControl.Width + (SystemInformation.FrameBorderSize.Width + SystemInformation.HorizontalResizeBorderThickness) * 2;
|
// PuTTYNG 0.70.0.1 and later doesn't have any window borders
|
||||||
var height = InterfaceControl.Height + SystemInformation.CaptionHeight +
|
NativeMethods.MoveWindow(PuttyHandle, 0, 0, InterfaceControl.Width, InterfaceControl.Height, true);
|
||||||
(SystemInformation.FrameBorderSize.Height + SystemInformation.VerticalResizeBorderThickness) * 2;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var left = -(SystemInformation.FrameBorderSize.Width + SystemInformation.HorizontalResizeBorderThickness);
|
||||||
|
var top = -(SystemInformation.CaptionHeight + SystemInformation.FrameBorderSize.Height + SystemInformation.VerticalResizeBorderThickness);
|
||||||
|
var width = InterfaceControl.Width + (SystemInformation.FrameBorderSize.Width + SystemInformation.HorizontalResizeBorderThickness) * 2;
|
||||||
|
var height = InterfaceControl.Height + SystemInformation.CaptionHeight + (SystemInformation.FrameBorderSize.Height +
|
||||||
|
SystemInformation.VerticalResizeBorderThickness) * 2;
|
||||||
|
|
||||||
NativeMethods.MoveWindow(PuttyHandle, left, top, width, height, true);
|
NativeMethods.MoveWindow(PuttyHandle, left, top, width, height, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strPuttyResizeFailed + Environment.NewLine + ex.Message, true);
|
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strPuttyResizeFailed + Environment.NewLine + ex.Message, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Close()
|
public override void Close()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -227,7 +235,7 @@ namespace mRemoteNG.Connection.Protocol
|
|||||||
{
|
{
|
||||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strPuttyKillFailed + Environment.NewLine + ex.Message, true);
|
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strPuttyKillFailed + Environment.NewLine + ex.Message, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PuttyProcess.Dispose();
|
PuttyProcess.Dispose();
|
||||||
@@ -236,10 +244,10 @@ namespace mRemoteNG.Connection.Protocol
|
|||||||
{
|
{
|
||||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strPuttyDisposeFailed + Environment.NewLine + ex.Message, true);
|
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strPuttyDisposeFailed + Environment.NewLine + ex.Message, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Close();
|
base.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ShowSettingsDialog()
|
public void ShowSettingsDialog()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -253,7 +261,7 @@ namespace mRemoteNG.Connection.Protocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Enums
|
#region Enums
|
||||||
|
|
||||||
protected enum Putty_Protocol
|
protected enum Putty_Protocol
|
||||||
|
|||||||
@@ -33,5 +33,5 @@ using System.Runtime.InteropServices;
|
|||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// <Assembly: AssemblyVersion("1.0.*")>
|
// <Assembly: AssemblyVersion("1.0.*")>
|
||||||
|
|
||||||
[assembly: AssemblyVersion("1.76.14.*")]
|
[assembly: AssemblyVersion("1.76.20.*")]
|
||||||
[assembly: NeutralResourcesLanguage("en")]
|
[assembly: NeutralResourcesLanguage("en")]
|
||||||
Binary file not shown.
45
mRemoteV1/Tools/DisposableAction.cs
Normal file
45
mRemoteV1/Tools/DisposableAction.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace mRemoteNG.Tools
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an action that will be executed when the <see cref="Dispose"/>
|
||||||
|
/// method is called. Useful for creating Using blocks around logical start/end
|
||||||
|
/// actions.
|
||||||
|
/// </summary>
|
||||||
|
public class DisposableAction : IDisposable
|
||||||
|
{
|
||||||
|
private bool _isDisposed;
|
||||||
|
private readonly Action _disposeAction;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="initializeAction">
|
||||||
|
/// An <see cref="Action"/> that should be performed immediately
|
||||||
|
/// when this object is initialized. It should return quickly.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="disposeAction">
|
||||||
|
/// An <see cref="Action"/> to be executed when this object is disposed.
|
||||||
|
/// </param>
|
||||||
|
public DisposableAction(Action initializeAction, Action disposeAction)
|
||||||
|
{
|
||||||
|
initializeAction();
|
||||||
|
_disposeAction = disposeAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (!disposing || _isDisposed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_isDisposed = true;
|
||||||
|
_disposeAction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -318,6 +318,7 @@
|
|||||||
<Compile Include="Tools\Cmdline\StartupArgumentsInterpreter.cs" />
|
<Compile Include="Tools\Cmdline\StartupArgumentsInterpreter.cs" />
|
||||||
<Compile Include="Tools\CustomCollections\CollectionUpdatedEventArgs.cs" />
|
<Compile Include="Tools\CustomCollections\CollectionUpdatedEventArgs.cs" />
|
||||||
<Compile Include="Settings.cs" />
|
<Compile Include="Settings.cs" />
|
||||||
|
<Compile Include="Tools\DisposableAction.cs" />
|
||||||
<Compile Include="Tools\Extensions.cs" />
|
<Compile Include="Tools\Extensions.cs" />
|
||||||
<Compile Include="Tools\ExternalToolArgumentParser.cs" />
|
<Compile Include="Tools\ExternalToolArgumentParser.cs" />
|
||||||
<Compile Include="Tools\Cmdline\CmdArgumentsInterpreter.cs" />
|
<Compile Include="Tools\Cmdline\CmdArgumentsInterpreter.cs" />
|
||||||
|
|||||||
Reference in New Issue
Block a user