Merge branch 'v1.78.2-dev' into copilot/add-wsl-connection-protocol

This commit is contained in:
Dimitrij
2025-10-19 21:55:39 +01:00
committed by GitHub
9 changed files with 179 additions and 0 deletions

View File

@@ -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;
}

View File

@@ -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 == "")
{

View File

@@ -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);
}
}
}

View File

@@ -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
}
}

View File

@@ -2105,6 +2105,9 @@ Le canal nightly inclut les versions alpha, beta et release candidates.</value>
<data name="PowerShell" xml:space="preserve">
<value>PowerShell</value>
</data>
<data name="Terminal" xml:space="preserve">
<value>Terminal</value>
</data>
<data name="Changelog" xml:space="preserve">
<value>Historique des modifications</value>
</data>

View File

@@ -2152,6 +2152,9 @@ Kanał nocny obejmuje wersje alfa, beta i RC (gotowe do wydania).</value>
<data name="PowerShell" xml:space="preserve">
<value>PowerShell</value>
</data>
<data name="Terminal" xml:space="preserve">
<value>Terminal</value>
</data>
<data name="Changelog" xml:space="preserve">
<value>Dziennik zmian</value>
</data>

View File

@@ -2194,6 +2194,9 @@ Nightly Channel includes Alphas, Betas &amp; Release Candidates.</value>
<data name="PowerShell" xml:space="preserve">
<value>PowerShell</value>
</data>
<data name="Terminal" xml:space="preserve">
<value>Terminal</value>
</data>
<data name="Changelog" xml:space="preserve">
<value>Changelog</value>
</data>

View File

@@ -2155,6 +2155,9 @@
<data name="PowerShell" xml:space="preserve">
<value>ஆற்றல்ஓடு</value>
</data>
<data name="Terminal" xml:space="preserve">
<value>Terminal</value>
</data>
<data name="Changelog" xml:space="preserve">
<value>மாற்றபதிவு</value>
</data>

View File

@@ -2074,6 +2074,9 @@ mRemoteNG 将退出并安装更新。</value>
<data name="PowerShell" xml:space="preserve">
<value>PowerShell</value>
</data>
<data name="Terminal" xml:space="preserve">
<value>Terminal</value>
</data>
<data name="Gateway" xml:space="preserve">
<value>网关</value>
</data>