diff --git a/WowUp.WPF/App.xaml.cs b/WowUp.WPF/App.xaml.cs index 88e013fd..c56146f3 100644 --- a/WowUp.WPF/App.xaml.cs +++ b/WowUp.WPF/App.xaml.cs @@ -1,7 +1,9 @@ -using Microsoft.Extensions.DependencyInjection; +using CommandLine; +using Microsoft.Extensions.DependencyInjection; using Serilog; using System; using System.IO; +using System.Linq; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; @@ -10,6 +12,7 @@ using WowUp.Common.Services.Contracts; using WowUp.WPF.AddonProviders; using WowUp.WPF.AddonProviders.Contracts; using WowUp.WPF.Enums; +using WowUp.WPF.Models.WowUp; using WowUp.WPF.Repositories; using WowUp.WPF.Repositories.Contracts; using WowUp.WPF.Services; @@ -40,6 +43,8 @@ namespace WowUp.WPF [DllImport("user32.dll")] public static extern int SetForegroundWindow(IntPtr hwnd); + public static StartupOptions StartupOptions { get; private set; } + public App() { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(ExceptionHandler); @@ -56,13 +61,14 @@ namespace WowUp.WPF Log.Information($"Starting {AppUtilities.CurrentVersion}"); + ParseCommandLineArgs(); + var serviceCollection = new ServiceCollection(); ConfigureServices(serviceCollection); _serviceProvider = serviceCollection.BuildServiceProvider(); _analyticsService = _serviceProvider.GetRequiredService(); } - protected override void OnStartup(StartupEventArgs e) { HandleSingleInstance(); @@ -159,5 +165,15 @@ namespace WowUp.WPF //there is already another instance running! Current.Shutdown(); } + + private void ParseCommandLineArgs() + { + var args = Environment.GetCommandLineArgs().Skip(1); + Parser.Default.ParseArguments(args) + .WithParsed( + options => StartupOptions = options) + .WithNotParsed( + errors => Log.Error(string.Join("\r\n", errors.Select(x => x.ToString()).ToArray()))); + } } } diff --git a/WowUp.WPF/Models/WowUp/StartupOptions.cs b/WowUp.WPF/Models/WowUp/StartupOptions.cs new file mode 100644 index 00000000..b9853dfd --- /dev/null +++ b/WowUp.WPF/Models/WowUp/StartupOptions.cs @@ -0,0 +1,18 @@ +using CommandLine; +using System.Collections.Generic; +using WowUp.Common.Enums; + +namespace WowUp.WPF.Models.WowUp +{ + public class StartupOptions + { + [Option(shortName: 'i', longName: "install", HelpText = "Specify addon URLs to install them")] + public IEnumerable InputURLs { get; set; } + [Option(shortName: 'm', longName: "minimized", HelpText = "Start the application minimized")] + public bool Minimized { get; set; } + [Option(shortName: 'q', longName: "quit", HelpText = "Exit the application after auto-updates")] + public bool Quit { get; set; } + [Option(shortName: 'c', longName: "client", HelpText = "Specify client version to use", Default = WowClientType.None)] + public WowClientType ClientType { get; set; } + } +} diff --git a/WowUp.WPF/Services/SessionService.cs b/WowUp.WPF/Services/SessionService.cs index 07085e25..e607475a 100644 --- a/WowUp.WPF/Services/SessionService.cs +++ b/WowUp.WPF/Services/SessionService.cs @@ -4,9 +4,12 @@ using System; using System.Linq; using System.Threading; using System.Threading.Tasks; +using System.Windows; +using System.Windows.Threading; using WowUp.Common.Enums; using WowUp.Common.Models; using WowUp.Common.Models.Events; +using WowUp.WPF.Extensions; using WowUp.WPF.Services.Contracts; namespace WowUp.WPF.Services @@ -54,7 +57,6 @@ namespace WowUp.WPF.Services StatusText = string.Empty, UpdaterReady = false }; - } private async void UpdateCheckTimerElapsed() @@ -112,9 +114,16 @@ namespace WowUp.WPF.Services SessionChanged?.Invoke(this, new SessionEventArgs(_sessionState)); } - public void AppLoaded() + public async void AppLoaded() { - if(_updateCheckTimer == null) + if (App.StartupOptions != null && App.StartupOptions.ClientType != WowClientType.None) + { + SelectedClientType = App.StartupOptions.ClientType; + } + + await ProcessInputUrls(); + + if (_updateCheckTimer == null) { _updateCheckTimer = new Timer(_ => UpdateCheckTimerElapsed(), null, TimeSpan.FromSeconds(0), TimeSpan.FromMinutes(60)); } @@ -136,6 +145,41 @@ namespace WowUp.WPF.Services SetContextText(text); } + private async Task ProcessInputUrls() + { + if (!App.StartupOptions?.InputURLs.Any() ?? false) + { + return; + } + + await App.StartupOptions.InputURLs.ForEachAsync(2, async x => + { + PotentialAddon potentialAddon = null; + try + { + potentialAddon = await _addonService.GetAddonByUri(new Uri(x), SelectedClientType); + } + catch + { + MessageBox.Show($"Failed to import addon by URI: {x}"); + return; + } + + if (potentialAddon != null) + { + try + { + await _addonService.InstallAddon(potentialAddon, SelectedClientType); + } + catch + { + MessageBox.Show($"Failed to install addon {potentialAddon.Name}"); + } + } + + }); + } + private async void ProcessAutoUpdates() { var updateCount = await _addonService.ProcessAutoUpdates(); @@ -144,6 +188,13 @@ namespace WowUp.WPF.Services { TaskbarIcon.ShowBalloonTip("WowUp", $"Automatically updated {updateCount} addons.", TaskbarIcon.Icon, true); } + + if (App.StartupOptions?.Quit == true) + { + // Artificial delay to allow notification to fire. + await Task.Delay(3000); + await Application.Current.Dispatcher.BeginInvoke(() => { Application.Current.Shutdown(); }, DispatcherPriority.SystemIdle); + } } private void SetContextText(string text) diff --git a/WowUp.WPF/ViewModels/MainWindowViewModel.cs b/WowUp.WPF/ViewModels/MainWindowViewModel.cs index 3e8771dc..a0c4228e 100644 --- a/WowUp.WPF/ViewModels/MainWindowViewModel.cs +++ b/WowUp.WPF/ViewModels/MainWindowViewModel.cs @@ -1,4 +1,4 @@ -using Hardcodet.Wpf.TaskbarNotification; +using Hardcodet.Wpf.TaskbarNotification; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.ObjectModel; @@ -6,7 +6,6 @@ using System.Linq; using System.Windows; using System.Windows.Controls; using WowUp.Common.Enums; -using WowUp.Common.Services.Contracts; using WowUp.WPF.Entities; using WowUp.WPF.Extensions; using WowUp.WPF.Repositories.Contracts; @@ -220,6 +219,7 @@ namespace WowUp.WPF.ViewModels return; } + Application.Current.MainWindow.ShowInTaskbar = true; Application.Current.MainWindow.Show(); Application.Current.MainWindow.WindowState = WindowState.Normal; Application.Current.MainWindow.Activate(); @@ -256,6 +256,13 @@ namespace WowUp.WPF.ViewModels public void OnSourceInitialized(Window window) { + if (App.StartupOptions?.Minimized == true) + { + window.Hide(); + window.ShowInTaskbar = false; + window.WindowState = WindowState.Minimized; + } + var windowPref = _preferenceRepository.FindByKey(WindowPlacementKey); var windowStatePref = _preferenceRepository.FindByKey(WindowStateKey); if (windowPref == null) diff --git a/WowUp.WPF/WowUp.WPF.csproj b/WowUp.WPF/WowUp.WPF.csproj index 44194921..73a2fba3 100644 --- a/WowUp.WPF/WowUp.WPF.csproj +++ b/WowUp.WPF/WowUp.WPF.csproj @@ -54,6 +54,7 @@ +