From 42469bfa67cc2e5b1cf0ccabf4a4fe1de24a8f3b Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Fri, 20 Aug 2021 19:33:03 +0200 Subject: [PATCH] WindowsTrait: Creating a custom host for windows with a notification icon. Starting to create a inno setup installer --- Kyoo.WindowsHost/Kyoo.WindowsHost.csproj | 22 ++++ Kyoo.WindowsHost/Program.cs | 28 +++++ Kyoo.WindowsHost/SystemTrait.cs | 135 +++++++++++++++++++++++ Kyoo.WindowsHost/kyoo.ico | Bin 0 -> 15406 bytes Kyoo.sln | 10 ++ Kyoo/CoreModule.cs | 5 +- Kyoo/Kyoo.csproj | 3 +- Kyoo/Program.cs | 56 ++++++++-- deployment/kyoo-windows.iss | 39 +++++++ 9 files changed, 282 insertions(+), 16 deletions(-) create mode 100644 Kyoo.WindowsHost/Kyoo.WindowsHost.csproj create mode 100644 Kyoo.WindowsHost/Program.cs create mode 100644 Kyoo.WindowsHost/SystemTrait.cs create mode 100644 Kyoo.WindowsHost/kyoo.ico create mode 100644 deployment/kyoo-windows.iss diff --git a/Kyoo.WindowsHost/Kyoo.WindowsHost.csproj b/Kyoo.WindowsHost/Kyoo.WindowsHost.csproj new file mode 100644 index 00000000..fe167974 --- /dev/null +++ b/Kyoo.WindowsHost/Kyoo.WindowsHost.csproj @@ -0,0 +1,22 @@ + + + + WinExe + net5.0-windows + enable + true + Kyoo.Host.Windows + + + + + + + + + + PreserveNewest + + + + \ No newline at end of file diff --git a/Kyoo.WindowsHost/Program.cs b/Kyoo.WindowsHost/Program.cs new file mode 100644 index 00000000..ace92e24 --- /dev/null +++ b/Kyoo.WindowsHost/Program.cs @@ -0,0 +1,28 @@ +using System.Threading.Tasks; +using Autofac; +using Microsoft.Extensions.Hosting; + +namespace Kyoo.Host.Windows +{ + public static class Program + { + /// + /// The main entry point for the application that overrides the default host (). + /// It adds a system trait for windows and since the host is build as a windows executable instead of a console + /// app, the console is not showed. + /// + public static async Task Main(string[] args) + { + Kyoo.Program.SetupDataDir(args); + + IHost host = Kyoo.Program.CreateWebHostBuilder(args) + .ConfigureContainer(builder => + { + builder.RegisterType().As().SingleInstance(); + }) + .Build(); + + await Kyoo.Program.StartWithHost(host); + } + } +} \ No newline at end of file diff --git a/Kyoo.WindowsHost/SystemTrait.cs b/Kyoo.WindowsHost/SystemTrait.cs new file mode 100644 index 00000000..22009ab1 --- /dev/null +++ b/Kyoo.WindowsHost/SystemTrait.cs @@ -0,0 +1,135 @@ +using System; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Threading; +using System.Windows.Forms; +using Autofac; +using Kyoo.Models.Options; +using Microsoft.Extensions.Options; + +namespace Kyoo.Host.Windows +{ + /// + /// A singleton that add an notification icon on the window's toolbar. + /// + public sealed class SystemTrait : IStartable, IDisposable + { + /// + /// The options containing the . + /// + private readonly IOptions _options; + + /// + /// The thread where the trait is running. + /// + private Thread? _thread; + + + /// + /// Create a new . + /// + /// The options to use. + public SystemTrait(IOptions options) + { + _options = options; + } + + /// + public void Start() + { + _thread = new Thread(() => InternalSystemTrait.Run(_options)) + { + IsBackground = true + }; + _thread.Start(); + } + + /// + public void Dispose() + { + // TODO not sure that the trait is ended and that it does shutdown but the only way to shutdown the + // app anyway is via the Trait's Exit or a Signal so it's fine. + _thread?.Join(); + _thread = null; + } + + /// + /// The internal class for . It should be invoked via + /// . + /// + private class InternalSystemTrait : ApplicationContext + { + /// + /// 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 option containing the public url. + private InternalSystemTrait(IOptions options) + { + _options = options; + + Application.ApplicationExit += (_, _) => Dispose(); + + _icon = new NotifyIcon(); + _icon.Text = "Kyoo"; + _icon.Icon = new Icon(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "kyoo.ico")); + _icon.Visible = true; + _icon.MouseClick += (_, e) => + { + if (e.Button != MouseButtons.Left) + return; + _StartBrowser(); + }; + + _icon.ContextMenuStrip = new ContextMenuStrip(); + _icon.ContextMenuStrip.Items.AddRange(new ToolStripItem[] + { + new ToolStripMenuItem("Exit", null, (_, _) => { Environment.Exit(0); }) + }); + } + + /// + /// Run the trait in the current thread, this method does not return while the trait is running. + /// + /// The options to pass to . + public static void Run(IOptions options) + { + using InternalSystemTrait trait = new(options); + Application.Run(trait); + } + + /// + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + _icon.Visible = false; + _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(); + } + } + } +} \ No newline at end of file diff --git a/Kyoo.WindowsHost/kyoo.ico b/Kyoo.WindowsHost/kyoo.ico new file mode 100644 index 0000000000000000000000000000000000000000..61e160247cb9651a48c86119ecae4e3a7d0558cc GIT binary patch literal 15406 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 D&GxeA literal 0 HcmV?d00001 diff --git a/Kyoo.sln b/Kyoo.sln index 701d760b..6ab7d6d9 100644 --- a/Kyoo.sln +++ b/Kyoo.sln @@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Tests", "tests\Kyoo.Te EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.WebApp", "Kyoo.WebApp\Kyoo.WebApp.csproj", "{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.WindowsHost", "Kyoo.WindowsHost\Kyoo.WindowsHost.csproj", "{98851001-40DD-46A6-94B3-2F8D90722076}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -65,5 +67,13 @@ Global {2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Debug|Any CPU.Build.0 = Debug|Any CPU {2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Release|Any CPU.ActiveCfg = Release|Any CPU {2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Release|Any CPU.Build.0 = Release|Any CPU + {4FF1ECD9-6EEF-4440-B037-A661D78FB04D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4FF1ECD9-6EEF-4440-B037-A661D78FB04D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4FF1ECD9-6EEF-4440-B037-A661D78FB04D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4FF1ECD9-6EEF-4440-B037-A661D78FB04D}.Release|Any CPU.Build.0 = Release|Any CPU + {98851001-40DD-46A6-94B3-2F8D90722076}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {98851001-40DD-46A6-94B3-2F8D90722076}.Debug|Any CPU.Build.0 = Debug|Any CPU + {98851001-40DD-46A6-94B3-2F8D90722076}.Release|Any CPU.ActiveCfg = Release|Any CPU + {98851001-40DD-46A6-94B3-2F8D90722076}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/Kyoo/CoreModule.cs b/Kyoo/CoreModule.cs index b6445b3d..2d1e35e8 100644 --- a/Kyoo/CoreModule.cs +++ b/Kyoo/CoreModule.cs @@ -70,10 +70,11 @@ namespace Kyoo builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); + builder.RegisterType().As().As().SingleInstance(); + builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().InstancePerLifetimeScope(); - builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().InstancePerLifetimeScope(); builder.RegisterType().As().SingleInstance(); @@ -135,8 +136,6 @@ namespace Kyoo }); services.AddHttpClient(); - - services.AddHostedService(x => x.GetService() as TaskManager); } /// diff --git a/Kyoo/Kyoo.csproj b/Kyoo/Kyoo.csproj index 28ac7ff0..d4a573f9 100644 --- a/Kyoo/Kyoo.csproj +++ b/Kyoo/Kyoo.csproj @@ -44,7 +44,8 @@ - + diff --git a/Kyoo/Program.cs b/Kyoo/Program.cs index e9f21a0b..f905b8ba 100644 --- a/Kyoo/Program.cs +++ b/Kyoo/Program.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using SEnvironment = System.Environment; namespace Kyoo { @@ -28,20 +29,23 @@ namespace Kyoo #else private const string Environment = "Production"; #endif - + /// /// Main function of the program /// /// Command line arguments - public static async Task Main(string[] args) + public static Task Main(string[] args) + { + SetupDataDir(args); + return StartWithHost(CreateWebHostBuilder(args).Build()); + } + + /// + /// Start the given host and log failing exceptions. + /// + /// The host to start. + public static async Task StartWithHost(IHost host) { - if (!File.Exists(JsonConfigPath)) - File.Copy(Path.Join(AppDomain.CurrentDomain.BaseDirectory, JsonConfigPath), JsonConfigPath); - - IHost host = CreateWebHostBuilder(args) - .UseEnvironment(Environment) - .Build(); - try { host.Services.GetRequiredService>() @@ -65,6 +69,7 @@ namespace Kyoo return builder.SetBasePath(System.Environment.CurrentDirectory) .AddJsonFile(JsonConfigPath, false, true) .AddEnvironmentVariables() + .AddEnvironmentVariables("KYOO_") .AddCommandLine(args); } @@ -73,7 +78,7 @@ namespace Kyoo /// /// The host context that contains the configuration /// The logger builder to configure. - private static void _ConfigureLogging(HostBuilderContext context, ILoggingBuilder builder) + public static void ConfigureLogging(HostBuilderContext context, ILoggingBuilder builder) { builder.AddConfiguration(context.Configuration.GetSection("logging")) .AddSimpleConsole(x => @@ -89,18 +94,19 @@ namespace Kyoo /// /// Command line parameters that can be handled by kestrel /// - /// An action to configure the logging. If it is null, will be used. + /// An action to configure the logging. If it is null, will be used. /// /// A new web host instance public static IHostBuilder CreateWebHostBuilder(string[] args, Action loggingConfiguration = null) { IConfiguration configuration = SetupConfig(new ConfigurationBuilder(), args).Build(); - loggingConfiguration ??= _ConfigureLogging; + loggingConfiguration ??= ConfigureLogging; return new HostBuilder() .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .UseContentRoot(AppDomain.CurrentDomain.BaseDirectory) + .UseEnvironment(Environment) .ConfigureAppConfiguration(x => SetupConfig(x, args)) .ConfigureLogging(loggingConfiguration) .ConfigureServices(x => x.AddRouting()) @@ -113,6 +119,32 @@ namespace Kyoo ); } + /// + /// Parse the data directory from environment variables and command line arguments, create it if necessary. + /// Set the current directory to said data folder and place a default configuration file if it does not already + /// exists. + /// + /// The command line arguments + public static void SetupDataDir(string[] args) + { + IConfiguration parsed = new ConfigurationBuilder() + .AddEnvironmentVariables() + .AddEnvironmentVariables("KYOO_") + .AddCommandLine(args) + .Build(); + + string path = parsed.GetValue("data_dir"); + if (path == null) + path = Path.Combine(SEnvironment.GetFolderPath(SEnvironment.SpecialFolder.LocalApplicationData), "Kyoo"); + + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); + SEnvironment.CurrentDirectory = path; + + if (!File.Exists(JsonConfigPath)) + File.Copy(Path.Join(AppDomain.CurrentDomain.BaseDirectory, JsonConfigPath), JsonConfigPath); + } + /// /// An useless class only used to have a logger in the main. /// diff --git a/deployment/kyoo-windows.iss b/deployment/kyoo-windows.iss new file mode 100644 index 00000000..99d9d426 --- /dev/null +++ b/deployment/kyoo-windows.iss @@ -0,0 +1,39 @@ +[Setup] +AppId={{31A61284-7939-46BC-B584-D2279A6EEEE8} +AppName=Kyoo +AppVersion=1.0 +AppPublisher=SDG +AppPublisherURL=https://github.com/AnonymusRaccoon/Kyoo +AppSupportURL=https://github.com/AnonymusRaccoon/Kyoo +AppUpdatesURL=https://github.com/AnonymusRaccoon/Kyoo +DefaultDirName={commonpf}\Kyoo +DisableProgramGroupPage=yes +LicenseFile={#kyoo}\LICENSE +OutputBaseFilename=kyoo-windows +SetupIconFile={#kyoo}\wwwroot\favicon.ico +Compression=lzma +SolidCompression=yes +WizardStyle=modern +AppCopyright=GPL-3.0 + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked +Name: "startupShortcut"; Description: "Create shortcut in Startup folder (Starts when you log into Windows)"; GroupDescription: "Start automatically"; Flags: exclusive +Name: "none"; Description: "Do not start automatically"; GroupDescription: "Start automatically"; Flags: exclusive unchecked + +[Files] +Source: "{#kyoo}\Kyoo.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#kyoo}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs + +[UninstallDelete] +Type: filesandordirs; Name: "{commonappdata}\Kyoo" + +[Icons] +Name: "{autoprograms}\Kyoo"; Filename: "{app}\Kyoo.exe" +Name: "{autodesktop}\Kyoo"; Filename: "{app}\Kyoo.exe"; Tasks: desktopicon + +[Run] +Filename: "{app}\Kyoo.exe"; Description: "{cm:LaunchProgram,Kyoo}"; Flags: nowait postinstall skipifsilent \ No newline at end of file