From 2a55fbf1d40bba6bb9a38c802cb3e0ad2b93798d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Feb 2026 22:37:27 +0000 Subject: [PATCH 1/9] Initial plan From cb5d63224aa278ce89b85829f4ad7b045649cbe6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Feb 2026 22:40:48 +0000 Subject: [PATCH 2/9] Add dedicated variables reference page to documentation Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com> --- mRemoteNGDocumentation/index.rst | 1 + .../user_interface/external_tools.rst | 58 ++-------- .../variables_reference.rst | 102 ++++++++++++++++++ 3 files changed, 111 insertions(+), 50 deletions(-) create mode 100644 mRemoteNGDocumentation/variables_reference.rst diff --git a/mRemoteNGDocumentation/index.rst b/mRemoteNGDocumentation/index.rst index a3b37e3e1..97eb9e9c9 100644 --- a/mRemoteNGDocumentation/index.rst +++ b/mRemoteNGDocumentation/index.rst @@ -39,6 +39,7 @@ Welcome to mRemoteNG's documentation! :maxdepth: 2 :caption: Miscellaneous + variables_reference.rst external_tools_cheat_sheet.rst migrate.rst Contribute diff --git a/mRemoteNGDocumentation/user_interface/external_tools.rst b/mRemoteNGDocumentation/user_interface/external_tools.rst index d06e85447..385bdc5b1 100644 --- a/mRemoteNGDocumentation/user_interface/external_tools.rst +++ b/mRemoteNGDocumentation/user_interface/external_tools.rst @@ -100,7 +100,9 @@ Variables Variables and arguments can be used to tell the external tool what to do. -This is the list of variables supported by mRemoteNG: +For a complete list of available variables and their usage, see the :ref:`variables_reference` page. + +Quick Reference - Available Variables: - %NAME% - %HOSTNAME% @@ -112,53 +114,9 @@ This is the list of variables supported by mRemoteNG: - %MACADDRESS% - %USERFIELD% -mRemoteNG will also expand environment variables such as %PATH% and %USERPROFILE%. If you need to use an environment -variable with the same name as an mRemoteNG variable, use \\% instead of %. The most common use of this is for the -USERNAME environment variable. %USERNAME% will be expanded to the username set in the currently selected connection. -\\%USERNAME\\% will be expanded to the value set in the USERNAME environment variable. +See the :ref:`variables_reference` page for detailed information about: -If you need to send a variable name to a program without mRemoteNG expanding it, use ^% instead of %. -mRemoteNG will remove the caret (^) and leave the rest unchanged. -For example, ^%USERNAME^% will be sent to the program as %USERNAME% and will not be expanded. - -Rules for variables -------------------- -- Variables always refer to the currently selected connection. -- Variable names are case-insensitive. -- Variables can be used in both the Filename and Arguments fields. - - -Special Character Escaping -========================== -Expanded variables will be escaped using the rules below. There are two levels of escaping that are done. - -1. Is escaping for standard argument splitting (C/C++ argv, CommandLineToArgvW, etc) -2. Is escaping shell metacharacters for ShellExecute. - -Argument splitting escaping ---------------------------- - -- Each quotation mark will be escaped by a backslash -- One or more backslashes (\\) followed by a quotation mark ("): - - Each backslash will be escaped by another backslash - - The quotation mark will be escaped by a backslash - - If the connection's user field contains ``"This"`` is a ``\"test\"`` - - Then %USERFIELD% is replaced with ``\"This\"`` is a ``\\\"test\\\"`` -- A variable name followed by a quotation mark (for example, %USERFIELD%") with a value ending in one or more backslashes: - - Each backslash will be escaped by another backslash - - Example: - - If the connection's user field contains ``c:\Example\`` - - Then "%USERFIELD%" is replaced with ``"c:\Example\\"`` - -To disable argument splitting escaping for a variable, precede its name with a minus (-) sign. For example: %-USERFIELD% - -Shell metacharacter escaping ----------------------------- - -- The shell metacharacters are ( ) % ! ^ " < > & | -- Each shell metacharacter will be escaped by a caret (^) - -To disable both argument splitting and shell metacharacter escaping for a variable, precede its name with an exclamation point (!). -For example, %!USERFIELD%. This is not recommended and may cause unexpected results. - -Only variables that have been expanded will be escaped. It is up to you to escape the rest of the arguments. +- How to use environment variables +- How to prevent variable expansion +- Rules for using variables +- Special character escaping diff --git a/mRemoteNGDocumentation/variables_reference.rst b/mRemoteNGDocumentation/variables_reference.rst new file mode 100644 index 000000000..fdc152f31 --- /dev/null +++ b/mRemoteNGDocumentation/variables_reference.rst @@ -0,0 +1,102 @@ +.. _variables_reference: + +******************* +Variables Reference +******************* + +Variables can be used with External Tools to dynamically insert connection properties into commands and arguments. + +Available Variables +=================== + +mRemoteNG supports the following variables: + +%NAME% + The display name of the connection. + +%HOSTNAME% + The hostname or IP address of the connection. + +%PORT% + The port number for the connection. + +%USERNAME% + The username configured for the connection. + +%PASSWORD% + The password configured for the connection. + +%DOMAIN% + The domain configured for the connection. + +%DESCRIPTION% + The description text of the connection. + +%MACADDRESS% + The MAC address configured for the connection. + +%USERFIELD% + The custom user field configured for the connection. + +Environment Variables +====================== + +mRemoteNG will also expand environment variables such as %PATH% and %USERPROFILE%. If you need to use an environment +variable with the same name as an mRemoteNG variable, use \\% instead of %. The most common use of this is for the +USERNAME environment variable. %USERNAME% will be expanded to the username set in the currently selected connection. +\\%USERNAME\\% will be expanded to the value set in the USERNAME environment variable. + +Preventing Variable Expansion +============================== + +If you need to send a variable name to a program without mRemoteNG expanding it, use ^% instead of %. +mRemoteNG will remove the caret (^) and leave the rest unchanged. +For example, ^%USERNAME^% will be sent to the program as %USERNAME% and will not be expanded. + +Rules for Variables +=================== + +- Variables always refer to the currently selected connection. +- Variable names are case-insensitive. +- Variables can be used in both the Filename and Arguments fields in External Tools. + +Special Character Escaping +=========================== + +Expanded variables will be escaped using the rules below. There are two levels of escaping that are done: + +1. Escaping for standard argument splitting (C/C++ argv, CommandLineToArgvW, etc) +2. Escaping shell metacharacters for ShellExecute. + +Argument Splitting Escaping +---------------------------- + +- Each quotation mark will be escaped by a backslash +- One or more backslashes (\\) followed by a quotation mark ("): + - Each backslash will be escaped by another backslash + - The quotation mark will be escaped by a backslash + - If the connection's user field contains ``"This"`` is a ``\"test\"`` + - Then %USERFIELD% is replaced with ``\"This\"`` is a ``\\\"test\\\"`` +- A variable name followed by a quotation mark (for example, %USERFIELD%") with a value ending in one or more backslashes: + - Each backslash will be escaped by another backslash + - Example: + - If the connection's user field contains ``c:\Example\`` + - Then "%USERFIELD%" is replaced with ``"c:\Example\\"`` + +To disable argument splitting escaping for a variable, precede its name with a minus (-) sign. For example: %-USERFIELD% + +Shell Metacharacter Escaping +----------------------------- + +- The shell metacharacters are ( ) % ! ^ " < > & | +- Each shell metacharacter will be escaped by a caret (^) + +To disable both argument splitting and shell metacharacter escaping for a variable, precede its name with an exclamation point (!). +For example, %!USERFIELD%. This is not recommended and may cause unexpected results. + +Only variables that have been expanded will be escaped. It is up to you to escape the rest of the arguments. + +See Also +======== + +- :ref:`external_tools` - For information on using variables with External Tools From 27dd79c940d494e537a08c3ec87de0b0218021c5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Feb 2026 22:41:55 +0000 Subject: [PATCH 3/9] Add 'parameters' keyword to improve search discoverability Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com> --- mRemoteNGDocumentation/variables_reference.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mRemoteNGDocumentation/variables_reference.rst b/mRemoteNGDocumentation/variables_reference.rst index fdc152f31..357477888 100644 --- a/mRemoteNGDocumentation/variables_reference.rst +++ b/mRemoteNGDocumentation/variables_reference.rst @@ -4,7 +4,7 @@ Variables Reference ******************* -Variables can be used with External Tools to dynamically insert connection properties into commands and arguments. +Variables (also called parameters) can be used with External Tools to dynamically insert connection properties into commands and arguments. Available Variables =================== From b127968a6c26169e0b1a8a8fd6396f24da13bf91 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Feb 2026 22:42:26 +0000 Subject: [PATCH 4/9] Add cross-references to variables page from howtos and cheat sheet Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com> --- mRemoteNGDocumentation/external_tools_cheat_sheet.rst | 4 ++++ mRemoteNGDocumentation/howtos/external_tools.rst | 2 ++ 2 files changed, 6 insertions(+) diff --git a/mRemoteNGDocumentation/external_tools_cheat_sheet.rst b/mRemoteNGDocumentation/external_tools_cheat_sheet.rst index d6ffe9ea5..6adc18719 100644 --- a/mRemoteNGDocumentation/external_tools_cheat_sheet.rst +++ b/mRemoteNGDocumentation/external_tools_cheat_sheet.rst @@ -5,6 +5,10 @@ Common External Tool Configurations The list below of various examples is by no means a full list of ways to use **External Tools** but gives you a idea of how it can be used in different ways. +.. note:: + These examples use variables like %HOSTNAME%, %USERNAME%, etc. + For a complete list of available variables, see the :ref:`variables_reference` page. + Ping ==== Ping a server via cmdline. diff --git a/mRemoteNGDocumentation/howtos/external_tools.rst b/mRemoteNGDocumentation/howtos/external_tools.rst index be247e7a5..59eb814f8 100644 --- a/mRemoteNGDocumentation/howtos/external_tools.rst +++ b/mRemoteNGDocumentation/howtos/external_tools.rst @@ -23,6 +23,8 @@ What we are going to use is the following for our entry: - Protocol - sftp:// - Input Parameters (variables) - %HOSTNAME%, %USERNAME%,%PASSWORD% and %PORT% +For a complete list of available variables, see the :ref:`variables_reference` page. + All of the variables are parsed from mRemoteNG connection item to the filezilla command line. So lets build this entry up in **External Tools** where we add all these items. From 4328d36a1d2f30210b2cdbd584ec723cbb7872d7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 12:39:08 +0000 Subject: [PATCH 5/9] Update dependency System.ValueTuple to 4.6.2 --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 317cbdc76..7d762084e 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -95,7 +95,7 @@ - + From 1a0de7cb2dafe2ce3fef5b9867adf394ca780715 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 13:32:08 +0000 Subject: [PATCH 6/9] Update dependency log4net to 3.3.0 --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 7d762084e..4e3e5e3bd 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -19,7 +19,7 @@ - + From fd41e27d474a2a50bccd519d429e310d358b4c9f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Feb 2026 13:54:30 +0000 Subject: [PATCH 7/9] Initial plan From 0b7fd5b5f57c1b465f33db5449f9d14b466044ce Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Feb 2026 14:02:53 +0000 Subject: [PATCH 8/9] Add ODBC support for database connection list storage Co-authored-by: Kvarkas <3611964+Kvarkas@users.noreply.github.com> --- Directory.Packages.props | 1 + .../DatabaseConnectionTester.cs | 147 +++--------------- .../DatabaseConnectorFactory.cs | 2 + .../OdbcDatabaseConnector.cs | 106 +++++++++++++ mRemoteNG/mRemoteNG.csproj | 1 + 5 files changed, 128 insertions(+), 129 deletions(-) create mode 100644 mRemoteNG/Config/DatabaseConnectors/OdbcDatabaseConnector.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 4e3e5e3bd..04c2d5136 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -62,6 +62,7 @@ + diff --git a/mRemoteNG/Config/DatabaseConnectors/DatabaseConnectionTester.cs b/mRemoteNG/Config/DatabaseConnectors/DatabaseConnectionTester.cs index 5165e024a..94331329d 100644 --- a/mRemoteNG/Config/DatabaseConnectors/DatabaseConnectionTester.cs +++ b/mRemoteNG/Config/DatabaseConnectors/DatabaseConnectionTester.cs @@ -1,149 +1,38 @@ -using System; -using Microsoft.Data.SqlClient; +using System; using System.Runtime.Versioning; using System.Threading.Tasks; -using System.Runtime.InteropServices; -using LiteDB; -using mRemoteNG.Resources.Language; namespace mRemoteNG.Config.DatabaseConnectors { - //[SupportedOSPlatform("windows")] /// - /// A helper class for testing database connectivity + /// A helper class for testing database connectivity. /// - /// - using System; - using System.Data.SqlClient; - + [SupportedOSPlatform("windows")] public class DatabaseConnectionTester { public async Task TestConnectivity(string type, string server, string database, string username, string password) { try { - // Build the connection string based on the provided parameters - string connectionString = $"Data Source={server};Initial Catalog={database};User ID={username};Password={password}"; - - // Attempt to open a connection to the database - using (SqlConnection connection = new SqlConnection(connectionString)) - { - await connection.OpenAsync(); - } - + using IDatabaseConnector dbConnector = DatabaseConnectorFactory.DatabaseConnector(type, server, database, username, password); + await dbConnector.ConnectAsync(); return ConnectionTestResult.ConnectionSucceded; } - catch (SqlException ex) + catch (Exception ex) { - // Handle specific SQL exceptions - switch (ex.Number) - { - case 4060: // Invalid Database - return ConnectionTestResult.UnknownDatabase; - case 18456: // Login Failed - return ConnectionTestResult.CredentialsRejected; - case -1: // Server not accessible - return ConnectionTestResult.ServerNotAccessible; - default: - return ConnectionTestResult.UnknownError; - } - } - catch - { - // Handle any other exceptions + string message = ex.Message; + if (message.Contains("server was not found", StringComparison.OrdinalIgnoreCase) + || message.Contains("network-related", StringComparison.OrdinalIgnoreCase) + || message.Contains("instance-specific", StringComparison.OrdinalIgnoreCase)) + return ConnectionTestResult.ServerNotAccessible; + if (message.Contains("Cannot open database", StringComparison.OrdinalIgnoreCase) + || message.Contains("Unknown database", StringComparison.OrdinalIgnoreCase)) + return ConnectionTestResult.UnknownDatabase; + if (message.Contains("Login failed", StringComparison.OrdinalIgnoreCase) + || message.Contains("Access denied", StringComparison.OrdinalIgnoreCase)) + return ConnectionTestResult.CredentialsRejected; return ConnectionTestResult.UnknownError; } } } - //public class DatabaseConnectionTester - //{ - //public async Task TestConnectivity(string type, string server, string database, string username, string password) - //{ - //using IDatabaseConnector dbConnector = DatabaseConnectorFactory.DatabaseConnector(type, server, database, username, password); - //try - //{ - // Validate architecture compatibility - //if (!Environment.Is64BitProcess) - //{ - // throw new PlatformNotSupportedException("The application must run in a 64-bit process to use this database connector."); - // } - - // Attempt to connect - - //using (SqlConnection connection = new SqlConnection("Data Source=172.22.155.100,1433;Initial Catalog=Demo;Integrated Security=False;User ID=sa;Password=London123;Multiple Active Result Sets=True;Connect Timeout=30;Encrypt=True;Trust Server Certificate=True;Application Name=mRemoteNG;Application Intent=ReadOnly")) - //{ - // connection.Open(); - // Console.WriteLine("Connection successful!"); - //} - //Console.WriteLine($"{RuntimeInformation.OSArchitecture}"); - //Console.WriteLine($"{RuntimeInformation.ProcessArchitecture}"); - //try - //{ - // using (SqlConnection connection = new SqlConnection("Data Source=172.22.155.100,1433;Initial Catalog=Demo;Integrated Security=False;User ID=sa;Password=London123;Multiple Active Result Sets=True;Connect Timeout=30;Encrypt=True;Trust Server Certificate=True;Application Name=mRemoteNG;Application Intent=ReadOnly")) - // { - // connection.Open(); - // Console.WriteLine("Connection successful!"); - // } - //} - //catch (Exception ex) - //{ - // Console.WriteLine($"Connection failed: {ex.Message}"); - //} - //} -/* - - - try - { - using (SqlConnection connection = new SqlConnection("Data Source=172.22.155.100,1433;Initial Catalog=Demo;Integrated Security=False;User ID=sa;Password=London123;Multiple Active Result Sets=True;Connect Timeout=30;Encrypt=True;Trust Server Certificate=True;Application Name=mRemoteNG;Application Intent=ReadOnly")) - { - connection.Open(); - } - } - catch (TypeInitializationException ex) - { - Console.WriteLine($"Type initialization error: {ex.InnerException?.Message}"); - } - - - //await dbConnector.ConnectAsync(); - return ConnectionTestResult.ConnectionSucceded; - } - catch (PlatformNotSupportedException ex) - { - // Log or handle architecture mismatch - Console.WriteLine(string.Format(Language.ErrorPlatformNotSupported, ex.Message)); - return ConnectionTestResult.UnknownError; - } - catch (DllNotFoundException ex) - { - // Handle missing native dependencies - Console.WriteLine(string.Format(Language.ErrorMissingDependency, ex.Message)); - return ConnectionTestResult.UnknownError; - } - catch (BadImageFormatException ex) - { - // Handle architecture mismatch in native libraries - Console.WriteLine(string.Format(Language.ErrorArchitectureMismatch, ex.Message)); - return ConnectionTestResult.UnknownError; - } - catch (SqlException sqlException) - { - if (sqlException.Message.Contains("The server was not found")) - return ConnectionTestResult.ServerNotAccessible; - if (sqlException.Message.Contains("Cannot open database")) - return ConnectionTestResult.UnknownDatabase; - if (sqlException.Message.Contains("Login failed for user")) - return ConnectionTestResult.CredentialsRejected; - return ConnectionTestResult.UnknownError; - } - catch (Exception ex) - { - // Log unexpected errors - Console.WriteLine($"Unexpected error: {ex.Message}"); - return ConnectionTestResult.UnknownError; - } -*/ - // } - // } -} \ No newline at end of file +} diff --git a/mRemoteNG/Config/DatabaseConnectors/DatabaseConnectorFactory.cs b/mRemoteNG/Config/DatabaseConnectors/DatabaseConnectorFactory.cs index da82f5019..1b0468e00 100644 --- a/mRemoteNG/Config/DatabaseConnectors/DatabaseConnectorFactory.cs +++ b/mRemoteNG/Config/DatabaseConnectors/DatabaseConnectorFactory.cs @@ -26,6 +26,8 @@ namespace mRemoteNG.Config.DatabaseConnectors { case "mysql": return new MySqlDatabaseConnector(server, database, username, password); + case "odbc": + return new OdbcDatabaseConnector(server, username, password); case "mssql": default: return new MSSqlDatabaseConnector(server, database, username, password); diff --git a/mRemoteNG/Config/DatabaseConnectors/OdbcDatabaseConnector.cs b/mRemoteNG/Config/DatabaseConnectors/OdbcDatabaseConnector.cs new file mode 100644 index 000000000..a8793bfe4 --- /dev/null +++ b/mRemoteNG/Config/DatabaseConnectors/OdbcDatabaseConnector.cs @@ -0,0 +1,106 @@ +using System.Data; +using System.Data.Common; +using System.Data.Odbc; +using System.Threading.Tasks; + +// ReSharper disable ArrangeAccessorOwnerBody + +namespace mRemoteNG.Config.DatabaseConnectors +{ + public class OdbcDatabaseConnector : IDatabaseConnector + { + private DbConnection _dbConnection { get; set; } = default(OdbcConnection); + private string _dbConnectionString = ""; + private readonly string _connectionString; + private readonly string _dbUsername; + private readonly string _dbPassword; + + public DbConnection DbConnection() + { + return _dbConnection; + } + + public DbCommand DbCommand(string dbCommand) + { + return new OdbcCommand(dbCommand, (OdbcConnection) _dbConnection); + } + + public bool IsConnected => (_dbConnection.State == ConnectionState.Open); + + /// + /// Creates an ODBC database connector. + /// + /// + /// An ODBC connection string or DSN name. If a plain DSN name is provided (no '=' character), + /// it is automatically wrapped as "DSN=<name>". + /// + /// Optional user name appended to the connection string as UID. + /// Optional password appended to the connection string as PWD. + public OdbcDatabaseConnector(string connectionString, string username, string password) + { + _connectionString = connectionString; + _dbUsername = username; + _dbPassword = password; + Initialize(); + } + + private void Initialize() + { + BuildConnectionString(); + _dbConnection = new OdbcConnection(_dbConnectionString); + } + + private void BuildConnectionString() + { + // If no '=' present in the provided string it is a plain DSN name. + string baseString = _connectionString.Contains('=') + ? _connectionString + : $"DSN={_connectionString}"; + + OdbcConnectionStringBuilder builder = new() + { + ConnectionString = baseString + }; + + if (!string.IsNullOrEmpty(_dbUsername)) + builder["UID"] = _dbUsername; + + if (!string.IsNullOrEmpty(_dbPassword)) + builder["PWD"] = _dbPassword; + + _dbConnectionString = builder.ConnectionString; + } + + public void Connect() + { + _dbConnection.Open(); + } + + public async Task ConnectAsync() + { + await _dbConnection.OpenAsync(); + } + + public void Disconnect() + { + _dbConnection.Close(); + } + + public void AssociateItemToThisConnector(DbCommand dbCommand) + { + dbCommand.Connection = (OdbcConnection) _dbConnection; + } + + public void Dispose() + { + Dispose(true); + } + + private void Dispose(bool itIsSafeToFreeManagedObjects) + { + if (!itIsSafeToFreeManagedObjects) return; + _dbConnection.Close(); + _dbConnection.Dispose(); + } + } +} diff --git a/mRemoteNG/mRemoteNG.csproj b/mRemoteNG/mRemoteNG.csproj index f978e8381..f6a18b11b 100644 --- a/mRemoteNG/mRemoteNG.csproj +++ b/mRemoteNG/mRemoteNG.csproj @@ -138,6 +138,7 @@ + From 12f2942202e663e8f086c596a0ddf17fad9d22ca Mon Sep 17 00:00:00 2001 From: Dimitrij Date: Fri, 20 Feb 2026 14:27:04 +0000 Subject: [PATCH 9/9] Update mRemoteNG/Config/DatabaseConnectors/DatabaseConnectorFactory.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- mRemoteNG/Config/DatabaseConnectors/DatabaseConnectorFactory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mRemoteNG/Config/DatabaseConnectors/DatabaseConnectorFactory.cs b/mRemoteNG/Config/DatabaseConnectors/DatabaseConnectorFactory.cs index 1b0468e00..a54b06a00 100644 --- a/mRemoteNG/Config/DatabaseConnectors/DatabaseConnectorFactory.cs +++ b/mRemoteNG/Config/DatabaseConnectors/DatabaseConnectorFactory.cs @@ -27,7 +27,7 @@ namespace mRemoteNG.Config.DatabaseConnectors case "mysql": return new MySqlDatabaseConnector(server, database, username, password); case "odbc": - return new OdbcDatabaseConnector(server, username, password); + throw new NotSupportedException("ODBC database connections are not supported for schema initialization. Please use a supported database backend."); case "mssql": default: return new MSSqlDatabaseConnector(server, database, username, password);