137 lines
4.4 KiB
C#
137 lines
4.4 KiB
C#
using FluentTerminal.App.Services;
|
|
using FluentTerminal.Models;
|
|
using FluentTerminal.Models.Enums;
|
|
using FluentTerminal.Models.Requests;
|
|
using FluentTerminal.Models.Responses;
|
|
using FluentTerminal.SystemTray.Services.ConPty;
|
|
using FluentTerminal.SystemTray.Services.WinPty;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Text;
|
|
using Windows.ApplicationModel;
|
|
|
|
namespace FluentTerminal.SystemTray.Services
|
|
{
|
|
public class TerminalsManager
|
|
{
|
|
private readonly Dictionary<int, ITerminalSession> _terminals = new Dictionary<int, ITerminalSession>();
|
|
private readonly ISettingsService _settingsService;
|
|
|
|
public event EventHandler<DisplayTerminalOutputRequest> DisplayOutputRequested;
|
|
|
|
public event EventHandler<int> TerminalExited;
|
|
|
|
public TerminalsManager(ISettingsService settingsService)
|
|
{
|
|
_settingsService = settingsService;
|
|
}
|
|
|
|
public void DisplayTerminalOutput(int terminalId, byte[] output)
|
|
{
|
|
DisplayOutputRequested?.Invoke(this, new DisplayTerminalOutputRequest
|
|
{
|
|
TerminalId = terminalId,
|
|
Output = output
|
|
});
|
|
}
|
|
|
|
public CreateTerminalResponse CreateTerminal(CreateTerminalRequest request)
|
|
{
|
|
if (_terminals.ContainsKey(request.Id))
|
|
{
|
|
// App terminated without cleaning up, removing orphaned sessions
|
|
foreach (var item in _terminals.Values)
|
|
{
|
|
item.Dispose();
|
|
}
|
|
_terminals.Clear();
|
|
}
|
|
|
|
ITerminalSession terminal = null;
|
|
try
|
|
{
|
|
if (request.SessionType == SessionType.WinPty)
|
|
{
|
|
terminal = new WinPtySession();
|
|
}
|
|
else if (request.SessionType == SessionType.ConPty)
|
|
{
|
|
terminal = new ConPtySession();
|
|
}
|
|
terminal.Start(request, this);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
return new CreateTerminalResponse { Error = e.ToString() };
|
|
}
|
|
|
|
terminal.ConnectionClosed += OnTerminalConnectionClosed;
|
|
_terminals.Add(terminal.Id, terminal);
|
|
return new CreateTerminalResponse
|
|
{
|
|
Success = true,
|
|
ShellExecutableName = terminal.ShellExecutableName
|
|
};
|
|
}
|
|
|
|
public void Write(int id, byte[] data)
|
|
{
|
|
if (_terminals.TryGetValue(id, out ITerminalSession terminal))
|
|
{
|
|
terminal.Write(data);
|
|
}
|
|
}
|
|
|
|
public void ResizeTerminal(int id, TerminalSize size)
|
|
{
|
|
if (_terminals.TryGetValue(id, out ITerminalSession terminal))
|
|
{
|
|
terminal.Resize(size);
|
|
}
|
|
else
|
|
{
|
|
Debug.WriteLine($"ResizeTerminal: terminal with id '{id}' was not found");
|
|
}
|
|
}
|
|
|
|
public void CloseTerminal(int id)
|
|
{
|
|
if (_terminals.TryGetValue(id, out ITerminalSession terminal))
|
|
{
|
|
_terminals.Remove(terminal.Id);
|
|
terminal.Close();
|
|
}
|
|
}
|
|
|
|
public string GetDefaultEnvironmentVariableString()
|
|
{
|
|
var environmentVariables = Environment.GetEnvironmentVariables();
|
|
environmentVariables["TERM"] = "xterm-256color";
|
|
environmentVariables["TERM_PROGRAM"] = "FluentTerminal";
|
|
environmentVariables["TERM_PROGRAM_VERSION"] = $"{Package.Current.Id.Version.Major}.{Package.Current.Id.Version.Minor}.{Package.Current.Id.Version.Build}.{Package.Current.Id.Version.Revision}";
|
|
|
|
var builder = new StringBuilder();
|
|
|
|
foreach (DictionaryEntry item in environmentVariables)
|
|
{
|
|
builder.Append(item.Key).Append("=").Append(item.Value).Append("\0");
|
|
}
|
|
builder.Append('\0');
|
|
|
|
return builder.ToString();
|
|
}
|
|
|
|
private void OnTerminalConnectionClosed(object sender, System.EventArgs e)
|
|
{
|
|
if (sender is ITerminalSession terminal)
|
|
{
|
|
_terminals.Remove(terminal.Id);
|
|
terminal.Dispose();
|
|
TerminalExited?.Invoke(this, terminal.Id);
|
|
}
|
|
}
|
|
}
|
|
}
|