using System; using System.Diagnostics; using System.Drawing; using System.IO; using System.Threading; using System.Windows.Forms; using Autofac; using Kyoo.Abstractions.Controllers; using Kyoo.Core.Models.Options; using Microsoft.Extensions.Options; namespace Kyoo.Host.WindowsTrait { /// /// A singleton that add an notification icon on the window's toolbar. /// public sealed class SystemTrait : IStartable, IDisposable { /// /// The application running Kyoo. /// private readonly IApplication _application; /// /// The options containing the . /// private readonly IOptions _options; /// /// The thread where the trait is running. /// private Thread _thread; /// /// Create a new . /// /// The application running Kyoo. /// The options to use. public SystemTrait(IApplication application, IOptions options) { _application = application; _options = options; } /// public void Start() { _thread = new Thread(() => InternalSystemTrait.Run(_application, _options)) { IsBackground = true }; _thread.Start(); } /// public void Dispose() { System.Windows.Forms.Application.Exit(); _thread?.Join(); _thread = null; } /// /// The internal class for . It should be invoked via /// . /// private class InternalSystemTrait : ApplicationContext { /// /// The application running Kyoo. /// private readonly IApplication _application; /// /// The options containing the . /// private readonly IOptions _options; /// /// The Icon that is displayed in the window's bar. /// private readonly NotifyIcon _icon; /// /// Create a new . Used only by . /// /// The application running Kyoo. /// The option containing the public url. private InternalSystemTrait(IApplication application, IOptions options) { _application = application; _options = options; AppDomain.CurrentDomain.ProcessExit += (_, _) => Dispose(); System.Windows.Forms.Application.ApplicationExit += (_, _) => Dispose(); _icon = new NotifyIcon { Text = "Kyoo", Icon = new Icon(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "kyoo.ico")), Visible = true }; _icon.MouseClick += (_, e) => { if (e.Button != MouseButtons.Left) return; _StartBrowser(); }; _icon.ContextMenuStrip = new ContextMenuStrip(); _icon.ContextMenuStrip.Items.AddRange(new ToolStripItem[] { new ToolStripMenuItem("Open browser", null, (_, _) => { _StartBrowser(); }), new ToolStripMenuItem("Open logs", null, (_, _) => { _OpenLogs(); }), new ToolStripSeparator(), new ToolStripMenuItem("Exit", null, (_, _) => { _application.Shutdown(); }) }); } /// /// Run the trait in the current thread, this method does not return while the trait is running. /// /// The application running Kyoo. /// The options to pass to . public static void Run(IApplication application, IOptions options) { using InternalSystemTrait trait = new(application, options); System.Windows.Forms.Application.Run(trait); } /// protected override void Dispose(bool disposing) { _icon.Visible = false; base.Dispose(disposing); _icon.Dispose(); } /// /// Open kyoo's page in the user's default browser. /// private void _StartBrowser() { Process browser = new() { StartInfo = new ProcessStartInfo(_options.Value.PublicUrl.ToString()) { UseShellExecute = true } }; browser.Start(); } /// /// Open the log directory in windows's explorer. /// private void _OpenLogs() { string logDir = Path.Combine(_application.GetDataDirectory(), "logs"); Process.Start("explorer.exe", logDir); } } } }