diff --git a/mRemoteNG/Connection/ConnectionInfo.cs b/mRemoteNG/Connection/ConnectionInfo.cs
index 095fc473..147e50b9 100644
--- a/mRemoteNG/Connection/ConnectionInfo.cs
+++ b/mRemoteNG/Connection/ConnectionInfo.cs
@@ -8,6 +8,7 @@ using mRemoteNG.Connection.Protocol;
using mRemoteNG.Connection.Protocol.ARD;
using mRemoteNG.Connection.Protocol.Http;
using mRemoteNG.Connection.Protocol.PowerShell;
+using mRemoteNG.Connection.Protocol.Terminal;
using mRemoteNG.Connection.Protocol.RAW;
using mRemoteNG.Connection.Protocol.RDP;
using mRemoteNG.Connection.Protocol.Rlogin;
@@ -275,6 +276,8 @@ namespace mRemoteNG.Connection
return (int)ProtocolPowerShell.Defaults.Port;
case ProtocolType.WSL:
return (int)ProtocolWSL.Defaults.Port;
+ case ProtocolType.Terminal:
+ return (int)ProtocolTerminal.Defaults.Port;
case ProtocolType.IntApp:
return (int)IntegratedProgram.Defaults.Port;
}
diff --git a/mRemoteNG/Connection/Protocol/ProtocolFactory.cs b/mRemoteNG/Connection/Protocol/ProtocolFactory.cs
index 42017f56..110a4b5d 100644
--- a/mRemoteNG/Connection/Protocol/ProtocolFactory.cs
+++ b/mRemoteNG/Connection/Protocol/ProtocolFactory.cs
@@ -9,6 +9,7 @@ using mRemoteNG.Connection.Protocol.ARD;
using System;
using mRemoteNG.Connection.Protocol.PowerShell;
using mRemoteNG.Connection.Protocol.WSL;
+using mRemoteNG.Connection.Protocol.Terminal;
using mRemoteNG.Resources.Language;
using System.Runtime.Versioning;
@@ -50,6 +51,8 @@ namespace mRemoteNG.Connection.Protocol
return new ProtocolPowerShell(connectionInfo);
case ProtocolType.WSL:
return new ProtocolWSL(connectionInfo);
+ case ProtocolType.Terminal:
+ return new ProtocolTerminal(connectionInfo);
case ProtocolType.IntApp:
if (connectionInfo.ExtApp == "")
{
diff --git a/mRemoteNG/Connection/Protocol/ProtocolType.cs b/mRemoteNG/Connection/Protocol/ProtocolType.cs
index b9a32a8f..20af662b 100644
--- a/mRemoteNG/Connection/Protocol/ProtocolType.cs
+++ b/mRemoteNG/Connection/Protocol/ProtocolType.cs
@@ -40,6 +40,8 @@ namespace mRemoteNG.Connection.Protocol
[LocalizedAttributes.LocalizedDescription(nameof(Language.Wsl))]
WSL = 12,
+ [LocalizedAttributes.LocalizedDescription(nameof(Language.Terminal))]
+ Terminal = 12,
[LocalizedAttributes.LocalizedDescription(nameof(Language.ExternalTool))]
IntApp = 20
@@ -50,6 +52,7 @@ namespace mRemoteNG.Connection.Protocol
public static bool SupportBlankHostname(ProtocolType protocolType)
{
return (protocolType == ProtocolType.IntApp || protocolType == ProtocolType.PowerShell || protocolType == ProtocolType.WSL);
+ return (protocolType == ProtocolType.IntApp || protocolType == ProtocolType.PowerShell || protocolType == ProtocolType.Terminal);
}
}
}
\ No newline at end of file
diff --git a/mRemoteNG/Connection/Protocol/Terminal/Connection.Protocol.Terminal.cs b/mRemoteNG/Connection/Protocol/Terminal/Connection.Protocol.Terminal.cs
new file mode 100644
index 00000000..4116975a
--- /dev/null
+++ b/mRemoteNG/Connection/Protocol/Terminal/Connection.Protocol.Terminal.cs
@@ -0,0 +1,155 @@
+using System;
+using System.Drawing;
+using System.Runtime.Versioning;
+using System.Windows.Forms;
+using mRemoteNG.App;
+using mRemoteNG.Messages;
+using mRemoteNG.Resources.Language;
+
+namespace mRemoteNG.Connection.Protocol.Terminal
+{
+ [SupportedOSPlatform("windows")]
+ public class ProtocolTerminal(ConnectionInfo connectionInfo) : ProtocolBase
+ {
+ #region Private Fields
+
+ private IntPtr _handle;
+ private readonly ConnectionInfo _connectionInfo = connectionInfo;
+ private ConsoleControl.ConsoleControl _consoleControl;
+
+ #endregion
+
+ #region Public Methods
+
+ public override bool Connect()
+ {
+ try
+ {
+ Runtime.MessageCollector?.AddMessage(MessageClass.InformationMsg, "Attempting to start Terminal session.", true);
+
+ _consoleControl = new ConsoleControl.ConsoleControl
+ {
+ Dock = DockStyle.Fill,
+ BackColor = ColorTranslator.FromHtml("#012456"),
+ ForeColor = Color.White,
+ IsInputEnabled = true,
+ Padding = new Padding(0, 20, 0, 0)
+ };
+
+ // Path to command prompt - dynamically determined from system
+ // Using COMSPEC environment variable which points to the system's command processor
+ string terminalExe = Environment.GetEnvironmentVariable("COMSPEC") ?? @"C:\Windows\System32\cmd.exe";
+
+ // Setup arguments based on whether hostname is provided
+ string arguments = "";
+ string hostname = _connectionInfo.Hostname.Trim().ToLower();
+ bool useLocalHost = hostname == "" || hostname.Equals("localhost");
+
+ if (!useLocalHost)
+ {
+ // If hostname is provided, try to connect via SSH
+ // Note: Domain field is not used for SSH as it's Windows-specific
+ // SSH authentication will use standard SSH mechanisms (password prompt, keys, etc.)
+ string username = _connectionInfo.Username;
+ int port = _connectionInfo.Port;
+
+ // Build SSH command
+ string sshCommand = "ssh";
+
+ // Add port if it's not the default SSH port (22)
+ if (port > 0 && port != 22)
+ {
+ sshCommand += $" -p {port}";
+ }
+
+ if (!string.IsNullOrEmpty(username))
+ {
+ sshCommand += $" {username}@{_connectionInfo.Hostname}";
+ }
+ else
+ {
+ sshCommand += $" {_connectionInfo.Hostname}";
+ }
+
+ arguments = $"/K {sshCommand}";
+ }
+ else
+ {
+ // For local sessions, just start cmd with /K to keep it open
+ arguments = "/K";
+ }
+
+ _consoleControl.StartProcess(terminalExe, arguments);
+
+ // Wait for the console control to create its handle
+ int maxWaitMs = 5000; // 5 seconds timeout
+ long startTicks = Environment.TickCount64;
+ while (!_consoleControl.IsHandleCreated &&
+ Environment.TickCount64 < startTicks + maxWaitMs)
+ {
+ System.Threading.Thread.Sleep(50);
+ }
+
+ if (!_consoleControl.IsHandleCreated)
+ {
+ throw new Exception("Failed to initialize terminal console within 5 seconds. This may indicate system resource constraints or permission issues.");
+ }
+
+ _handle = _consoleControl.Handle;
+ NativeMethods.SetParent(_handle, InterfaceControl.Handle);
+
+ Resize(this, new EventArgs());
+ base.Connect();
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Runtime.MessageCollector?.AddExceptionMessage(Language.ConnectionFailed, ex);
+ return false;
+ }
+ }
+
+ public override void Focus()
+ {
+ try
+ {
+ NativeMethods.SetForegroundWindow(_handle);
+ }
+ catch (Exception ex)
+ {
+ Runtime.MessageCollector.AddExceptionMessage(Language.IntAppFocusFailed, ex);
+ }
+ }
+
+ protected override void Resize(object sender, EventArgs e)
+ {
+ try
+ {
+ if (InterfaceControl.Size == Size.Empty) return;
+ // Use ClientRectangle to account for padding (for connection frame color)
+ Rectangle clientRect = InterfaceControl.ClientRectangle;
+ NativeMethods.MoveWindow(_handle,
+ clientRect.X - SystemInformation.FrameBorderSize.Width,
+ clientRect.Y - (SystemInformation.CaptionHeight + SystemInformation.FrameBorderSize.Height),
+ clientRect.Width + SystemInformation.FrameBorderSize.Width * 2,
+ clientRect.Height + SystemInformation.CaptionHeight +
+ SystemInformation.FrameBorderSize.Height * 2, true);
+ }
+ catch (Exception ex)
+ {
+ Runtime.MessageCollector.AddExceptionMessage(Language.IntAppResizeFailed, ex);
+ }
+ }
+
+ #endregion
+
+ #region Enumerations
+
+ public enum Defaults
+ {
+ Port = 22
+ }
+
+ #endregion
+ }
+}
diff --git a/mRemoteNG/Language/Language.fr.resx b/mRemoteNG/Language/Language.fr.resx
index b6d30075..92609590 100644
--- a/mRemoteNG/Language/Language.fr.resx
+++ b/mRemoteNG/Language/Language.fr.resx
@@ -2105,6 +2105,9 @@ Le canal nightly inclut les versions alpha, beta et release candidates.
PowerShell
+
+ Terminal
+
Historique des modifications
diff --git a/mRemoteNG/Language/Language.pl.resx b/mRemoteNG/Language/Language.pl.resx
index d35c8940..b48f4b45 100644
--- a/mRemoteNG/Language/Language.pl.resx
+++ b/mRemoteNG/Language/Language.pl.resx
@@ -2152,6 +2152,9 @@ Kanał nocny obejmuje wersje alfa, beta i RC (gotowe do wydania).
PowerShell
+
+ Terminal
+
Dziennik zmian
diff --git a/mRemoteNG/Language/Language.resx b/mRemoteNG/Language/Language.resx
index 5bbe26b2..83b9c5c7 100644
--- a/mRemoteNG/Language/Language.resx
+++ b/mRemoteNG/Language/Language.resx
@@ -2194,6 +2194,9 @@ Nightly Channel includes Alphas, Betas & Release Candidates.
PowerShell
+
+ Terminal
+
Changelog
diff --git a/mRemoteNG/Language/Language.ta.resx b/mRemoteNG/Language/Language.ta.resx
index f213fc51..b6b7befb 100644
--- a/mRemoteNG/Language/Language.ta.resx
+++ b/mRemoteNG/Language/Language.ta.resx
@@ -2155,6 +2155,9 @@
ஆற்றல்ஓடு
+
+ Terminal
+
மாற்றபதிவு
diff --git a/mRemoteNG/Language/Language.zh-CN.resx b/mRemoteNG/Language/Language.zh-CN.resx
index be5715ab..5d23e814 100644
--- a/mRemoteNG/Language/Language.zh-CN.resx
+++ b/mRemoteNG/Language/Language.zh-CN.resx
@@ -2074,6 +2074,9 @@ mRemoteNG 将退出并安装更新。
PowerShell
+
+ Terminal
+
网关