mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-17 22:11:48 +08:00
more refactoring. most connection saving/loading calls now go through the connection service class
This commit is contained in:
@@ -67,14 +67,14 @@ namespace mRemoteNG.App
|
||||
}
|
||||
}
|
||||
|
||||
private static void SaveExportFile(string fileName, ConnectionsSaver.Format saveFormat, SaveFilter saveFilter, ConnectionInfo exportTarget)
|
||||
private static void SaveExportFile(string fileName, SaveFormat saveFormat, SaveFilter saveFilter, ConnectionInfo exportTarget)
|
||||
{
|
||||
try
|
||||
{
|
||||
ISerializer<ConnectionInfo, string> serializer;
|
||||
switch (saveFormat)
|
||||
{
|
||||
case ConnectionsSaver.Format.mRXML:
|
||||
case SaveFormat.mRXML:
|
||||
var cryptographyProvider = new CryptoProviderFactoryFromSettings().Build();
|
||||
var rootNode = exportTarget.GetRootParent() as RootNodeInfo;
|
||||
var connectionNodeSerializer = new XmlConnectionNodeSerializer26(
|
||||
@@ -83,7 +83,7 @@ namespace mRemoteNG.App
|
||||
saveFilter);
|
||||
serializer = new XmlConnectionsSerializer(cryptographyProvider, connectionNodeSerializer);
|
||||
break;
|
||||
case ConnectionsSaver.Format.mRCSV:
|
||||
case SaveFormat.mRCSV:
|
||||
serializer = new CsvConnectionsSerializerMremotengFormat(saveFilter, Runtime.CredentialProviderCatalog);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.Security;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using mRemoteNG.App.Info;
|
||||
using mRemoteNG.Config.Connections;
|
||||
using mRemoteNG.Config.Connections.Multiuser;
|
||||
using mRemoteNG.Config.DataProviders;
|
||||
using mRemoteNG.Config.Putty;
|
||||
@@ -13,7 +12,6 @@ using mRemoteNG.Credential;
|
||||
using mRemoteNG.Credential.Repositories;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Security.SymmetricEncryption;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tree.Root;
|
||||
using mRemoteNG.UI;
|
||||
@@ -40,8 +38,6 @@ namespace mRemoteNG.App
|
||||
public static MessageCollector MessageCollector { get; } = new MessageCollector();
|
||||
public static NotificationAreaIcon NotificationAreaIcon { get; set; }
|
||||
public static RemoteConnectionsSyncronizer RemoteConnectionsSyncronizer { get; set; }
|
||||
// ReSharper disable once UnusedAutoPropertyAccessor.Local
|
||||
public static DateTime LastSqlUpdate { get; set; }
|
||||
public static ExternalToolsService ExternalToolsService { get; } = new ExternalToolsService();
|
||||
public static SecureString EncryptionKey { get; set; } = new RootNodeInfo(RootNodeType.Connection).PasswordString.ConvertToSecureString();
|
||||
public static ICredentialRepositoryList CredentialProviderCatalog { get; } = new CredentialRepositoryList();
|
||||
@@ -97,7 +93,7 @@ namespace mRemoteNG.App
|
||||
|
||||
if (Settings.Default.UseSQLServer)
|
||||
{
|
||||
LastSqlUpdate = DateTime.Now;
|
||||
ConnectionsService.LastSqlUpdate = DateTime.Now;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -210,98 +206,9 @@ namespace mRemoteNG.App
|
||||
private static void SaveConnectionsBGd()
|
||||
{
|
||||
Monitor.Enter(SaveLock);
|
||||
SaveConnections();
|
||||
ConnectionsService.SaveConnections();
|
||||
Monitor.Exit(SaveLock);
|
||||
}
|
||||
|
||||
public static void SaveConnections()
|
||||
{
|
||||
if (ConnectionsService.ConnectionTreeModel == null) return;
|
||||
if (!ConnectionsService.IsConnectionsFileLoaded) return;
|
||||
|
||||
try
|
||||
{
|
||||
RemoteConnectionsSyncronizer?.Disable();
|
||||
|
||||
var connectionsSaver = new ConnectionsSaver();
|
||||
|
||||
if (!Settings.Default.UseSQLServer)
|
||||
connectionsSaver.ConnectionFileName = ConnectionsService.GetStartupConnectionFileName();
|
||||
|
||||
connectionsSaver.SaveFilter = new SaveFilter();
|
||||
connectionsSaver.ConnectionTreeModel = ConnectionsService.ConnectionTreeModel;
|
||||
|
||||
if (Settings.Default.UseSQLServer)
|
||||
{
|
||||
connectionsSaver.SaveFormat = ConnectionsSaver.Format.SQL;
|
||||
connectionsSaver.SQLHost = Settings.Default.SQLHost;
|
||||
connectionsSaver.SQLDatabaseName = Settings.Default.SQLDatabaseName;
|
||||
connectionsSaver.SQLUsername = Settings.Default.SQLUser;
|
||||
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
|
||||
connectionsSaver.SQLPassword = cryptographyProvider.Decrypt(Settings.Default.SQLPass, EncryptionKey);
|
||||
}
|
||||
|
||||
connectionsSaver.SaveConnections();
|
||||
|
||||
if (Settings.Default.UseSQLServer)
|
||||
LastSqlUpdate = DateTime.Now;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strConnectionsFileCouldNotBeSaved + Environment.NewLine + ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
RemoteConnectionsSyncronizer?.Enable();
|
||||
}
|
||||
}
|
||||
|
||||
public static void SaveConnectionsAs()
|
||||
{
|
||||
var connectionsSave = new ConnectionsSaver();
|
||||
|
||||
try
|
||||
{
|
||||
RemoteConnectionsSyncronizer?.Disable();
|
||||
|
||||
using (var saveFileDialog = new SaveFileDialog())
|
||||
{
|
||||
saveFileDialog.CheckPathExists = true;
|
||||
saveFileDialog.InitialDirectory = ConnectionsFileInfo.DefaultConnectionsPath;
|
||||
saveFileDialog.FileName = ConnectionsFileInfo.DefaultConnectionsFile;
|
||||
saveFileDialog.OverwritePrompt = true;
|
||||
saveFileDialog.Filter = $@"{Language.strFiltermRemoteXML}|*.xml|{Language.strFilterAll}|*.*";
|
||||
|
||||
if (saveFileDialog.ShowDialog(FrmMain.Default) != DialogResult.OK) return;
|
||||
|
||||
connectionsSave.SaveFormat = ConnectionsSaver.Format.mRXML;
|
||||
connectionsSave.ConnectionFileName = saveFileDialog.FileName;
|
||||
connectionsSave.SaveFilter = new SaveFilter();
|
||||
connectionsSave.ConnectionTreeModel = ConnectionsService.ConnectionTreeModel;
|
||||
|
||||
connectionsSave.SaveConnections();
|
||||
|
||||
if (saveFileDialog.FileName == ConnectionsService.GetDefaultStartupConnectionFileName())
|
||||
{
|
||||
Settings.Default.LoadConsFromCustomLocation = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Settings.Default.LoadConsFromCustomLocation = true;
|
||||
Settings.Default.CustomConsPath = saveFileDialog.FileName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageCollector.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotSaveAs, connectionsSave.ConnectionFileName), ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
RemoteConnectionsSyncronizer?.Enable();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ namespace mRemoteNG.App
|
||||
private static void SaveConnections()
|
||||
{
|
||||
if (Settings.Default.SaveConsOnExit)
|
||||
Runtime.SaveConnections();
|
||||
Runtime.ConnectionsService.SaveConnections();
|
||||
}
|
||||
|
||||
private static void SaveSettings(Control quickConnectToolStrip, ExternalToolsToolStrip externalToolsToolStrip, FrmMain frmMain)
|
||||
|
||||
@@ -57,8 +57,6 @@ namespace mRemoteNG.App
|
||||
public void CreateConnectionsProvider(MessageCollector messageCollector)
|
||||
{
|
||||
messageCollector.AddMessage(MessageClass.DebugMsg, "Determining if we need a database syncronizer");
|
||||
_frmMain.AreWeUsingSqlServerForSavingConnections = Settings.Default.UseSQLServer;
|
||||
|
||||
if (!Settings.Default.UseSQLServer) return;
|
||||
messageCollector.AddMessage(MessageClass.DebugMsg, "Creating database syncronizer");
|
||||
Runtime.RemoteConnectionsSyncronizer = new RemoteConnectionsSyncronizer(new SqlConnectionsUpdateChecker());
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
using mRemoteNG.Config.Putty;
|
||||
using mRemoteNG.Tree;
|
||||
|
||||
namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
public class ConnectionsLoader
|
||||
{
|
||||
/// <summary>
|
||||
/// Load connections from a source. <see cref="connectionFileName"/> is ignored if
|
||||
/// <see cref="useDatabase"/> is true.
|
||||
/// </summary>
|
||||
/// <param name="useDatabase"></param>
|
||||
/// <param name="import"></param>
|
||||
/// <param name="connectionFileName"></param>
|
||||
public ConnectionTreeModel LoadConnections(bool useDatabase, bool import, string connectionFileName)
|
||||
{
|
||||
ConnectionTreeModel connectionTreeModel;
|
||||
|
||||
if (useDatabase)
|
||||
{
|
||||
var sqlLoader = new SqlConnectionsLoader();
|
||||
connectionTreeModel = sqlLoader.Load();
|
||||
}
|
||||
else
|
||||
{
|
||||
var xmlLoader = new XmlConnectionsLoader(connectionFileName);
|
||||
connectionTreeModel = xmlLoader.Load();
|
||||
}
|
||||
|
||||
if (connectionTreeModel == null)
|
||||
connectionTreeModel = new ConnectionTreeModel();
|
||||
|
||||
if (!import)
|
||||
AddPuttySessions(connectionTreeModel);
|
||||
|
||||
return connectionTreeModel;
|
||||
}
|
||||
|
||||
private void AddPuttySessions(ConnectionTreeModel connectionTreeModel)
|
||||
{
|
||||
PuttySessionsManager.Instance.AddSessions();
|
||||
connectionTreeModel.RootNodes.AddRange(PuttySessionsManager.Instance.RootPuttySessionsNodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
24
mRemoteV1/Config/Connections/ConnectionsSavedEventArgs.cs
Normal file
24
mRemoteV1/Config/Connections/ConnectionsSavedEventArgs.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using mRemoteNG.Tree;
|
||||
|
||||
namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
public class ConnectionsSavedEventArgs
|
||||
{
|
||||
public ConnectionTreeModel ModelThatWasSaved { get; }
|
||||
public bool PreviouslyUsingDatabase { get; }
|
||||
public bool UsingDatabase { get; }
|
||||
public string ConnectionFileName { get; }
|
||||
|
||||
public ConnectionsSavedEventArgs(ConnectionTreeModel modelThatWasSaved, bool previouslyUsingDatabase, bool usingDatabase, string connectionFileName)
|
||||
{
|
||||
if (modelThatWasSaved == null)
|
||||
throw new ArgumentNullException(nameof(modelThatWasSaved));
|
||||
|
||||
ModelThatWasSaved = modelThatWasSaved;
|
||||
PreviouslyUsingDatabase = previouslyUsingDatabase;
|
||||
UsingDatabase = usingDatabase;
|
||||
ConnectionFileName = connectionFileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using System.Windows.Forms;
|
||||
using System.Xml;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.App.Info;
|
||||
using mRemoteNG.Config.DatabaseConnectors;
|
||||
using mRemoteNG.Config.DataProviders;
|
||||
using mRemoteNG.Config.Serializers;
|
||||
using mRemoteNG.Config.Serializers.Versioning;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Security.Factories;
|
||||
using mRemoteNG.Security.SymmetricEncryption;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
using mRemoteNG.UI.Forms;
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||
|
||||
namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
public class ConnectionsSaver
|
||||
{
|
||||
public enum Format
|
||||
{
|
||||
None,
|
||||
mRXML,
|
||||
mRCSV,
|
||||
SQL
|
||||
}
|
||||
|
||||
private SecureString _password = Runtime.EncryptionKey;
|
||||
|
||||
#region Public Properties
|
||||
public string SQLHost {get; set;}
|
||||
public string SQLDatabaseName {get; set;}
|
||||
public string SQLUsername {get; set;}
|
||||
public string SQLPassword {get; set;}
|
||||
|
||||
public string ConnectionFileName {get; set;}
|
||||
public TreeNode RootTreeNode {get; set;}
|
||||
public Format SaveFormat {get; set;}
|
||||
public SaveFilter SaveFilter {get; set;}
|
||||
public ConnectionTreeModel ConnectionTreeModel { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
public void SaveConnections()
|
||||
{
|
||||
switch (SaveFormat)
|
||||
{
|
||||
case Format.SQL:
|
||||
SaveToSql();
|
||||
break;
|
||||
case Format.mRCSV:
|
||||
SaveToMremotengFormattedCsv();
|
||||
break;
|
||||
default:
|
||||
SaveToXml();
|
||||
FrmMain.Default.ConnectionsFileName = ConnectionFileName;
|
||||
break;
|
||||
}
|
||||
FrmMain.Default.AreWeUsingSqlServerForSavingConnections = SaveFormat == Format.SQL;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SQL
|
||||
private void SaveToSql()
|
||||
{
|
||||
var sqlConnector = DatabaseConnectorFactory.SqlDatabaseConnectorFromSettings();
|
||||
sqlConnector.Connect();
|
||||
var databaseVersionVerifier = new SqlDatabaseVersionVerifier(sqlConnector);
|
||||
|
||||
if (!databaseVersionVerifier.VerifyDatabaseVersion())
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strErrorConnectionListSaveFailed);
|
||||
return;
|
||||
}
|
||||
|
||||
var rootTreeNode = Runtime.ConnectionsService.ConnectionTreeModel.RootNodes.OfType<RootNodeInfo>().First();
|
||||
|
||||
UpdateRootNodeTable(rootTreeNode, sqlConnector);
|
||||
UpdateConnectionsTable(rootTreeNode, sqlConnector);
|
||||
UpdateUpdatesTable(sqlConnector);
|
||||
|
||||
sqlConnector.Disconnect();
|
||||
sqlConnector.Dispose();
|
||||
}
|
||||
|
||||
private void UpdateRootNodeTable(RootNodeInfo rootTreeNode, SqlDatabaseConnector sqlDatabaseConnector)
|
||||
{
|
||||
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
|
||||
string strProtected;
|
||||
if (rootTreeNode != null)
|
||||
{
|
||||
if (rootTreeNode.Password)
|
||||
{
|
||||
_password = rootTreeNode.PasswordString.ConvertToSecureString();
|
||||
strProtected = cryptographyProvider.Encrypt("ThisIsProtected", _password);
|
||||
}
|
||||
else
|
||||
{
|
||||
strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _password);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _password);
|
||||
}
|
||||
|
||||
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!");
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateConnectionsTable(ContainerInfo rootTreeNode, SqlDatabaseConnector sqlDatabaseConnector)
|
||||
{
|
||||
var sqlQuery = new SqlCommand("DELETE FROM tblCons", sqlDatabaseConnector.SqlConnection);
|
||||
sqlQuery.ExecuteNonQuery();
|
||||
var serializer = new DataTableSerializer(SaveFilter);
|
||||
var dataTable = serializer.Serialize(rootTreeNode);
|
||||
var dataProvider = new SqlDataProvider(sqlDatabaseConnector);
|
||||
dataProvider.Save(dataTable);
|
||||
}
|
||||
|
||||
private void UpdateUpdatesTable(SqlDatabaseConnector sqlDatabaseConnector)
|
||||
{
|
||||
var sqlQuery = new SqlCommand("DELETE FROM tblUpdate", sqlDatabaseConnector.SqlConnection);
|
||||
sqlQuery.ExecuteNonQuery();
|
||||
sqlQuery = new SqlCommand("INSERT INTO tblUpdate (LastUpdate) VALUES(\'" + MiscTools.DBDate(DateTime.Now) + "\')", sqlDatabaseConnector.SqlConnection);
|
||||
sqlQuery.ExecuteNonQuery();
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void SaveToXml()
|
||||
{
|
||||
try
|
||||
{
|
||||
var cryptographyProvider = new CryptoProviderFactoryFromSettings().Build();
|
||||
var connectionNodeSerializer = new XmlConnectionNodeSerializer26(
|
||||
cryptographyProvider,
|
||||
ConnectionTreeModel.RootNodes.OfType<RootNodeInfo>().First().PasswordString.ConvertToSecureString(),
|
||||
SaveFilter);
|
||||
var xmlConnectionsSerializer = new XmlConnectionsSerializer(cryptographyProvider, connectionNodeSerializer)
|
||||
{
|
||||
UseFullEncryption = mRemoteNG.Settings.Default.EncryptCompleteConnectionsFile
|
||||
};
|
||||
var xml = xmlConnectionsSerializer.Serialize(ConnectionTreeModel);
|
||||
|
||||
var fileDataProvider = new FileDataProviderWithRollingBackup(ConnectionFileName);
|
||||
fileDataProvider.Save(xml);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector.AddExceptionStackTrace("SaveToXml failed", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveToMremotengFormattedCsv()
|
||||
{
|
||||
var csvConnectionsSerializer = new CsvConnectionsSerializerMremotengFormat(SaveFilter, Runtime.CredentialProviderCatalog);
|
||||
var dataProvider = new FileDataProvider(ConnectionFileName);
|
||||
var csvContent = csvConnectionsSerializer.Serialize(ConnectionTreeModel);
|
||||
dataProvider.Save(csvContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
34
mRemoteV1/Config/Connections/CsvConnectionsSaver.cs
Normal file
34
mRemoteV1/Config/Connections/CsvConnectionsSaver.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Config.DataProviders;
|
||||
using mRemoteNG.Config.Serializers;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Tree;
|
||||
|
||||
namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
public class CsvConnectionsSaver : ISaver<ConnectionTreeModel>
|
||||
{
|
||||
private readonly string _connectionFileName;
|
||||
private readonly SaveFilter _saveFilter;
|
||||
|
||||
public CsvConnectionsSaver(string connectionFileName, SaveFilter saveFilter)
|
||||
{
|
||||
if (string.IsNullOrEmpty(connectionFileName))
|
||||
throw new ArgumentException($"Argument '{nameof(connectionFileName)}' cannot be null or empty");
|
||||
if (saveFilter == null)
|
||||
throw new ArgumentNullException(nameof(saveFilter));
|
||||
|
||||
_connectionFileName = connectionFileName;
|
||||
_saveFilter = saveFilter;
|
||||
}
|
||||
|
||||
public void Save(ConnectionTreeModel connectionTreeModel)
|
||||
{
|
||||
var csvConnectionsSerializer = new CsvConnectionsSerializerMremotengFormat(_saveFilter, Runtime.CredentialProviderCatalog);
|
||||
var dataProvider = new FileDataProvider(_connectionFileName);
|
||||
var csvContent = csvConnectionsSerializer.Serialize(connectionTreeModel);
|
||||
dataProvider.Save(csvContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ namespace mRemoteNG.Config.Connections.Multiuser
|
||||
{
|
||||
private readonly Timer _updateTimer;
|
||||
private readonly IConnectionsUpdateChecker _updateChecker;
|
||||
private readonly ConnectionsSaver _connectionsSaver;
|
||||
|
||||
public double TimerIntervalInMilliseconds
|
||||
{
|
||||
@@ -20,7 +19,6 @@ namespace mRemoteNG.Config.Connections.Multiuser
|
||||
{
|
||||
_updateChecker = updateChecker;
|
||||
_updateTimer = new Timer(3000);
|
||||
_connectionsSaver = new ConnectionsSaver { SaveFormat = ConnectionsSaver.Format.SQL };
|
||||
SetEventListeners();
|
||||
}
|
||||
|
||||
@@ -33,22 +31,12 @@ namespace mRemoteNG.Config.Connections.Multiuser
|
||||
ConnectionsUpdateAvailable += Load;
|
||||
}
|
||||
|
||||
public void Load()
|
||||
{
|
||||
Runtime.ConnectionsService.ConnectionTreeModel = Runtime.ConnectionsService.LoadConnections(mRemoteNG.Settings.Default.UseSQLServer, false, "");
|
||||
}
|
||||
|
||||
private void Load(object sender, ConnectionsUpdateAvailableEventArgs args)
|
||||
{
|
||||
Load();
|
||||
Runtime.ConnectionsService.ConnectionTreeModel = Runtime.ConnectionsService.LoadConnections(true, false, "");
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
_connectionsSaver.SaveConnections();
|
||||
}
|
||||
|
||||
public void Enable()
|
||||
{
|
||||
_updateTimer.Start();
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace mRemoteNG.Config.Connections
|
||||
|
||||
private bool CheckIfIAmTheLastOneUpdated(DateTime lastUpdateInDb)
|
||||
{
|
||||
DateTime LastSqlUpdateWithoutMilliseconds = new DateTime(Runtime.LastSqlUpdate.Ticks - (Runtime.LastSqlUpdate.Ticks % TimeSpan.TicksPerSecond), Runtime.LastSqlUpdate.Kind);
|
||||
DateTime LastSqlUpdateWithoutMilliseconds = new DateTime(Runtime.ConnectionsService.LastSqlUpdate.Ticks - (Runtime.ConnectionsService.LastSqlUpdate.Ticks % TimeSpan.TicksPerSecond), Runtime.ConnectionsService.LastSqlUpdate.Kind);
|
||||
return lastUpdateInDb == LastSqlUpdateWithoutMilliseconds;
|
||||
}
|
||||
|
||||
|
||||
10
mRemoteV1/Config/Connections/SaveFormat.cs
Normal file
10
mRemoteV1/Config/Connections/SaveFormat.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
public enum SaveFormat
|
||||
{
|
||||
None,
|
||||
mRXML,
|
||||
mRCSV,
|
||||
SQL
|
||||
}
|
||||
}
|
||||
113
mRemoteV1/Config/Connections/SqlConnectionsSaver.cs
Normal file
113
mRemoteV1/Config/Connections/SqlConnectionsSaver.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.App.Info;
|
||||
using mRemoteNG.Config.DatabaseConnectors;
|
||||
using mRemoteNG.Config.DataProviders;
|
||||
using mRemoteNG.Config.Serializers;
|
||||
using mRemoteNG.Config.Serializers.Versioning;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Messages;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Security.SymmetricEncryption;
|
||||
using mRemoteNG.Tools;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
|
||||
namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
public class SqlConnectionsSaver : ISaver<ConnectionTreeModel>
|
||||
{
|
||||
private SecureString _password = Runtime.EncryptionKey;
|
||||
private readonly SaveFilter _saveFilter;
|
||||
|
||||
public SqlConnectionsSaver(SaveFilter saveFilter)
|
||||
{
|
||||
if (saveFilter == null)
|
||||
throw new ArgumentNullException(nameof(saveFilter));
|
||||
_saveFilter = saveFilter;
|
||||
}
|
||||
|
||||
public void Save(ConnectionTreeModel connectionTreeModel)
|
||||
{
|
||||
using (var sqlConnector = DatabaseConnectorFactory.SqlDatabaseConnectorFromSettings())
|
||||
{
|
||||
sqlConnector.Connect();
|
||||
var databaseVersionVerifier = new SqlDatabaseVersionVerifier(sqlConnector);
|
||||
|
||||
if (!databaseVersionVerifier.VerifyDatabaseVersion())
|
||||
{
|
||||
Runtime.MessageCollector.AddMessage(MessageClass.ErrorMsg, Language.strErrorConnectionListSaveFailed);
|
||||
return;
|
||||
}
|
||||
|
||||
var rootTreeNode = connectionTreeModel.RootNodes.OfType<RootNodeInfo>().First();
|
||||
|
||||
UpdateRootNodeTable(rootTreeNode, sqlConnector);
|
||||
UpdateConnectionsTable(rootTreeNode, sqlConnector);
|
||||
UpdateUpdatesTable(sqlConnector);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateRootNodeTable(RootNodeInfo rootTreeNode, SqlDatabaseConnector sqlDatabaseConnector)
|
||||
{
|
||||
var cryptographyProvider = new LegacyRijndaelCryptographyProvider();
|
||||
string strProtected;
|
||||
if (rootTreeNode != null)
|
||||
{
|
||||
if (rootTreeNode.Password)
|
||||
{
|
||||
_password = rootTreeNode.PasswordString.ConvertToSecureString();
|
||||
strProtected = cryptographyProvider.Encrypt("ThisIsProtected", _password);
|
||||
}
|
||||
else
|
||||
{
|
||||
strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _password);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strProtected = cryptographyProvider.Encrypt("ThisIsNotProtected", _password);
|
||||
}
|
||||
|
||||
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!");
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateConnectionsTable(ContainerInfo rootTreeNode, SqlDatabaseConnector sqlDatabaseConnector)
|
||||
{
|
||||
var sqlQuery = new SqlCommand("DELETE FROM tblCons", sqlDatabaseConnector.SqlConnection);
|
||||
sqlQuery.ExecuteNonQuery();
|
||||
var serializer = new DataTableSerializer(_saveFilter);
|
||||
var dataTable = serializer.Serialize(rootTreeNode);
|
||||
var dataProvider = new SqlDataProvider(sqlDatabaseConnector);
|
||||
dataProvider.Save(dataTable);
|
||||
}
|
||||
|
||||
private void UpdateUpdatesTable(SqlDatabaseConnector sqlDatabaseConnector)
|
||||
{
|
||||
var sqlQuery = new SqlCommand("DELETE FROM tblUpdate", sqlDatabaseConnector.SqlConnection);
|
||||
sqlQuery.ExecuteNonQuery();
|
||||
sqlQuery = new SqlCommand("INSERT INTO tblUpdate (LastUpdate) VALUES(\'" + MiscTools.DBDate(DateTime.Now) + "\')", sqlDatabaseConnector.SqlConnection);
|
||||
sqlQuery.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
53
mRemoteV1/Config/Connections/XmlConnectionsSaver.cs
Normal file
53
mRemoteV1/Config/Connections/XmlConnectionsSaver.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using mRemoteNG.App;
|
||||
using mRemoteNG.Config.DataProviders;
|
||||
using mRemoteNG.Config.Serializers;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Security.Factories;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
|
||||
namespace mRemoteNG.Config.Connections
|
||||
{
|
||||
public class XmlConnectionsSaver : ISaver<ConnectionTreeModel>
|
||||
{
|
||||
private readonly string _connectionFileName;
|
||||
private readonly SaveFilter _saveFilter;
|
||||
|
||||
public XmlConnectionsSaver(string connectionFileName, SaveFilter saveFilter)
|
||||
{
|
||||
if (string.IsNullOrEmpty(connectionFileName))
|
||||
throw new ArgumentException($"Argument '{nameof(connectionFileName)}' cannot be null or empty");
|
||||
if (saveFilter == null)
|
||||
throw new ArgumentNullException(nameof(saveFilter));
|
||||
|
||||
_connectionFileName = connectionFileName;
|
||||
_saveFilter = saveFilter;
|
||||
}
|
||||
|
||||
public void Save(ConnectionTreeModel connectionTreeModel)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cryptographyProvider = new CryptoProviderFactoryFromSettings().Build();
|
||||
var connectionNodeSerializer = new XmlConnectionNodeSerializer26(
|
||||
cryptographyProvider,
|
||||
connectionTreeModel.RootNodes.OfType<RootNodeInfo>().First().PasswordString.ConvertToSecureString(),
|
||||
_saveFilter);
|
||||
var xmlConnectionsSerializer = new XmlConnectionsSerializer(cryptographyProvider, connectionNodeSerializer)
|
||||
{
|
||||
UseFullEncryption = mRemoteNG.Settings.Default.EncryptCompleteConnectionsFile
|
||||
};
|
||||
var xml = xmlConnectionsSerializer.Serialize(connectionTreeModel);
|
||||
|
||||
var fileDataProvider = new FileDataProviderWithRollingBackup(_connectionFileName);
|
||||
fileDataProvider.Save(xml);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector?.AddExceptionStackTrace("SaveToXml failed", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using mRemoteNG.App.Info;
|
||||
using mRemoteNG.Config.Connections;
|
||||
using mRemoteNG.Config.Putty;
|
||||
using mRemoteNG.Connection.Protocol;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.Tree.Root;
|
||||
|
||||
@@ -14,12 +15,11 @@ namespace mRemoteNG.Connection
|
||||
public class ConnectionsService
|
||||
{
|
||||
private readonly PuttySessionsManager _puttySessionsManager;
|
||||
private readonly ConnectionsLoader _connectionsLoader;
|
||||
|
||||
public bool IsConnectionsFileLoaded { get; set; }
|
||||
public bool UsingDatabase { get; private set; }
|
||||
public string ConnectionFileName { get; private set; }
|
||||
public static DateTime LastSqlUpdate { get; private set; }
|
||||
public DateTime LastSqlUpdate { get; set; }
|
||||
|
||||
public ConnectionTreeModel ConnectionTreeModel
|
||||
{
|
||||
@@ -31,27 +31,19 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
if (puttySessionsManager == null)
|
||||
throw new ArgumentNullException(nameof(puttySessionsManager));
|
||||
|
||||
_puttySessionsManager = puttySessionsManager;
|
||||
_connectionsLoader = new ConnectionsLoader();
|
||||
}
|
||||
|
||||
public void NewConnectionsFile(string filename)
|
||||
{
|
||||
try
|
||||
{
|
||||
UpdateCustomConsPathSetting(filename);
|
||||
|
||||
var newConnectionsModel = new ConnectionTreeModel();
|
||||
newConnectionsModel.AddRootNode(new RootNodeInfo(RootNodeType.Connection));
|
||||
var connectionSaver = new ConnectionsSaver
|
||||
{
|
||||
ConnectionTreeModel = newConnectionsModel,
|
||||
ConnectionFileName = filename,
|
||||
SaveFilter = new Security.SaveFilter()
|
||||
};
|
||||
connectionSaver.SaveConnections();
|
||||
|
||||
SaveConnections(newConnectionsModel, false, new SaveFilter(), filename);
|
||||
LoadConnections(false, false, filename);
|
||||
UpdateCustomConsPathSetting(filename);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -103,7 +95,19 @@ namespace mRemoteNG.Connection
|
||||
{
|
||||
var oldConnectionTreeModel = ConnectionTreeModel;
|
||||
var oldIsUsingDatabaseValue = UsingDatabase;
|
||||
var newConnectionTreeModel = _connectionsLoader.LoadConnections(useDatabase, import, connectionFileName);
|
||||
|
||||
var newConnectionTreeModel =
|
||||
(useDatabase
|
||||
? new SqlConnectionsLoader().Load()
|
||||
: new XmlConnectionsLoader(connectionFileName).Load())
|
||||
?? new ConnectionTreeModel();
|
||||
|
||||
if (!import)
|
||||
{
|
||||
_puttySessionsManager.AddSessions();
|
||||
newConnectionTreeModel.RootNodes.AddRange(_puttySessionsManager.RootPuttySessionsNodes);
|
||||
}
|
||||
|
||||
IsConnectionsFileLoaded = true;
|
||||
ConnectionFileName = connectionFileName;
|
||||
UsingDatabase = useDatabase;
|
||||
@@ -112,6 +116,66 @@ namespace mRemoteNG.Connection
|
||||
return newConnectionTreeModel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the currently loaded <see cref="ConnectionTreeModel"/> with
|
||||
/// no <see cref="SaveFilter"/>.
|
||||
/// </summary>
|
||||
public void SaveConnections()
|
||||
{
|
||||
if (!IsConnectionsFileLoaded)
|
||||
return;
|
||||
SaveConnections(ConnectionTreeModel, UsingDatabase, new SaveFilter(), ConnectionFileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the given <see cref="ConnectionTreeModel"/>.
|
||||
/// If <see cref="useDatabase"/> is true, <see cref="connectionFileName"/> is ignored
|
||||
/// </summary>
|
||||
/// <param name="connectionTreeModel"></param>
|
||||
/// <param name="useDatabase"></param>
|
||||
/// <param name="saveFilter"></param>
|
||||
/// <param name="connectionFileName"></param>
|
||||
public void SaveConnections(ConnectionTreeModel connectionTreeModel, bool useDatabase, SaveFilter saveFilter, string connectionFileName)
|
||||
{
|
||||
if (connectionTreeModel == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
Runtime.RemoteConnectionsSyncronizer?.Disable();
|
||||
|
||||
var previouslyUsingDatabase = UsingDatabase;
|
||||
if (useDatabase)
|
||||
new SqlConnectionsSaver(saveFilter).Save(connectionTreeModel);
|
||||
else
|
||||
new XmlConnectionsSaver(connectionFileName, saveFilter).Save(connectionTreeModel);
|
||||
|
||||
if (UsingDatabase)
|
||||
LastSqlUpdate = DateTime.Now;
|
||||
|
||||
UsingDatabase = useDatabase;
|
||||
ConnectionFileName = connectionFileName;
|
||||
RaiseConnectionsSavedEvent(connectionTreeModel, previouslyUsingDatabase, UsingDatabase, connectionFileName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Runtime.MessageCollector?.AddExceptionMessage(string.Format(Language.strConnectionsFileCouldNotSaveAs, connectionFileName), ex, logOnly:false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Runtime.RemoteConnectionsSyncronizer?.Enable();
|
||||
}
|
||||
}
|
||||
|
||||
public string GetStartupConnectionFileName()
|
||||
{
|
||||
return Settings.Default.LoadConsFromCustomLocation == false ? GetDefaultStartupConnectionFileName() : Settings.Default.CustomConsPath;
|
||||
}
|
||||
|
||||
public string GetDefaultStartupConnectionFileName()
|
||||
{
|
||||
return Runtime.IsPortableEdition ? GetDefaultStartupConnectionFileNamePortableEdition() : GetDefaultStartupConnectionFileNameNormalEdition();
|
||||
}
|
||||
|
||||
private void UpdateCustomConsPathSetting(string filename)
|
||||
{
|
||||
if (filename == GetDefaultStartupConnectionFileName())
|
||||
@@ -125,16 +189,6 @@ namespace mRemoteNG.Connection
|
||||
}
|
||||
}
|
||||
|
||||
public string GetStartupConnectionFileName()
|
||||
{
|
||||
return Settings.Default.LoadConsFromCustomLocation == false ? GetDefaultStartupConnectionFileName() : Settings.Default.CustomConsPath;
|
||||
}
|
||||
|
||||
public string GetDefaultStartupConnectionFileName()
|
||||
{
|
||||
return Runtime.IsPortableEdition ? GetDefaultStartupConnectionFileNamePortableEdition() : GetDefaultStartupConnectionFileNameNormalEdition();
|
||||
}
|
||||
|
||||
private string GetDefaultStartupConnectionFileNameNormalEdition()
|
||||
{
|
||||
var appDataPath = Path.Combine(
|
||||
@@ -151,8 +205,9 @@ namespace mRemoteNG.Connection
|
||||
|
||||
#region Events
|
||||
public event EventHandler<ConnectionsLoadedEventArgs> ConnectionsLoaded;
|
||||
public event EventHandler<ConnectionsSavedEventArgs> ConnectionsSaved;
|
||||
|
||||
protected virtual void RaiseConnectionsLoadedEvent(ConnectionTreeModel previousTreeModel, ConnectionTreeModel newTreeModel,
|
||||
private void RaiseConnectionsLoadedEvent(ConnectionTreeModel previousTreeModel, ConnectionTreeModel newTreeModel,
|
||||
bool previousSourceWasDatabase, bool newSourceIsDatabase,
|
||||
string newSourcePath)
|
||||
{
|
||||
@@ -163,6 +218,11 @@ namespace mRemoteNG.Connection
|
||||
newSourceIsDatabase,
|
||||
newSourcePath));
|
||||
}
|
||||
|
||||
private void RaiseConnectionsSavedEvent(ConnectionTreeModel modelThatWasSaved, bool previouslyUsingDatabase, bool usingDatabase, string connectionFileName)
|
||||
{
|
||||
ConnectionsSaved?.Invoke(this, new ConnectionsSavedEventArgs(modelThatWasSaved, previouslyUsingDatabase, usingDatabase, connectionFileName));
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -26,12 +26,12 @@ namespace mRemoteNG.UI.Forms
|
||||
}
|
||||
}
|
||||
|
||||
public ConnectionsSaver.Format SaveFormat
|
||||
public SaveFormat SaveFormat
|
||||
{
|
||||
get
|
||||
{
|
||||
var exportFormat = cboFileFormat.SelectedItem as ExportFormat;
|
||||
return exportFormat?.Format ?? ConnectionsSaver.Format.mRXML;
|
||||
return exportFormat?.Format ?? SaveFormat.mRXML;
|
||||
}
|
||||
set
|
||||
{
|
||||
@@ -173,8 +173,8 @@ namespace mRemoteNG.UI.Forms
|
||||
private void ExportForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
cboFileFormat.Items.Clear();
|
||||
cboFileFormat.Items.Add(new ExportFormat(ConnectionsSaver.Format.mRXML));
|
||||
cboFileFormat.Items.Add(new ExportFormat(ConnectionsSaver.Format.mRCSV));
|
||||
cboFileFormat.Items.Add(new ExportFormat(SaveFormat.mRXML));
|
||||
cboFileFormat.Items.Add(new ExportFormat(SaveFormat.mRCSV));
|
||||
cboFileFormat.SelectedIndex = 0;
|
||||
ApplyTheme();
|
||||
ThemeManager.getInstance().ThemeChanged += ApplyTheme;
|
||||
@@ -211,7 +211,7 @@ namespace mRemoteNG.UI.Forms
|
||||
|
||||
private void SelectFileTypeBasedOnSaveFormat(FileDialog saveFileDialog)
|
||||
{
|
||||
saveFileDialog.FilterIndex = SaveFormat == ConnectionsSaver.Format.mRCSV ? 2 : 1;
|
||||
saveFileDialog.FilterIndex = SaveFormat == SaveFormat.mRCSV ? 2 : 1;
|
||||
}
|
||||
|
||||
private void btnOK_Click(object sender, EventArgs e)
|
||||
@@ -226,7 +226,7 @@ namespace mRemoteNG.UI.Forms
|
||||
|
||||
private void cboFileformat_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (SaveFormat == ConnectionsSaver.Format.mRXML)
|
||||
if (SaveFormat == SaveFormat.mRXML)
|
||||
{
|
||||
chkUsername.Enabled = false;
|
||||
chkPassword.Enabled = false;
|
||||
@@ -296,12 +296,12 @@ namespace mRemoteNG.UI.Forms
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
public ConnectionsSaver.Format Format { get; }
|
||||
public SaveFormat Format { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
public ExportFormat(ConnectionsSaver.Format format)
|
||||
public ExportFormat(SaveFormat format)
|
||||
{
|
||||
Format = format;
|
||||
}
|
||||
@@ -312,9 +312,9 @@ namespace mRemoteNG.UI.Forms
|
||||
{
|
||||
switch (Format)
|
||||
{
|
||||
case ConnectionsSaver.Format.mRXML:
|
||||
case SaveFormat.mRXML:
|
||||
return Language.strMremoteNgXml;
|
||||
case ConnectionsSaver.Format.mRCSV:
|
||||
case SaveFormat.mRCSV:
|
||||
return Language.strMremoteNgCsv;
|
||||
default:
|
||||
return Format.ToString();
|
||||
|
||||
@@ -69,7 +69,6 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
private static void ReinitializeSqlUpdater()
|
||||
{
|
||||
Runtime.RemoteConnectionsSyncronizer?.Dispose();
|
||||
FrmMain.Default.AreWeUsingSqlServerForSavingConnections = Settings.Default.UseSQLServer;
|
||||
|
||||
if (Settings.Default.UseSQLServer)
|
||||
{
|
||||
@@ -80,6 +79,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
Runtime.RemoteConnectionsSyncronizer?.Dispose();
|
||||
Runtime.RemoteConnectionsSyncronizer = null;
|
||||
Runtime.LoadConnections(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -449,7 +449,7 @@ namespace mRemoteNG.UI.Forms
|
||||
|
||||
if (Runtime.ConnectionsService.IsConnectionsFileLoaded)
|
||||
{
|
||||
if (AreWeUsingSqlServerForSavingConnections)
|
||||
if (Runtime.ConnectionsService.UsingDatabase)
|
||||
{
|
||||
titleBuilder.Append(separator);
|
||||
titleBuilder.Append(Language.strSQLServer.TrimEnd(':'));
|
||||
|
||||
@@ -6,7 +6,9 @@ using mRemoteNG.App;
|
||||
using mRemoteNG.App.Info;
|
||||
using mRemoteNG.Connection;
|
||||
using mRemoteNG.Container;
|
||||
using mRemoteNG.Security;
|
||||
using mRemoteNG.Tree;
|
||||
using mRemoteNG.UI.Forms;
|
||||
using mRemoteNG.UI.Window;
|
||||
|
||||
namespace mRemoteNG.UI.Menu
|
||||
@@ -358,7 +360,7 @@ namespace mRemoteNG.UI.Menu
|
||||
switch (msgBoxResult)
|
||||
{
|
||||
case DialogResult.Yes:
|
||||
Runtime.SaveConnections();
|
||||
Runtime.ConnectionsService.SaveConnections();
|
||||
break;
|
||||
case DialogResult.Cancel:
|
||||
return;
|
||||
@@ -375,7 +377,29 @@ namespace mRemoteNG.UI.Menu
|
||||
|
||||
private void mMenFileSaveAs_Click(object sender, EventArgs e)
|
||||
{
|
||||
Runtime.SaveConnectionsAs();
|
||||
using (var saveFileDialog = new SaveFileDialog())
|
||||
{
|
||||
saveFileDialog.CheckPathExists = true;
|
||||
saveFileDialog.InitialDirectory = ConnectionsFileInfo.DefaultConnectionsPath;
|
||||
saveFileDialog.FileName = ConnectionsFileInfo.DefaultConnectionsFile;
|
||||
saveFileDialog.OverwritePrompt = true;
|
||||
saveFileDialog.Filter = $@"{Language.strFiltermRemoteXML}|*.xml|{Language.strFilterAll}|*.*";
|
||||
|
||||
if (saveFileDialog.ShowDialog(FrmMain.Default) != DialogResult.OK) return;
|
||||
var newFileName = saveFileDialog.FileName;
|
||||
|
||||
Runtime.ConnectionsService.SaveConnections(Runtime.ConnectionsService.ConnectionTreeModel, false, new SaveFilter(), newFileName);
|
||||
|
||||
if (newFileName == Runtime.ConnectionsService.GetDefaultStartupConnectionFileName())
|
||||
{
|
||||
Settings.Default.LoadConsFromCustomLocation = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Settings.Default.LoadConsFromCustomLocation = true;
|
||||
Settings.Default.CustomConsPath = newFileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void mMenFileDelete_Click(object sender, EventArgs e)
|
||||
|
||||
@@ -134,12 +134,17 @@
|
||||
<Compile Include="App\Update\UpdateInfo.cs" />
|
||||
<Compile Include="App\Windows.cs" />
|
||||
<Compile Include="Config\Connections\ConnectionsLoadedEventArgs.cs" />
|
||||
<Compile Include="Config\Connections\ConnectionsSavedEventArgs.cs" />
|
||||
<Compile Include="Config\Connections\CsvConnectionsSaver.cs" />
|
||||
<Compile Include="Config\Connections\SaveFormat.cs" />
|
||||
<Compile Include="Config\Connections\Multiuser\ConnectionsUpdateCheckFinishedEventArgs.cs" />
|
||||
<Compile Include="Config\Connections\Multiuser\IConnectionsUpdateChecker.cs" />
|
||||
<Compile Include="Config\Connections\Multiuser\ConnectionsUpdateAvailableEventArgs.cs" />
|
||||
<Compile Include="Config\Connections\Multiuser\RemoteConnectionsSyncronizer.cs" />
|
||||
<Compile Include="Config\Connections\SqlConnectionsLoader.cs" />
|
||||
<Compile Include="Config\Connections\SqlConnectionsSaver.cs" />
|
||||
<Compile Include="Config\Connections\XmlConnectionsLoader.cs" />
|
||||
<Compile Include="Config\Connections\XmlConnectionsSaver.cs" />
|
||||
<Compile Include="Config\CredentialHarvester.cs" />
|
||||
<Compile Include="Config\CredentialRecordLoader.cs" />
|
||||
<Compile Include="Config\CredentialRecordSaver.cs" />
|
||||
@@ -175,8 +180,6 @@
|
||||
<Compile Include="Config\Serializers\Versioning\SqlVersion24To25Upgrader.cs" />
|
||||
<Compile Include="Config\Serializers\Versioning\SqlVersion25To26Upgrader.cs" />
|
||||
<Compile Include="Config\Serializers\XmlConnectionsDecryptor.cs" />
|
||||
<Compile Include="Config\Connections\ConnectionsLoader.cs" />
|
||||
<Compile Include="Config\Connections\ConnectionsSaver.cs" />
|
||||
<Compile Include="Config\DataProviders\FileDataProviderWithRollingBackup.cs" />
|
||||
<Compile Include="Config\DataProviders\SqlDataProvider.cs" />
|
||||
<Compile Include="Config\Serializers\IDeserializer.cs" />
|
||||
|
||||
Reference in New Issue
Block a user