Files
FluentTerminal/FluentTerminal.SystemTray/Services/ConPty/ConPtySession.cs
T
Felix d52860e90a Dev/renderer neutral (#220)
* Encapsulate xterm.js implementation in XtermTerminalView

* fix TerminalTheme Equals()

* Fix new output indicator

* Ut8 and some fixes

* fix test

* fixed infinite loop on shell exit
2019-03-06 20:06:19 +01:00

117 lines
3.4 KiB
C#

using FluentTerminal.Models;
using FluentTerminal.Models.Requests;
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace FluentTerminal.SystemTray.Services.ConPty
{
public class ConPtySession : ITerminalSession
{
private TerminalsManager _terminalsManager;
private Terminal _terminal;
private bool _exited;
public int Id { get; private set; }
public string ShellExecutableName { get; private set; }
public event EventHandler ConnectionClosed;
public void Close()
{
ConnectionClosed?.Invoke(this, EventArgs.Empty);
}
public void Resize(TerminalSize size)
{
_terminal.Resize(size.Columns, size.Rows);
}
public void Start(CreateTerminalRequest request, TerminalsManager terminalsManager)
{
Id = request.Id;
_terminalsManager = terminalsManager;
ShellExecutableName = Path.GetFileNameWithoutExtension(request.Profile.Location);
var cwd = GetWorkingDirectory(request.Profile);
string args = $"\"{request.Profile.Location}\" {request.Profile.Arguments}";
_terminal = new Terminal();
_terminal.OutputReady += _terminal_OutputReady;
_terminal.Exited += _terminal_Exited;
Task.Run(() => _terminal.Start(args, cwd, request.Size.Columns, request.Size.Rows));
}
private void _terminal_Exited(object sender, EventArgs e)
{
_exited = true;
Close();
}
private string GetWorkingDirectory(ShellProfile configuration)
{
if (string.IsNullOrWhiteSpace(configuration.WorkingDirectory) || !Directory.Exists(configuration.WorkingDirectory))
{
return Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
}
return configuration.WorkingDirectory;
}
private void _terminal_OutputReady(object sender, EventArgs e)
{
ListenToStdOut();
}
private void ListenToStdOut()
{
Task.Factory.StartNew(async () =>
{
using (var reader = new StreamReader(_terminal.ConsoleOutStream))
{
do
{
var buffer = new byte[1024];
var readBytes = await _terminal.ConsoleOutStream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
if (readBytes > 0)
{
_terminalsManager.DisplayTerminalOutput(Id, buffer);
}
}
while (!_exited);
}
}, TaskCreationOptions.LongRunning);
}
public void Write(byte[] data)
{
_terminal.WriteToPseudoConsole(data);
}
#region IDisposable Support
private bool disposedValue = false;
private void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
_terminal?.Dispose();
}
disposedValue = true;
}
}
public void Dispose()
{
Dispose(true);
}
#endregion IDisposable Support
}
}