示例#1
0
        // Invoked when application is being started up (before MainWindow creation).
        private void App_Startup(object sender, StartupEventArgs e)
        {
            // Set main thread apartment state.
            Thread.CurrentThread.SetApartmentState(ApartmentState.STA);

            // Set AppUserModelId of current process.
            TaskbarHelper.SetAppUserModelId();

            // Create Mutex if this is first instance.
            try
            {
                RunningInstanceMutex = Mutex.OpenExisting(RunningInstanceMutexName);
            }
            catch (WaitHandleCannotBeOpenedException)
            {
                bool created = false;
                RunningInstanceMutex = new Mutex(false, RunningInstanceMutexName, out created);
                if (!created)
                {
                    throw new Exception("Unable to create application mutex");
                }
            }

            // Load persistent data.
            // Take the first not-switch argument as path to the build that will be imported
            var importedBuildPath = e.Args.FirstOrDefault(s => !s.StartsWith("/"));

            PersistentData = PersistentDataSerializationService.CreatePersistentData(importedBuildPath);

            // Initialize localization.
            L10n.Initialize(PersistentData.Options.Language);
        }
        public async Task FirstStepRemovesPinnedTaskbarIcon()
        {
            string roamingFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            string taskbarFolder = Path.Combine(roamingFolder, @"Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar");

            using (IntegrationTestHelper.WithClickOnceApp())
            {
                var    clickOnceInfo = UninstallInfo.Find(IntegrationTestHelper.ClickOnceAppName);
                string shortcutPath  = clickOnceInfo.GetShortcutPath();
                TaskbarHelper.PinToTaskbar(shortcutPath);

                string rootDir;
                using (IntegrationTestHelper.WithTempDirectory(out rootDir))
                {
                    using (var updateManager = IntegrationTestHelper.GetSquirrelUpdateManager(rootDir))
                    {
                        using (IntegrationTestHelper.CleanupSquirrel(updateManager))
                        {
                            var migrator = new InClickOnceAppMigrator(updateManager, IntegrationTestHelper.ClickOnceAppName);

                            await migrator.Execute();

                            Assert.False(File.Exists(Path.Combine(taskbarFolder, IntegrationTestHelper.ClickOnceAppName + ".appref-ms")));
                        }
                    }
                }
            }
        }
示例#3
0
 public static void SetProgressState(TaskbarButtonProgressMode State)
 {
     if (!cantInteractWithTaskbar && MainWindowHandle != IntPtr.Zero)
     {
         try { TaskbarHelper.SetProgressState(MainWindowHandle, State); }
         catch (Exception) { cantInteractWithTaskbar = true; }
     }
 }
        //
        JumpListItemTask CreateJumpListTask(string caption, string iconName)
        {
            JumpListItemTask task = new JumpListItemTask(caption);

            task.IconPath  = TaskbarHelper.GetIconPath(iconName);
            task.IconIndex = 0;
            return(task);
        }
示例#5
0
 public MainForm()
 {
     TaskbarHelper.InitDemoJumpList(TaskbarAssistant.Default, this);
     Program.MainForm = this;
     Icon             = Program.AppIcon;
     ShowSplashScreen();
     InitializeComponent();
     PrepareUI();
     InitViewModel();
     DevExpress.Utils.About.UAlgo.Default.DoEventObject(DevExpress.Utils.About.UAlgo.kDemo, DevExpress.Utils.About.UAlgo.pWinForms, this);
 }
示例#6
0
 public static void SetProgressValue(ulong CurrentValue, ulong MaximumValue)
 {
     if (!cantInteractWithTaskbar && MainWindowHandle != IntPtr.Zero)
     {
         if (CurrentValue > MaximumValue)
         {
             throw new Exception($"WindowsTaskbarHelper.SetProgressValue: Incorrect parameters - Cur: {CurrentValue}, Max: {MaximumValue}.");
         }
         try { TaskbarHelper.SetProgressValue(MainWindowHandle, CurrentValue, MaximumValue); }
         catch (Exception) { cantInteractWithTaskbar = true; }
     }
 }
示例#7
0
        internal void OnStarted()
        {
            started = true;
            MiniProgressBar.IsIndeterminate = false;
            if (client.TransferEvent.IsUpload)
            {
                Title = AppLanguage.Get("LangTitleUploading_x").FormatC(0);
            }
            else
            {
                Title = AppLanguage.Get("LangTitleDownloading_x").FormatC(0);
            }

            GroupBoxCurrentX.Visibility = GroupBoxTotal.Visibility = Visibility.Visible;
            LabelETA.Visibility         = Visibility.Visible;
            TransferProgress.Roll(false);
            TextBlockCounts.Visibility = Visibility.Collapsed;

            ButtonPause.Visibility = Visibility.Visible;

            if (client.TransferEvent.TotalFiles > 0)
            {
                LabelFilesXY.Content    = AppLanguage.Get("LangLabelFiles_X_Y").FormatC(0, client.TransferEvent.TotalFiles);
                LabelFilesXY.Visibility = Visibility.Visible;
            }

            if (client.TransferEvent.TotalFolders > 0)
            {
                LabelFoldersXY.Content    = AppLanguage.Get("LangLabelFolders_X_Y").FormatC(0, client.TransferEvent.TotalFolders);
                LabelFoldersXY.Visibility = Visibility.Visible;
            }

            cacher.TotalSize           = SizeUnit.Parse(client.TransferEvent.TotalSize);
            LabelTotalSizeXY.Content   = AppLanguage.Get("LangLabelTransferredSize_X_FromTotal_Y").FormatC(0, cacher.TotalSize);
            LabelTotalRemainsX.Content = AppLanguage.Get("LangLabelRemains_X").FormatC(cacher.TotalSize);

            maximum = client.TransferEvent.TotalFolders + client.TransferEvent.TotalFiles + client.TransferEvent.TotalSize;
            if (maximum == 0)
            {
                maximum = 1;
            }

            LabelTransferSpeed.Content = AppLanguage.Get("LangLabelAverageTransferSpeed_X").FormatC(SizeUnit.Parse(0));
            ElapsedTimeLabel.Content   = AppLanguage.Get("LangLabelElapsedTime_X").FormatC(zeroTime);
            LabelETA.Content           = AppLanguage.Get("LangLabelETATime_X").FormatC(zeroTime);

            ButtonFished.Visibility = Visibility.Visible;
            TaskbarHelper.Add(ProgressBarTotal);

            timer200.Start();
            timer1000.Start();
        }
示例#8
0
 public frmMain()
 {
     TaskbarHelper.InitDemoJumpList(TaskbarAssistant.Default, this);
     InitializeComponent();
     RibbonButtonsInitialize();
     modulesNavigator = new ModulesNavigator(ribbonControl1, pcMain);
     zoomManager      = new ZoomManager(ribbonControl1, modulesNavigator, beiZoom);
     InitNavBarItemLinks();
     NavigationInitialize();
     SetPageLayoutStyle();
     guideGenerator = new GuideGenerator();
     guideGenerator.CreateWhatsThisItem(ribbonControl1, () => { return(this); });
 }
示例#9
0
 public frmMain()
 {
     TaskbarHelper.InitDemoJumpList(TaskbarAssistant.Default, this);
     InitializeComponent();
     rpcSearch.Text = TagResources.SearchTools;
     InitNavBarGroups();
     SkinHelper.InitSkinGallery(rgbiSkins);
     RibbonButtonsInitialize();
     modulesNavigator = new ModulesNavigator(ribbonControl1, pcMain);
     zoomManager      = new ZoomManager(ribbonControl1, modulesNavigator, beiZoom);
     modulesNavigator.ChangeGroup(navBarControl1.ActiveGroup, this);
     NavigationInitialize();
     SetPageLayoutStyle();
 }
        public NotificationFlyoutApplication()
        {
            Uwp.UI.Controls.NotificationFlyout.SetApplication(this);

            _notificationIconHelper              = NotificationIconHelper.Create();
            _notificationIconHelper.IconInvoked += OnIconInvoked;

            _taskbarHelper = TaskbarHelper.Create();
            _taskbarHelper.TaskbarChanged += OnTaskbarChanged;

            _systemPersonalisationHelper = SystemPersonalisationHelper.Current;
            _systemPersonalisationHelper.ThemeChanged += OnThemeChanged;

            PrepareFlyoutHost();
            WndProcListener.Current.Start();
        }
示例#11
0
        private void Timer_OnNewState(object sender, TimerState e)
        {
            Threading.ComponentInvoke(buttonManualBackup, (x) => x.Enabled = e == TimerState.SavingEnabled || e == TimerState.WaitingForCanvas);

            if (e == TimerState.NeverSaved)
            {
                TaskbarHelper.SetState(SaiHelper.AppProcess, TaskbarProgressBarState.Paused);
            }
            else if (e == TimerState.SavingEnabled)
            {
                TaskbarHelper.SetState(SaiHelper.AppProcess, TaskbarProgressBarState.Normal);
            }

            switch (e)
            {
            case TimerState.NeverSaved:
                Threading.SetComponentText(this, labelStatus, Properties.Strings.StateNeverSaved);
                break;

            case TimerState.SavingDisabled:
                Threading.SetComponentText(this, labelStatus, Properties.Strings.StateSavingDisabled);
                break;

            case TimerState.SavingEnabled:
                Threading.SetComponentText(this, labelStatus, Properties.Strings.StateSavingEnabled);
                break;

            case TimerState.WaitingForCanvas:
                Threading.SetComponentText(this, labelStatus, Properties.Strings.StateWaitingForCanvas);
                break;

            case TimerState.WaitingForProcess:
                Threading.SetComponentText(this, labelStatus, Properties.Strings.StateWaitingForProcess);
                break;

            case TimerState.WaitingForProject:
                Threading.SetComponentText(this, labelStatus, Properties.Strings.StateWaitingForProject);
                break;
            }

            BeginInvoke(new Action(() => sToolStripMenuItem.Text = labelStatus.Text));
        }
示例#12
0
        /// <summary>
        /// Regenerates the window icon and set the taskbar status
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UpdateTaskbarAndIcon(object sender, EventArgs e)
        {
            //Sets the taskbar progress of this window
            TaskbarUtility.SetProgress(this);

            //Sets the title of the window
            TaskbarUtility.SetTitle(this);

            //A new window icon must be created. This happens once per minute
            if (_lastMinuteIconWasCreated != Config.RealTimeLeft.Minutes)
            {
                _lastMinuteIconWasCreated = Config.RealTimeLeft.Minutes;

                //Create new pie
                Bitmap pie = TaskbarHelper.CreatePie(
                    bounds: new Rectangle(0, 0, 64, 64),
                    primary: Properties.Resources.clrUpper.GetPixel(Config.TimeLeft.Minutes, 0),
                    secondary: Properties.Resources.clrLower.GetPixel(Config.TimeLeft.Minutes, 0),
                    primaryBG: Properties.Resources.clrToGreen.GetPixel(Config.TimeLeft.Minutes, 0),
                    secondaryBG: Properties.Resources.clrToRed.GetPixel(Config.TimeLeft.Minutes, 0),
                    value: (float)Config.TimeLeft.TotalMinutes / 60f,
                    startAngle: (int)Math.Floor(Config.Target.Minute / 60f * 360 - 90),
                    ccw: !Config.Overtime
                    );

                //Update icon
                Icon = TaskbarHelper.CreateIconFromBitmap(pie);
                pie.Dispose();
            }

            //We have reached overtime. Make background red. This happens only once
            if (Config.Overtime && !_overtimeBackColorSet)
            {
                foreach (Control i in tabs.Controls)
                {
                    i.BackColor = Config.GlobalOvertimeColor;
                }

                _overtimeBackColorSet = true;
            }
        }
示例#13
0
        public static void Main(string[] arguments)
        {
            // If executed from JumpTask, do nothing.
            if (TaskbarHelper.IsJumpTask(arguments))
            {
                return;
            }

            // Parse boostrap mode.
            Mode mode;

            Enum.TryParse <Mode>(Environment.GetEnvironmentVariable(ModeEnvironmentVariableName), false, out mode);
            // Parse original PID.
            int pid;

            int.TryParse(Environment.GetEnvironmentVariable(PIDEnvironmentVariableName), out pid);

            switch (mode)
            {
            case Mode.RESTART:
                // Wait for original process to exit.
                try
                {
                    Process wait = Process.GetProcessById(pid);
                    if (wait != null)
                    {
                        // If process didn't exit after 10s, bail out.
                        if (!wait.WaitForExit(10000))
                        {
                            return;
                        }
                    }
                }
                catch (ArgumentException) { } // Process doesn't exist, continue.
                goto default;                 // Fall-through.

            default:
                Run();
                break;
            }
        }
        public void ExecutablesPinnedToTaskbarShouldPointToNewVersion()
        {
            string tempDir;

            using (Utility.WithTempDirectory(out tempDir)) {
                string packagesDir = Path.Combine(tempDir, "theApp", "packages");
                Directory.CreateDirectory(packagesDir);

                new[] {
                    "SampleUpdatingApp.1.0.0.0.nupkg",
                    "SampleUpdatingApp.1.1.0.0.nupkg",
                }.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(packagesDir, x)));

                var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, tempDir, null, new FakeUrlDownloader());

                var baseEntry       = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "SampleUpdatingApp.1.0.0.0.nupkg"));
                var latestFullEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "SampleUpdatingApp.1.1.0.0.nupkg"));

                var updateInfo = UpdateInfo.Create(null, new[] { baseEntry }, packagesDir, FrameworkVersion.Net40);
                using (fixture) {
                    fixture.ApplyReleases(updateInfo).ToList().First();
                }

                var oldExecutable = Path.Combine(tempDir, "theApp", "app-1.0.0.0", "SampleUpdatingApp.exe");
                File.Exists(oldExecutable).ShouldBeTrue();
                TaskbarHelper.PinToTaskbar(oldExecutable);

                updateInfo = UpdateInfo.Create(baseEntry, new[] { latestFullEntry }, packagesDir, FrameworkVersion.Net40);
                using (fixture) {
                    fixture.ApplyReleases(updateInfo).ToList().First();
                }

                var newExecutable = Path.Combine(tempDir, "theApp", "app-1.1.0.0", "SampleUpdatingApp.exe");
                File.Exists(newExecutable).ShouldBeTrue();
                TaskbarHelper.IsPinnedToTaskbar(newExecutable).ShouldBeTrue();

                Utility.Retry(() => TaskbarHelper.UnpinFromTaskbar(newExecutable));
            }
        }
 public MainForm()
 {
     TaskbarHelper.InitDemoJumpList(TaskbarAssistant.Default, this);
     AppHelper.MainForm = this;
     DevExpress.DevAV.StartUpProcess.OnStart("When Only the Best Will Do");
     InitializeComponent();
     DevExpress.DevAV.StartUpProcess.OnRunning("Initializing...");
     Icon = AppHelper.AppIcon;
     mvvmContext.ViewModelConstructorParameter = this;
     ViewModel.ModuleAdded               += viewModel_ModuleAdded;
     ViewModel.ModuleRemoved             += viewModel_ModuleRemoved;
     ViewModel.SelectedModuleTypeChanged += viewModel_SelectedModuleTypeChanged;
     ViewModel.Print                          += viewModel_Print;
     ViewModel.ShowAllFolders                 += viewModel_ShowAllFolders;
     ViewModel.IsReadingModeChanged           += viewModel_IsReadingModeChanged;
     ribbonControl.MinimizedChanged           += Ribbon_MinimizedChanged;
     ribbonControl.Manager.HideBarsWhenMerging = false;
     ribbonStatusBar1.HideWhenMerging          = DefaultBoolean.False;
     ribbonControl.ForceInitialize();
     new ZoomLevelManager(beZoomLevel, bbiZoomDialog, ViewModel);
     officeNavigationBar.SynchronizeNavigationClientSelectedItem += officeNavigationBar_SynchronizeNavigationClientSelectedItem;
     officeNavigationBar.QueryPeekFormContent += officeNavigationBar_QueryPeekFormContent;
     officeNavigationBar.PopupMenuShowing     += officeNavigationBar_PopupMenuShowing;
     navBar.ActiveGroupChanged += navBar_ActiveGroupChanged;
     backstageViewControl.SelectedTabChanged += backstageViewControl_SelectedTabChanged;
     backstageViewControl.Shown  += backstageViewControl_Shown;
     backstageViewControl.Hidden += backstageViewControl_Hidden;
     backstageViewControl.Office2013StyleOptions.HeaderBackColor = ColorHelper.GetControlColor(LookAndFeel);
     backstageViewControl.BackstageViewShowRibbonItems           = BackstageViewShowRibbonItems.None;
     //
     BindCommands();
     BindFiltersVisibility();
     InitNotifications();
     InitTaskBarCommands();
     LookAndFeel.StyleChanged += LookAndFeel_StyleChanged;
     DevExpress.Utils.About.UAlgo.Default.DoEventObject(DevExpress.Utils.About.UAlgo.kDemo, DevExpress.Utils.About.UAlgo.pWinForms, new OutlookInspiredAppWin()); //DEMO_REMOVE
     this.outlookBehavior = new OutlookReadingModeBehavior(navBar, officeNavigationBar);
 }
        /// <summary>
        /// Starts preparing a mod by launching a background thread. This should be called from a UI thread
        /// </summary>
        private void StartPreparingModWrapper()
        {
            NamedBackgroundWorker nbw = new NamedBackgroundWorker(@"UpdaterServiceUpload");

            nbw.WorkerReportsProgress = true;
            nbw.ProgressChanged      += (a, b) =>
            {
                if (b.UserState is double d)
                {
                    TaskbarHelper.SetProgress(d);
                }
                else if (b.UserState is TaskbarItemProgressState tbs)
                {
                    TaskbarHelper.SetProgressState(tbs);
                }
            };
            nbw.DoWork += (a, b) =>
            {
                OperationInProgress = true;
                b.Result            = UploadMod(d => nbw.ReportProgress(0, d), s => nbw.ReportProgress(0, s));
            };
            nbw.RunWorkerCompleted += (a, b) =>
            {
                if (b.Error != null)
                {
                    Log.Error($@"Exception occurred in {nbw.Name} thread: {b.Error.Message}");
                }
                TaskbarHelper.SetProgressState(TaskbarItemProgressState.None);
                Analytics.TrackEvent(@"Uploaded mod to updater service", new Dictionary <string, string>()
                {
                    { @"Result", b.Result?.ToString() },
                    { @"Mod", mod.ModName + @" " + mod.ModVersionString }
                });
                OperationInProgress = false;
            };
            nbw.RunWorkerAsync();
        }
示例#17
0
        // Invoked when application is being started up (before MainWindow creation).
        private void App_Startup(object sender, StartupEventArgs e)
        {
            // Set main thread apartment state.
            Thread.CurrentThread.SetApartmentState(ApartmentState.STA);

            // Set AppUserModelId of current process.
            TaskbarHelper.SetAppUserModelId();

            // Create Mutex if this is first instance.
            try
            {
                RunningInstanceMutex = Mutex.OpenExisting(RunningInstanceMutexName);
            }
            catch (WaitHandleCannotBeOpenedException)
            {
                bool created = false;
                RunningInstanceMutex = new Mutex(false, RunningInstanceMutexName, out created);
                if (!created)
                {
                    throw new Exception("Unable to create application mutex");
                }
            }

            // Load persistent data.
            try
            {
                PrivatePersistentData.LoadPersistentDataFromFile();
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error occurred during a load operation.\n\n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }

            // Initialize localization.
            L10n.Initialize(PrivatePersistentData);
        }
示例#18
0
 private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
 {
     timer.CurrentTime = 0;
     TaskbarHelper.SetState(SaiHelper.AppProcess, TaskbarProgressBarState.NoProgress);
     Properties.Settings.Default.Save();
 }
示例#19
0
        internal async void OnEnded()
        {
            ended = true;
            timer1000.Stop();
            timer200.Stop();

            if (ownerClosing)
            {
                return;
            }

            TaskbarHelper.Remove(ProgressBarTotal);

            if (closing)
            {
                return;
            }

            if (client.IsChild)
            {
                await client.DisconnectAsync(false, false);
            }

            if (client.TransferEvent.Items.Length == 0)
            {
                if (client.TransferEvent.IsUpload)
                {
                    AppMessage.Add("Nothing to upload.", MessageType.Warning);
                }
                else
                {
                    AppMessage.Add("Nothing to download.", MessageType.Warning);
                }
                this.Close();
                return;
            }

            ButtonCancel.IsEnabled  = false;
            ButtonCancel.Visibility = Visibility.Collapsed;
            ButtonSkip.Visibility   = Visibility.Hidden;
            ButtonPause.Visibility  = Visibility.Hidden;

            if (client.TransferEvent.HasErrors)
            {
                MiniProgressBar.SetStateColor(ProgressBarExtension.ProgressState.Error);
            }
            else
            {
                MiniProgressBar.SetStateColor(ProgressBarExtension.ProgressState.Indeterminate);
            }

            switch (fishedAction)
            {
            case FishedAction.CloseWindow:
                if (!this.IsActive && !ClientHelper.Owner.IsActive)
                {
                    ClientHelper.Owner.FlashWindow(3);
                }
                this.Close();
                return;

            case FishedAction.CloseApp:
                AutoShutdownWindow.Initialize(this, false);
                this.Close();
                return;

            case FishedAction.Shutdown:
                AutoShutdownWindow.Initialize(this, true);
                this.Close();
                return;
            }

            updateCurrentItem();
            UpdateProgress();
            updateTotalFF();

            LabelCurrentRemainsX.Visibility = Visibility.Collapsed;
            LabelTotalRemainsX.Visibility   = Visibility.Collapsed;
            LabelETA.Visibility             = Visibility.Collapsed;

            if (client.TransferEvent.IsUpload)
            {
                this.Title = client.TransferEvent.HasErrors ? AppLanguage.Get("LangTitleUploadFinishedErrors") : AppLanguage.Get("LangTitleUploadDone");
            }
            else
            {
                this.Title = client.TransferEvent.HasErrors ? AppLanguage.Get("LangTitleDownloadFinishedErrors") : AppLanguage.Get("LangTitleDownloadDone");
                ButtonOpenTarget.Visibility = Visibility.Visible;
            }

            ButtonClose.Visibility = Visibility.Visible;
            ButtonClose.IsDefault  = true;
            ButtonClose.IsCancel   = true;
            ButtonClose.Focus();
        }
        private void UpdateClassicMod(OnlineContent.ModUpdateInfo ui)
        {
            NamedBackgroundWorker nbw = new NamedBackgroundWorker(@"ModUpdaterThread-" + ui.mod.ModName);

            nbw.WorkerReportsProgress = true;
            nbw.ProgressChanged      += (a, b) =>
            {
                if (b.UserState is double d)
                {
                    TaskbarHelper.SetProgress(d);
                }
            };
            nbw.DoWork += (a, b) =>
            {
                OperationInProgress   = true;
                ui.UpdateInProgress   = true;
                ui.Indeterminate      = false;
                ui.DownloadButtonText = M3L.GetString(M3L.string_downloading);
                ui.ProgressChanged   += (a, b) =>
                {
                    if (b.totalToDl != 0 && nbw.IsBusy) //? IsBusy needs to be here for some reason or it crashes, like progress comes in late or something.
                    {
                        nbw.ReportProgress(0, b.currentDl * 1.0 / b.totalToDl);
                    }
                };
                bool errorShown = false;
                void errorCallback(string message)
                {
                    if (!errorShown)
                    {
                        errorShown = true;
                        Application.Current.Dispatcher.Invoke(delegate { M3L.ShowDialog(window, M3L.GetString(M3L.string_interp_errorOccuredWhileUpdatingXErrorMessage, ui.mod.ModName, message), M3L.GetString(M3L.string_interp_errorUpdatingX, ui.mod.ModName), MessageBoxButton.OK, MessageBoxImage.Error); }
                                                              );
                    }
                }

                var stagingDirectory = Directory.CreateDirectory(Path.Combine(Utilities.GetTempPath(), Path.GetFileName(ui.mod.ModPath))).FullName;
                var modUpdated       = OnlineContent.UpdateMod(ui, stagingDirectory, errorCallback);
                ui.UpdateInProgress   = false;
                ui.CanUpdate          = !modUpdated;
                AnyModUpdated        |= modUpdated;
                ui.DownloadButtonText = ui.CanUpdate ? M3L.GetString(M3L.string_downloadUpdate) : M3L.GetString(M3L.string_updated);
                Utilities.DeleteFilesAndFoldersRecursively(stagingDirectory);
            };
            nbw.RunWorkerCompleted += (a, b) =>
            {
                if (b.Error != null)
                {
                    Log.Error($@"Exception occurred in {nbw.Name} thread: {b.Error.Message}");
                }
                Analytics.TrackEvent(@"Updated mod", new Dictionary <string, string>()
                {
                    { @"Type", @"Classic" },
                    { @"ModName", ui.mod.ModName },
                    { @"Result", ui.CanUpdate ? @"Success" : @"Failed" }
                });
                TaskbarHelper.SetProgressState(TaskbarProgressBarState.NoProgress);
                OperationInProgress = false;
                CommandManager.InvalidateRequerySuggested();
            };
            TaskbarHelper.SetProgress(0);
            TaskbarHelper.SetProgressState(TaskbarProgressBarState.Normal);
            nbw.RunWorkerAsync();
        }
            private void BeginBackup()
            {
                var targetToBackup = BackupSourceTarget;

                if (!targetToBackup.IsCustomOption)
                {
                    if (Utilities.IsGameRunning(targetToBackup.Game))
                    {
                        M3L.ShowDialog(window, M3L.GetString(M3L.string_interp_cannotBackupGameWhileRunning, Utilities.GetGameName(BackupSourceTarget.Game)), M3L.GetString(M3L.string_gameRunning), MessageBoxButton.OK, MessageBoxImage.Error);
                        return;
                    }
                }
                else
                {
                    // Point to existing game installation
                    Log.Information(@"BeginBackup() with IsCustomOption.");
                    var linkWarning = M3L.ShowDialog(window,
                                                     M3L.GetString(M3L.string_dialog_linkTargetWontBeModdable), M3L.GetString(M3L.string_linkWarning), MessageBoxButton.OKCancel, MessageBoxImage.Warning);
                    if (linkWarning == MessageBoxResult.Cancel)
                    {
                        Log.Information(@"User aborted linking due to dialog");
                        return;
                    }

                    Log.Information(@"Prompting user to select executable of link target");
                    var gameexe = Utilities.PromptForGameExecutable(new[] { Game });
                    if (gameexe == null)
                    {
                        return;
                    }
                    targetToBackup = new GameTarget(Game, Utilities.GetGamePathFromExe(Game, gameexe), false, true);
                    if (AvailableBackupSources.Any(x => x.TargetPath.Equals(targetToBackup.TargetPath, StringComparison.InvariantCultureIgnoreCase)))
                    {
                        // Can't point to an existing modding target
                        Log.Error(@"This target is not valid to point to as a backup: It is listed a modding target already, it must be removed as a target first");
                        M3L.ShowDialog(window, M3L.GetString(M3L.string_interp_dialog_linkFailedAlreadyATarget), M3L.GetString(M3L.string_cannotLinkGameCopy), MessageBoxButton.OK, MessageBoxImage.Error);
                        return;
                    }

                    var validationFailureReason = targetToBackup.ValidateTarget(ignoreCmmVanilla: true);
                    if (!targetToBackup.IsValid)
                    {
                        Log.Error(@"This installation is not valid to point to as a backup: " + validationFailureReason);
                        M3L.ShowDialog(window, M3L.GetString(M3L.string_interp_dialog_linkFailedInvalidTarget, validationFailureReason), M3L.GetString(M3L.string_invalidGameCopy), MessageBoxButton.OK, MessageBoxImage.Error);
                        return;
                    }
                }

                NamedBackgroundWorker nbw = new NamedBackgroundWorker(Game + @"Backup");

                nbw.WorkerReportsProgress = true;
                nbw.ProgressChanged      += (a, b) =>
                {
                    if (b.UserState is double d)
                    {
                        TaskbarHelper.SetProgress(d);
                    }
                    else if (b.UserState is TaskbarProgressBarState tbs)
                    {
                        TaskbarHelper.SetProgressState(tbs);
                    }
                };
                nbw.DoWork += (a, b) =>
                {
                    Log.Information(@"Starting the backup thread. Checking path: " + targetToBackup.TargetPath);
                    BackupInProgress = true;
                    bool end = false;

                    List <string> nonVanillaFiles = new List <string>();

                    void nonVanillaFileFoundCallback(string filepath)
                    {
                        Log.Error($@"Non-vanilla file found: {filepath}");
                        nonVanillaFiles.Add(filepath);
                    }

                    List <string> inconsistentDLC = new List <string>();

                    void inconsistentDLCFoundCallback(string filepath)
                    {
                        if (targetToBackup.Supported)
                        {
                            Log.Error($@"DLC is in an inconsistent state: {filepath}");
                            inconsistentDLC.Add(filepath);
                        }
                        else
                        {
                            Log.Error(@"Detected an inconsistent DLC, likely due to an unofficial copy of the game");
                        }
                    }

                    ProgressVisible       = true;
                    ProgressIndeterminate = true;
                    BackupStatus          = M3L.GetString(M3L.string_validatingBackupSource);
                    Log.Information(@"Checking target is vanilla");
                    bool isVanilla = VanillaDatabaseService.ValidateTargetAgainstVanilla(targetToBackup, nonVanillaFileFoundCallback);

                    Log.Information(@"Checking DLC consistency");
                    bool isDLCConsistent = VanillaDatabaseService.ValidateTargetDLCConsistency(targetToBackup, inconsistentDLCCallback: inconsistentDLCFoundCallback);

                    Log.Information(@"Checking only vanilla DLC is installed");
                    List <string> dlcModsInstalled = VanillaDatabaseService.GetInstalledDLCMods(targetToBackup).Select(x =>
                    {
                        var tpmi = ThirdPartyServices.GetThirdPartyModInfo(x, targetToBackup.Game);
                        if (tpmi != null)
                        {
                            return($@"{x} ({tpmi.modname})");
                        }
                        return(x);
                    }).ToList();
                    var installedDLC   = VanillaDatabaseService.GetInstalledOfficialDLC(targetToBackup);
                    var allOfficialDLC = MEDirectories.OfficialDLC(targetToBackup.Game);

                    if (installedDLC.Count() < allOfficialDLC.Count())
                    {
                        var dlcList = string.Join("\n - ", allOfficialDLC.Except(installedDLC).Select(x => $@"{MEDirectories.OfficialDLCNames(targetToBackup.Game)[x]} ({x})")); //do not localize
                        dlcList = @" - " + dlcList;
                        Log.Information(@"The following dlc will be missing in the backup if user continues: ");
                        Log.Information(dlcList);

                        Application.Current.Dispatcher.Invoke(delegate
                        {
                            var cancelDueToNotAllDLC = M3L.ShowDialog(window, M3L.GetString(M3L.string_dialog_notAllDLCInstalled, dlcList), M3L.GetString(M3L.string_someDlcNotInstalled), MessageBoxButton.YesNo, MessageBoxImage.Warning);
                            if (cancelDueToNotAllDLC == MessageBoxResult.No)
                            {
                                end = true;
                                EndBackup();
                                return;
                            }
                        });
                    }

                    Log.Information(@"Checking for TexturesMEM TFCs");
                    var memTextures = Directory.GetFiles(targetToBackup.TargetPath, @"TexturesMEM*.tfc", SearchOption.AllDirectories);

                    if (end)
                    {
                        return;
                    }
                    if (isVanilla && isDLCConsistent && !Enumerable.Any(dlcModsInstalled) && !Enumerable.Any(memTextures))
                    {
                        BackupStatus = M3L.GetString(M3L.string_waitingForUserInput);

                        string backupPath = null;
                        if (!targetToBackup.IsCustomOption)
                        {
                            // Creating a new backup
                            nbw.ReportProgress(0, TaskbarProgressBarState.Paused);

                            Application.Current.Dispatcher.Invoke(delegate
                            {
                                Log.Information(@"Prompting user to select backup destination");

                                CommonOpenFileDialog m = new CommonOpenFileDialog
                                {
                                    IsFolderPicker   = true,
                                    EnsurePathExists = true,
                                    Title            = M3L.GetString(M3L.string_selectBackupDestination)
                                };
                                if (m.ShowDialog() == CommonFileDialogResult.Ok)
                                {
                                    backupPath = m.FileName;
                                    Log.Information(@"Backup path chosen: " + backupPath);

                                    bool okToBackup = validateBackupPath(backupPath, targetToBackup);
                                    if (!okToBackup)
                                    {
                                        end = true;
                                        EndBackup();
                                        return;
                                    }
                                }
                                else
                                {
                                    end = true;
                                    EndBackup();
                                    return;
                                }
                            });
                            if (end)
                            {
                                return;
                            }
                            nbw.ReportProgress(0, TaskbarProgressBarState.Indeterminate);
                        }
                        else
                        {
                            Log.Information(@"Linking existing backup at " + targetToBackup.TargetPath);
                            backupPath = targetToBackup.TargetPath;
                            // Linking existing backup
                            Application.Current.Dispatcher.Invoke(delegate
                            {
                                bool okToBackup = validateBackupPath(targetToBackup.TargetPath, targetToBackup);
                                if (!okToBackup)
                                {
                                    end = true;
                                    EndBackup();
                                    return;
                                }
                            });
                        }

                        if (end)
                        {
                            return;
                        }

                        if (!targetToBackup.IsCustomOption)
                        {
                            #region callbacks and copy code

                            // Copy to new backup
                            void fileCopiedCallback()
                            {
                                ProgressValue++;
                                if (ProgressMax > 0)
                                {
                                    nbw.ReportProgress(0, ProgressValue * 1.0 / ProgressMax);
                                }
                            }

                            string dlcFolderpath   = M3Directories.GetDLCPath(targetToBackup) + '\\';
                            int    dlcSubStringLen = dlcFolderpath.Length;

                            bool aboutToCopyCallback(string file)
                            {
                                try
                                {
                                    if (file.Contains(@"\cmmbackup\"))
                                    {
                                        return(false);                               //do not copy cmmbackup files
                                    }
                                    if (file.StartsWith(dlcFolderpath, StringComparison.InvariantCultureIgnoreCase))
                                    {
                                        //It's a DLC!
                                        string dlcname             = file.Substring(dlcSubStringLen);
                                        var    dlcFolderNameEndPos = dlcname.IndexOf('\\');
                                        if (dlcFolderNameEndPos > 0)
                                        {
                                            dlcname = dlcname.Substring(0, dlcFolderNameEndPos);
                                            if (MEDirectories.OfficialDLCNames(targetToBackup.Game)
                                                .TryGetValue(dlcname, out var hrName))
                                            {
                                                BackupStatusLine2 = M3L.GetString(M3L.string_interp_backingUpX,
                                                                                  hrName);
                                            }
                                            else
                                            {
                                                BackupStatusLine2 = M3L.GetString(M3L.string_interp_backingUpX,
                                                                                  dlcname);
                                            }
                                        }
                                        else
                                        {
                                            // Loose files in the DLC folder
                                            BackupStatusLine2 = M3L.GetString(M3L.string_interp_backingUpX,
                                                                              M3L.GetString(M3L.string_basegame));
                                        }
                                    }
                                    else
                                    {
                                        //It's basegame
                                        if (file.EndsWith(@".bik"))
                                        {
                                            BackupStatusLine2 = M3L.GetString(M3L.string_interp_backingUpX,
                                                                              M3L.GetString(M3L.string_movies));
                                        }
                                        else if (new FileInfo(file).Length > 52428800)
                                        {
                                            BackupStatusLine2 = M3L.GetString(M3L.string_interp_backingUpX,
                                                                              Path.GetFileName(file));
                                        }
                                        else
                                        {
                                            BackupStatusLine2 = M3L.GetString(M3L.string_interp_backingUpX,
                                                                              M3L.GetString(M3L.string_basegame));
                                        }
                                    }
                                }
                                catch (Exception e)
                                {
                                    Crashes.TrackError(e, new Dictionary <string, string>()
                                    {
                                        { @"dlcFolderpath", dlcFolderpath },
                                        { @"dlcSubStringLen", dlcSubStringLen.ToString() },
                                        { @"file", file }
                                    });
                                }

                                return(true);
                            }

                            void totalFilesToCopyCallback(int total)
                            {
                                ProgressValue         = 0;
                                ProgressIndeterminate = false;
                                ProgressMax           = total;
                                nbw.ReportProgress(0, TaskbarProgressBarState.Normal);
                            }

                            BackupStatus = M3L.GetString(M3L.string_creatingBackup);
                            Log.Information($@"Backing up {targetToBackup.TargetPath} to {backupPath}");
                            nbw.ReportProgress(0, TaskbarProgressBarState.Normal);
                            CopyDir.CopyAll_ProgressBar(new DirectoryInfo(targetToBackup.TargetPath),
                                                        new DirectoryInfo(backupPath),
                                                        totalItemsToCopyCallback: totalFilesToCopyCallback,
                                                        aboutToCopyCallback: aboutToCopyCallback,
                                                        fileCopiedCallback: fileCopiedCallback,
                                                        ignoredExtensions: new[] { @"*.pdf", @"*.mp3" });
                            #endregion
                        }

                        // Write key
                        switch (Game)
                        {
                        case MEGame.ME1:
                        case MEGame.ME2:
                            Utilities.WriteRegistryKey(App.BACKUP_REGISTRY_KEY, Game + @"VanillaBackupLocation",
                                                       backupPath);
                            break;

                        case MEGame.ME3:
                            Utilities.WriteRegistryKey(App.REGISTRY_KEY_ME3CMM, @"VanillaCopyLocation",
                                                       backupPath);
                            break;
                        }

                        var cmmvanilla = Path.Combine(backupPath, @"cmm_vanilla");
                        if (!File.Exists(cmmvanilla))
                        {
                            Log.Information($@"Writing cmm_vanilla to " + cmmvanilla);
                            File.Create(cmmvanilla).Close();
                        }

                        Log.Information($@"Backup completed.");

                        Analytics.TrackEvent(@"Created a backup", new Dictionary <string, string>()
                        {
                            { @"Game", Game.ToString() },
                            { @"Result", @"Success" },
                            { @"Type", targetToBackup.IsCustomOption ? @"Linked" : @"Copy" }
                        });

                        EndBackup();
                        return;
                    }


                    if (!isVanilla)
                    {
                        //Show UI for non vanilla
                        Analytics.TrackEvent(@"Created a backup", new Dictionary <string, string>()
                        {
                            { @"Game", Game.ToString() },
                            { @"Result", @"Failure, Game modified" }
                        });
                        b.Result = (nonVanillaFiles, M3L.GetString(M3L.string_cannotBackupModifiedGame),
                                    M3L.GetString(M3L.string_followingFilesDoNotMatchTheVanillaDatabase));
                    }
                    else if (!isDLCConsistent)
                    {
                        Analytics.TrackEvent(@"Created a backup", new Dictionary <string, string>()
                        {
                            { @"Game", Game.ToString() },
                            { @"Result", @"Failure, DLC inconsistent" }
                        });
                        if (targetToBackup.Supported)
                        {
                            b.Result = (inconsistentDLC, M3L.GetString(M3L.string_inconsistentDLCDetected),
                                        M3L.GetString(M3L.string_dialogTheFollowingDLCAreInAnInconsistentState));
                        }
                        else
                        {
                            b.Result = (M3L.GetString(M3L.string_inconsistentDLCDetected),
                                        M3L.GetString(M3L.string_inconsistentDLCDetectedUnofficialGame));
                        }
                    }
                    else if (Enumerable.Any(dlcModsInstalled))
                    {
                        Analytics.TrackEvent(@"Created a backup", new Dictionary <string, string>()
                        {
                            { @"Game", Game.ToString() },
                            { @"Result", @"Failure, DLC mods found" }
                        });
                        b.Result = (dlcModsInstalled, M3L.GetString(M3L.string_dlcModsAreInstalled),
                                    M3L.GetString(M3L.string_dialogDLCModsWereDetectedCannotBackup));
                    }
                    else if (Enumerable.Any(memTextures))
                    {
                        Analytics.TrackEvent(@"Created a backup", new Dictionary <string, string>()
                        {
                            { @"Game", Game.ToString() },
                            { @"Result", @"Failure, TexturesMEM files found" }
                        });
                        b.Result = (M3L.GetString(M3L.string_leftoverTextureFilesFound),
                                    M3L.GetString(M3L.string_dialog_foundLeftoverTextureFiles));
                    }
                    EndBackup();
                };
                nbw.RunWorkerCompleted += (a, b) =>
                {
                    if (b.Error != null)
                    {
                        Log.Error($@"Exception occurred in {nbw.Name} thread: {b.Error.Message}");
                    }
                    TaskbarHelper.SetProgressState(TaskbarProgressBarState.NoProgress);
                    if (b.Result is (List <string> listItems, string title, string text))
                    {
                        ListDialog ld = new ListDialog(listItems, title, text, window);
                        ld.Show();
                    }
                    else if (b.Result is (string errortitle, string message))
                    {
                        M3L.ShowDialog(window, message, errortitle, MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                    CommandManager.InvalidateRequerySuggested();
                };
                nbw.RunWorkerAsync();
            }
示例#22
0
            private void BeginRestore()
            {
                if (Utilities.IsGameRunning(Game))
                {
                    M3L.ShowDialog(window, M3L.GetString(M3L.string_interp_dialogCannotRestoreXWhileItIsRunning, Utilities.GetGameName(Game)), M3L.GetString(M3L.string_gameRunning), MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                bool restore = RestoreTarget.IsCustomOption; //custom option is restore to custom location

                restore = restore || M3L.ShowDialog(window, M3L.GetString(M3L.string_dialog_restoringXWillDeleteGameDir, Utilities.GetGameName(Game)), M3L.GetString(M3L.string_gameTargetWillBeDeleted), MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes;
                if (restore)
                {
                    NamedBackgroundWorker nbw = new NamedBackgroundWorker(Game + @"-Restore");
                    nbw.WorkerReportsProgress = true;
                    nbw.ProgressChanged      += (a, b) =>
                    {
                        if (b.UserState is double d)
                        {
                            TaskbarHelper.SetProgress(d);
                        }
                    };
                    nbw.DoWork += (a, b) =>
                    {
                        RestoreInProgress = true;


                        string restoreTargetPath = b.Argument as string;
                        string backupPath        = BackupLocation;
                        BackupStatusLine2 = M3L.GetString(M3L.string_deletingExistingGameInstallation);
                        if (Directory.Exists(restoreTargetPath))
                        {
                            if (Directory.GetFiles(restoreTargetPath).Any() || Directory.GetDirectories(restoreTargetPath).Any())
                            {
                                Log.Information(@"Deleting existing game directory: " + restoreTargetPath);
                                try
                                {
                                    bool deletedDirectory = Utilities.DeleteFilesAndFoldersRecursively(restoreTargetPath);
                                    if (deletedDirectory != true)
                                    {
                                        b.Result = RestoreResult.ERROR_COULD_NOT_DELETE_GAME_DIRECTORY;
                                        return;
                                    }
                                }
                                catch (Exception ex)
                                {
                                    //todo: handle this better
                                    Log.Error($@"Exception deleting game directory: {restoreTargetPath}: {ex.Message}");
                                    b.Result = RestoreResult.EXCEPTION_DELETING_GAME_DIRECTORY;
                                    return;
                                }
                            }
                        }
                        else
                        {
                            Log.Error(@"Game directory not found! Was it removed while the app was running?");
                        }

                        //Todo: Revert LODs, remove IndirectSound settings (MEUITM)

                        var created = Utilities.CreateDirectoryWithWritePermission(restoreTargetPath);
                        if (!created)
                        {
                            b.Result = RestoreResult.ERROR_COULD_NOT_CREATE_DIRECTORY;
                            return;
                        }

                        BackupStatusLine2 = M3L.GetString(M3L.string_restoringGameFromBackup);
                        if (restoreTargetPath != null)
                        {
                            //callbacks

                            #region callbacks

                            void fileCopiedCallback()
                            {
                                ProgressValue++;
                                if (ProgressMax != 0)
                                {
                                    nbw.ReportProgress(0, ProgressValue * 1.0 / ProgressMax);
                                }
                            }

                            string dlcFolderpath   = MEDirectories.DLCPath(backupPath, Game) + '\\'; //\ at end makes sure we are restoring a subdir
                            int    dlcSubStringLen = dlcFolderpath.Length;
                            Debug.WriteLine(@"DLC Folder: " + dlcFolderpath);
                            Debug.Write(@"DLC Fodler path len:" + dlcFolderpath);

                            bool aboutToCopyCallback(string fileBeingCopied)
                            {
                                if (fileBeingCopied.Contains(@"\cmmbackup\"))
                                {
                                    return(false);                                          //do not copy cmmbackup files
                                }
                                Debug.WriteLine(fileBeingCopied);
                                if (fileBeingCopied.StartsWith(dlcFolderpath, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    //It's a DLC!
                                    string dlcname = fileBeingCopied.Substring(dlcSubStringLen);
                                    int    index   = dlcname.IndexOf('\\');
                                    try
                                    {
                                        dlcname = dlcname.Substring(0, index);
                                        if (MEDirectories.OfficialDLCNames(RestoreTarget.Game).TryGetValue(dlcname, out var hrName))
                                        {
                                            BackupStatusLine2 = M3L.GetString(M3L.string_interp_restoringX, hrName);
                                        }
                                        else
                                        {
                                            BackupStatusLine2 = M3L.GetString(M3L.string_interp_restoringX, dlcname);
                                        }
                                    }
                                    catch (Exception e)
                                    {
                                        Crashes.TrackError(e, new Dictionary <string, string>()
                                        {
                                            { @"Source", @"Restore UI display callback" },
                                            { @"Value", fileBeingCopied },
                                            { @"DLC Folder path", dlcFolderpath }
                                        });
                                    }
                                }
                                else
                                {
                                    //It's basegame
                                    if (fileBeingCopied.EndsWith(@".bik"))
                                    {
                                        BackupStatusLine2 = M3L.GetString(M3L.string_restoringMovies);
                                    }
                                    else if (new FileInfo(fileBeingCopied).Length > 52428800)
                                    {
                                        BackupStatusLine2 = M3L.GetString(M3L.string_interp_restoringX, Path.GetFileName(fileBeingCopied));
                                    }
                                    else
                                    {
                                        BackupStatusLine2 = M3L.GetString(M3L.string_restoringBasegame);
                                    }
                                }

                                return(true);
                            }

                            void totalFilesToCopyCallback(int total)
                            {
                                ProgressValue         = 0;
                                ProgressIndeterminate = false;
                                ProgressMax           = total;
                            }

                            #endregion

                            BackupStatus = M3L.GetString(M3L.string_restoringGame);
                            Log.Information($@"Copying backup to game directory: {backupPath} -> {restoreTargetPath}");
                            CopyDir.CopyAll_ProgressBar(new DirectoryInfo(backupPath), new DirectoryInfo(restoreTargetPath),
                                                        totalItemsToCopyCallback: totalFilesToCopyCallback,
                                                        aboutToCopyCallback: aboutToCopyCallback,
                                                        fileCopiedCallback: fileCopiedCallback,
                                                        ignoredExtensions: new[] { @"*.pdf", @"*.mp3" });
                            Log.Information(@"Restore of game data has completed");
                        }

                        //Check for cmmvanilla file and remove it present

                        string cmmVanilla = Path.Combine(restoreTargetPath, @"cmm_vanilla");
                        if (File.Exists(cmmVanilla))
                        {
                            Log.Information(@"Removing cmm_vanilla file");
                            File.Delete(cmmVanilla);
                        }

                        Log.Information(@"Restore thread wrapping up");
                        RestoreTarget.ReloadGameTarget();
                        b.Result = RestoreResult.RESTORE_OK;
                    };
                    nbw.RunWorkerCompleted += (a, b) =>
                    {
                        if (b.Error != null)
                        {
                            Log.Error($@"Exception occurred in {nbw.Name} thread: {b.Error.Message}");
                        }
                        TaskbarHelper.SetProgressState(TaskbarProgressBarState.NoProgress);
                        if (b.Result is RestoreResult result)
                        {
                            switch (result)
                            {
                            case RestoreResult.ERROR_COULD_NOT_CREATE_DIRECTORY:
                                Analytics.TrackEvent(@"Restored game", new Dictionary <string, string>()
                                {
                                    { @"Game", Game.ToString() },
                                    { @"Result", @"Failure, Could not create target directory" }
                                });
                                M3L.ShowDialog(window, M3L.GetString(M3L.string_dialogCouldNotCreateGameDirectoryAfterDeletion), M3L.GetString(M3L.string_errorRestoringGame), MessageBoxButton.OK, MessageBoxImage.Error);
                                break;

                            case RestoreResult.ERROR_COULD_NOT_DELETE_GAME_DIRECTORY:
                                Analytics.TrackEvent(@"Restored game", new Dictionary <string, string>()
                                {
                                    { @"Game", Game.ToString() },
                                    { @"Result", @"Failure, Could not delete existing game directory" }
                                });
                                M3L.ShowDialog(window, M3L.GetString(M3L.string_dialogcouldNotFullyDeleteGameDirectory), M3L.GetString(M3L.string_errorRestoringGame), MessageBoxButton.OK, MessageBoxImage.Error);
                                break;

                            case RestoreResult.EXCEPTION_DELETING_GAME_DIRECTORY:
                                Analytics.TrackEvent(@"Restored game", new Dictionary <string, string>()
                                {
                                    { @"Game", Game.ToString() },
                                    { @"Result", @"Failure, Exception deleting existing game directory" }
                                });
                                M3L.ShowDialog(window, M3L.GetString(M3L.string_dialogErrorOccuredDeletingGameDirectory), M3L.GetString(M3L.string_errorRestoringGame), MessageBoxButton.OK, MessageBoxImage.Error);
                                break;

                            case RestoreResult.RESTORE_OK:
                                Analytics.TrackEvent(@"Restored game", new Dictionary <string, string>()
                                {
                                    { @"Game", Game.ToString() },
                                    { @"Result", @"Success" }
                                });
                                break;
                            }
                        }

                        EndRestore();
                        CommandManager.InvalidateRequerySuggested();
                    };
                    var restTarget = RestoreTarget.TargetPath;
                    if (RestoreTarget.IsCustomOption)
                    {
                        CommonOpenFileDialog m = new CommonOpenFileDialog
                        {
                            IsFolderPicker   = true,
                            EnsurePathExists = true,
                            Title            = M3L.GetString(M3L.string_selectNewRestoreDestination)
                        };
                        if (m.ShowDialog() == CommonFileDialogResult.Ok)
                        {
                            //Check empty
                            restTarget = m.FileName;
                            if (Directory.Exists(restTarget))
                            {
                                if (Directory.GetFiles(restTarget).Length > 0 || Directory.GetDirectories(restTarget).Length > 0)
                                {
                                    //Directory not empty
                                    M3L.ShowDialog(window, M3L.GetString(M3L.string_dialogDirectoryIsNotEmptyLocationToRestoreToMustBeEmpty), M3L.GetString(M3L.string_cannotRestoreToThisLocation), MessageBoxButton.OK, MessageBoxImage.Error);
                                    return;
                                }

                                //TODO: PREVENT RESTORING TO DOCUMENTS/BIOWARE
                            }

                            Analytics.TrackEvent(@"Chose to restore game to custom location", new Dictionary <string, string>()
                            {
                                { @"Game", Game.ToString() }
                            });
                        }
                        else
                        {
                            return;
                        }
                    }

                    RefreshTargets = true;
                    TaskbarHelper.SetProgress(0);
                    TaskbarHelper.SetProgressState(TaskbarProgressBarState.Normal);
                    nbw.RunWorkerAsync(restTarget);
                }
            }
示例#23
0
 private void Timer_OnProgress(object sender, int e)
 {
     Threading.ComponentInvoke(progressBar1, (x) => x.Value = e);
     TaskbarHelper.SetProgress(SaiHelper.AppProcess, e, progressBar1.Maximum);
 }
        private void UpdateModMakerMod(OnlineContent.ModMakerModUpdateInfo mui)
        {
            //throw new NotImplementedException();
            NamedBackgroundWorker nbw = new NamedBackgroundWorker(@"ModmakerModUpdaterThread-" + mui.mod.ModName);

            nbw.WorkerReportsProgress = true;
            nbw.ProgressChanged      += (a, b) =>
            {
                if (b.UserState is double d)
                {
                    TaskbarHelper.SetProgress(d);
                }
            };
            nbw.DoWork += (a, b) =>
            {
                mui.DownloadButtonText = M3L.GetString(M3L.string_compiling);

                OperationInProgress  = true;
                mui.UpdateInProgress = true;
                mui.Indeterminate    = false;

                mui.UIStatusString = M3L.GetString(M3L.string_downloadingDelta);
                var normalEndpoint = OnlineContent.ModmakerModsEndpoint + mui.ModMakerId;
                var lzmaEndpoint   = normalEndpoint + @"&method=lzma";

                string modDelta = null;

                //Try LZMA first
                try
                {
                    var download = OnlineContent.DownloadToMemory(lzmaEndpoint);
                    if (download.errorMessage == null)
                    {
                        mui.UIStatusString = M3L.GetString(M3L.string_decompressingDelta);
                        // OK
                        var decompressed = SevenZipHelper.LZMA.DecompressLZMAFile(download.result.ToArray());
                        modDelta = Encoding.UTF8.GetString(decompressed);
                    }
                    else
                    {
                        Log.Error(@"Error downloading lzma mod delta to memory: " + download.errorMessage);
                    }
                }
                catch (Exception e)
                {
                    Log.Error(@"Error downloading LZMA mod delta to memory: " + e.Message);
                }

                if (modDelta == null)
                {
                    //failed to download LZMA.
                    var download = OnlineContent.DownloadToMemory(normalEndpoint);
                    if (download.errorMessage == null)
                    {
                        //OK
                        modDelta = Encoding.UTF8.GetString(download.result.ToArray());
                    }
                    else
                    {
                        Log.Error(@"Error downloading decompressed mod delta to memory: " + download.errorMessage);
                    }
                }

                void setOverallMax(int max)
                {
                    mui.OverallProgressMax = max;
                }

                void setOverallValue(int current)
                {
                    mui.OverallProgressValue = current;
                    nbw.ReportProgress(0, current * 1.0 / mui.OverallProgressMax);
                    if (current > mui.OverallProgressMax)
                    {
                        Debugger.Break();
                    }
                }

                void setCurrentTaskString(string str)
                {
                    mui.UIStatusString = str;
                }

                if (modDelta != null)
                {
                    var compiler = new ModMakerCompiler(mui.ModMakerId);
                    //compiler.SetCurrentMaxCallback = SetCurrentMax;
                    //compiler.SetCurrentValueCallback = SetCurrentProgressValue;
                    compiler.SetOverallMaxCallback   = setOverallMax;
                    compiler.SetOverallValueCallback = setOverallValue;
                    //compiler.SetCurrentTaskIndeterminateCallback = SetCurrentTaskIndeterminate;
                    compiler.SetCurrentTaskStringCallback = setCurrentTaskString;
                    //compiler.SetModNameCallback = SetModNameOrDownloadText;
                    //compiler.SetCompileStarted = CompilationInProgress;
                    //compiler.SetModNotFoundCallback = ModNotFound;
                    Mod m = compiler.DownloadAndCompileMod(modDelta);
                    if (m != null)
                    {
                        try
                        {
                            File.WriteAllText(System.IO.Path.Combine(Utilities.GetModmakerDefinitionsCache(), mui.ModMakerId + @".xml"), modDelta);
                        }
                        catch (Exception e)
                        {
                            Log.Error(@"Couldn't cache modmaker xml file: " + e.Message);
                        }

                        mui.DownloadButtonText = M3L.GetString(M3L.string_updated);
                        mui.UIStatusString     = M3L.GetString(M3L.string_interp_modMakerCodeX, mui.ModMakerId);
                        mui.UpdateInProgress   = false;
                        mui.CanUpdate          = false;
                        AnyModUpdated          = true;
                    }
                    else
                    {
                        mui.UpdateInProgress   = false;
                        mui.DownloadButtonText = M3L.GetString(M3L.string_compilingFailed);
                        mui.UpdateInProgress   = false;
                    }
                }
            };
            nbw.RunWorkerCompleted += (a, b) =>
            {
                if (b.Error != null)
                {
                    Log.Error($@"Exception occurred in {nbw.Name} thread: {b.Error.Message}");
                }
                Analytics.TrackEvent(@"Updated mod", new Dictionary <string, string>()
                {
                    { @"Type", @"ModMaker" },
                    { @"ModName", mui.mod.ModName },
                    { @"Result", mui.CanUpdate ? @"Success" : @"Failed" }
                });

                TaskbarHelper.SetProgressState(TaskbarProgressBarState.NoProgress);
                OperationInProgress = false;
                CommandManager.InvalidateRequerySuggested();
            };
            TaskbarHelper.SetProgress(0);
            TaskbarHelper.SetProgressState(TaskbarProgressBarState.Normal);
            nbw.RunWorkerAsync();
        }
示例#25
0
        public static async void StartRestore(MainWindow mw, bool isQuick, Action postRestoreDelegate = null)
        {
            var pd = await mw.ShowProgressAsync("Restoring game", "Preparing to restore game");

            pd.SetIndeterminate();
            await Task.Run(() =>
            {
                if (isQuick)
                {
                    // Nuke the DLC
                    MERLog.Information(@"Quick restore started");
                    pd.SetMessage("Removing randomize DLC component");
                    var dlcModPath = MERFileSystem.GetDLCModPath();
                    if (Directory.Exists(dlcModPath))
                    {
                        MERLog.Information($@"Deleting {dlcModPath}");
                        Utilities.DeleteFilesAndFoldersRecursively(dlcModPath);
                    }

                    mw.DLCComponentInstalled = false;


                    // Restore basegame only files
                    pd.SetMessage("Restoring randomized basegame files");
                    var isControllerModInstalled = SFXGame.IsControllerBasedInstall();

                    var backupPath       = BackupService.GetGameBackupPath(MERFileSystem.Game, out _, false);
                    var gameCookedPath   = M3Directories.GetCookedPath(Locations.GetTarget(MERFileSystem.Game));
                    var backupCookedPath = MEDirectories.GetCookedPath(MERFileSystem.Game, backupPath);
                    foreach (var bgf in MERFileSystem.alwaysBasegameFiles)
                    {
                        var srcPath  = Path.Combine(backupCookedPath, bgf);
                        var destPath = Path.Combine(gameCookedPath, bgf);
                        MERLog.Information($@"Restoring {bgf}");
                        File.Copy(srcPath, destPath, true);
                    }

                    if (isControllerModInstalled)
                    {
                        // We must also restore Coalesced.ini or it will reference a UI that is no longer available and game will not boot
                        MERLog.Information(@"Controller based install detected, also restoring Coalesced.ini to prevent startup crash");
                        File.Copy(Path.Combine(backupPath, "BioGame", "Config", "PC", "Cooked", "Coalesced.ini"), Path.Combine(Locations.GetTarget(MERFileSystem.Game).TargetPath, "BioGame", "Config", "PC", "Cooked", "Coalesced.ini"), true);
                    }

                    // Delete basegame TFC
                    var baseTFC = MERFileSystem.GetTFCPath(false);
                    if (File.Exists(baseTFC))
                    {
                        File.Delete(baseTFC);
                    }

                    // Done!
                }
                else
                {
                    // Full restore
                    var target = Locations.GetTarget(MERFileSystem.Game);
                    MERLog.Information($@"Performing full game restore on {target.TargetPath} target after restore");

                    object syncObj = new object();
                    BackupHandler.GameRestore gr = new BackupHandler.GameRestore(MERFileSystem.Game)
                    {
                        ConfirmationCallback = (title, message) =>
                        {
                            bool response = false;
                            Application.Current.Dispatcher.Invoke(async() =>
                            {
                                response = await mw.ShowMessageAsync(title, message,
                                                                     MessageDialogStyle.AffirmativeAndNegative,
                                                                     new MetroDialogSettings()
                                {
                                    AffirmativeButtonText = "OK",
                                    NegativeButtonText    = "Cancel",
                                }) == MessageDialogResult.Affirmative;
                                lock (syncObj)
                                {
                                    Monitor.Pulse(syncObj);
                                }
                            });
                            lock (syncObj)
                            {
                                Monitor.Wait(syncObj);
                            }

                            return(response);
                        },
                        BlockingErrorCallback = (title, message) => { Application.Current.Dispatcher.Invoke(async() => { await mw.ShowMessageAsync(title, message); }); },
                        RestoreErrorCallback  = (title, message) => { Application.Current.Dispatcher.Invoke(async() => { await mw.ShowMessageAsync(title, message); }); },
                        UpdateStatusCallback  = message =>
                                                Application.Current.Dispatcher.Invoke(() => pd.SetMessage(message)),
                        UpdateProgressCallback = (done, total) =>
                                                 Application.Current.Dispatcher.Invoke(() =>
                        {
                            pd.SetProgress(done * 1d / total);
                            if (total != 0)
                            {
                                TaskbarHelper.SetProgressState(TaskbarProgressBarState.Normal);
                                TaskbarHelper.SetProgress(done * 1.0 / total);
                            }
                        }),
                        SetProgressIndeterminateCallback = indeterminate => Application.Current.Dispatcher.Invoke(() =>
                        {
                            if (indeterminate)
                            {
                                pd.SetIndeterminate();
                            }
                            TaskbarHelper.SetProgressState(indeterminate ? TaskbarProgressBarState.Indeterminate : TaskbarProgressBarState.Normal);
                        }),
                        SelectDestinationDirectoryCallback = (title, message) =>
                        {
                            string selectedPath = null;
                            Application.Current.Dispatcher.Invoke(() =>
                            {
                                // Not sure if this has to be synced
                                CommonOpenFileDialog ofd = new CommonOpenFileDialog()
                                {
                                    Title            = "Select restore destination directory",
                                    IsFolderPicker   = true,
                                    EnsurePathExists = true
                                };
                                if (ofd.ShowDialog() == CommonFileDialogResult.Ok)
                                {
                                    selectedPath = ofd.FileName;
                                }
                            });
                            return(selectedPath);
                        }
                    };
                    gr.PerformRestore(target.TargetPath);
                    mw.DLCComponentInstalled = false;
                    MERLog.Information(@"Reloading target after restore");
                    target.ReloadGameTarget(false, false);
                    mw.SetupTargetDescriptionText();
                }
            }).ContinueWithOnUIThread(async x =>
            {
                TaskbarHelper.SetProgressState(TaskbarProgressBarState.NoProgress);
                await pd.CloseAsync();
                postRestoreDelegate?.Invoke();
            });
        }
            private void BeginRestore()
            {
                if (Utilities.IsGameRunning(Game))
                {
                    M3L.ShowDialog(window, M3L.GetString(M3L.string_interp_dialogCannotRestoreXWhileItIsRunning, Game.ToGameName()), M3L.GetString(M3L.string_gameRunning), MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                var useNewMethod = M3L.ShowDialog(window,
                                                  M3L.GetString(M3L.string_beta_useNewRestoreMethod),
                                                  M3L.GetString(M3L.string_useBetaFeatureQuestion), MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes;

                bool restore = RestoreTarget.IsCustomOption || useNewMethod; //custom option is restore to custom location

                restore = restore || M3L.ShowDialog(window, M3L.GetString(M3L.string_dialog_restoringXWillDeleteGameDir, Game.ToGameName()), M3L.GetString(M3L.string_gameTargetWillBeDeleted), MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes;
                if (restore)
                {
                    NamedBackgroundWorker nbw = new NamedBackgroundWorker(Game + @"-Restore");
                    nbw.WorkerReportsProgress = true;
                    nbw.ProgressChanged      += (a, b) =>
                    {
                        if (b.UserState is double d)
                        {
                            TaskbarHelper.SetProgress(d);
                        }
                    };
                    nbw.DoWork += (a, b) =>
                    {
                        RestoreInProgress = true;
                        // Nuke the LODs
                        if (!RestoreTarget.IsCustomOption && RestoreTarget.Game.IsOTGame())
                        {
                            Log.Information($@"Resetting LODs for {RestoreTarget.Game}");
                            Utilities.SetLODs(RestoreTarget, false, false, false);
                        }

                        string restoreTargetPath = b.Argument as string;
                        string backupPath        = BackupLocation;

                        if (!useNewMethod)
                        {
                            BackupStatusLine2 = M3L.GetString(M3L.string_deletingExistingGameInstallation);
                            if (Directory.Exists(restoreTargetPath))
                            {
                                if (Directory.GetFiles(restoreTargetPath).Any() ||
                                    Directory.GetDirectories(restoreTargetPath).Any())
                                {
                                    Log.Information(@"Deleting existing game directory: " + restoreTargetPath);
                                    try
                                    {
                                        bool deletedDirectory =
                                            Utilities.DeleteFilesAndFoldersRecursively(restoreTargetPath);
                                        if (deletedDirectory != true)
                                        {
                                            b.Result = RestoreResult.ERROR_COULD_NOT_DELETE_GAME_DIRECTORY;
                                            return;
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        //todo: handle this better
                                        Log.Error(
                                            $@"Exception deleting game directory: {restoreTargetPath}: {ex.Message}");
                                        b.Result = RestoreResult.EXCEPTION_DELETING_GAME_DIRECTORY;
                                        return;
                                    }
                                }
                            }
                            else
                            {
                                Log.Error(@"Game directory not found! Was it removed while the app was running?");
                            }

                            var created = Utilities.CreateDirectoryWithWritePermission(restoreTargetPath);
                            if (!created)
                            {
                                b.Result = RestoreResult.ERROR_COULD_NOT_CREATE_DIRECTORY;
                                return;
                            }
                        }

                        BackupStatusLine2 = M3L.GetString(M3L.string_restoringGameFromBackup);
                        if (restoreTargetPath != null)
                        {
                            //callbacks

                            #region callbacks

                            void fileCopiedCallback()
                            {
                                ProgressValue++;
                                if (ProgressMax != 0)
                                {
                                    nbw.ReportProgress(0, ProgressValue * 1.0 / ProgressMax);
                                }
                            }

                            string dlcFolderpath   = MEDirectories.GetDLCPath(Game, backupPath) + '\\'; //\ at end makes sure we are restoring a subdir
                            int    dlcSubStringLen = dlcFolderpath.Length;
                            Debug.WriteLine(@"DLC Folder: " + dlcFolderpath);
                            Debug.Write(@"DLC Folder path len:" + dlcFolderpath);

                            bool aboutToCopyCallback(string fileBeingCopied)
                            {
                                if (fileBeingCopied.Contains(@"\cmmbackup\"))
                                {
                                    return(false);                                          //do not copy cmmbackup files
                                }
                                Debug.WriteLine(fileBeingCopied);
                                if (fileBeingCopied.StartsWith(dlcFolderpath, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    //It's a DLC!
                                    string dlcname = fileBeingCopied.Substring(dlcSubStringLen);
                                    int    index   = dlcname.IndexOf('\\');
                                    if (index > 0) //Files directly in the DLC directory won't have path sep
                                    {
                                        try
                                        {
                                            dlcname = dlcname.Substring(0, index);
                                            if (MEDirectories.OfficialDLCNames(RestoreTarget.Game).TryGetValue(dlcname, out var hrName))
                                            {
                                                BackupStatusLine2 = M3L.GetString(M3L.string_interp_restoringX, hrName);
                                            }
                                            else
                                            {
                                                BackupStatusLine2 = M3L.GetString(M3L.string_interp_restoringX, dlcname);
                                            }
                                        }
                                        catch (Exception e)
                                        {
                                            Crashes.TrackError(e, new Dictionary <string, string>()
                                            {
                                                { @"Source", @"Restore UI display callback" },
                                                { @"Value", fileBeingCopied },
                                                { @"DLC Folder path", dlcFolderpath }
                                            });
                                        }
                                    }
                                }
                                else
                                {
                                    //It's basegame
                                    if (fileBeingCopied.EndsWith(@".bik"))
                                    {
                                        BackupStatusLine2 = M3L.GetString(M3L.string_restoringMovies);
                                    }
                                    else if (new FileInfo(fileBeingCopied).Length > 52428800)
                                    {
                                        BackupStatusLine2 = M3L.GetString(M3L.string_interp_restoringX, Path.GetFileName(fileBeingCopied));
                                    }
                                    else
                                    {
                                        BackupStatusLine2 = M3L.GetString(M3L.string_restoringBasegame);
                                    }
                                }

                                return(true);
                            }

                            void totalFilesToCopyCallback(int total)
                            {
                                ProgressValue         = 0;
                                ProgressIndeterminate = false;
                                ProgressMax           = total;
                            }

                            #endregion

                            BackupStatus = M3L.GetString(M3L.string_restoringGame);

                            // LE: Backup Config file so settings don't get lost
                            string configText = null;
                            var    configPath = RestoreTarget.Game.IsLEGame() ? M3Directories.GetLODConfigFile(RestoreTarget) : null;
                            if (File.Exists(configPath))
                            {
                                configText = File.ReadAllText(configPath); // backup to memory
                            }

                            Log.Information($@"Copying backup to game directory: {backupPath} -> {restoreTargetPath}");
                            if (useNewMethod)
                            {
                                string      CurrentRCFile = null;
                                RoboCommand rc            = new RoboCommand();
                                rc.CopyOptions.Destination = restoreTargetPath;
                                rc.CopyOptions.Source      = backupPath;
                                rc.CopyOptions.Mirror      = true;
                                rc.CopyOptions.MultiThreadedCopiesCount = 2;
                                rc.OnCopyProgressChanged += (sender, args) =>
                                {
                                    ProgressIndeterminate = false;
                                    ProgressValue         = (int)args.CurrentFileProgress;
                                    ProgressMax           = 100;
                                };
                                rc.OnFileProcessed += (sender, args) =>
                                {
                                    if (args.ProcessedFile.Name.StartsWith(backupPath) && args.ProcessedFile.Name.Length > backupPath.Length)
                                    {
                                        CurrentRCFile     = args.ProcessedFile.Name.Substring(backupPath.Length + 1);
                                        BackupStatusLine2 = M3L.GetString(M3L.string_interp_copyingX, CurrentRCFile);
                                    }
                                };
                                rc.Start().Wait();
                            }
                            else
                            {
                                CopyDir.CopyAll_ProgressBar(new DirectoryInfo(backupPath),
                                                            new DirectoryInfo(restoreTargetPath),
                                                            totalItemsToCopyCallback: totalFilesToCopyCallback,
                                                            aboutToCopyCallback: aboutToCopyCallback,
                                                            fileCopiedCallback: fileCopiedCallback,
                                                            ignoredExtensions: new[] { @"*.pdf", @"*.mp3" });
                            }

                            Log.Information(@"Restore of game data has completed");

                            if (configText != null)
                            {
                                // Restore config file
                                try
                                {
                                    Directory.CreateDirectory(Directory.GetParent(configPath).FullName);
                                    File.WriteAllText(configPath, configText);
                                    Log.Information(@"Restored config file");
                                }
                                catch (Exception e)
                                {
                                    Log.Error($@"Could not restore config file: {e.Message}");
                                }
                            }
                            BackupCopyFinished(restoreTargetPath);
                        }
                    };
                    nbw.RunWorkerCompleted += (a, b) =>
                    {
                        if (b.Error != null)
                        {
                            Log.Error($@"Exception occurred in {nbw.Name} thread: {b.Error.Message}");
                        }
                        TaskbarHelper.SetProgressState(TaskbarProgressBarState.NoProgress);
                        if (b.Result is RestoreResult result)
                        {
                            switch (result)
                            {
                            case RestoreResult.ERROR_COULD_NOT_CREATE_DIRECTORY:
                                Analytics.TrackEvent(@"Restored game", new Dictionary <string, string>()
                                {
                                    { @"Game", Game.ToString() },
                                    { @"Result", @"Failure, Could not create target directory" }
                                });
                                M3L.ShowDialog(window, M3L.GetString(M3L.string_dialogCouldNotCreateGameDirectoryAfterDeletion), M3L.GetString(M3L.string_errorRestoringGame), MessageBoxButton.OK, MessageBoxImage.Error);
                                break;

                            case RestoreResult.ERROR_COULD_NOT_DELETE_GAME_DIRECTORY:
                                Analytics.TrackEvent(@"Restored game", new Dictionary <string, string>()
                                {
                                    { @"Game", Game.ToString() },
                                    { @"Result", @"Failure, Could not delete existing game directory" }
                                });
                                M3L.ShowDialog(window, M3L.GetString(M3L.string_dialogcouldNotFullyDeleteGameDirectory), M3L.GetString(M3L.string_errorRestoringGame), MessageBoxButton.OK, MessageBoxImage.Error);
                                break;

                            case RestoreResult.EXCEPTION_DELETING_GAME_DIRECTORY:
                                Analytics.TrackEvent(@"Restored game", new Dictionary <string, string>()
                                {
                                    { @"Game", Game.ToString() },
                                    { @"Result", @"Failure, Exception deleting existing game directory" }
                                });
                                M3L.ShowDialog(window, M3L.GetString(M3L.string_dialogErrorOccuredDeletingGameDirectory), M3L.GetString(M3L.string_errorRestoringGame), MessageBoxButton.OK, MessageBoxImage.Error);
                                break;

                            case RestoreResult.RESTORE_OK:
                                Analytics.TrackEvent(@"Restored game", new Dictionary <string, string>()
                                {
                                    { @"Game", Game.ToString() },
                                    { @"Result", @"Success" }
                                });
                                break;
                            }
                        }

                        EndRestore();
                        CommandManager.InvalidateRequerySuggested();
                    };
                    var restoreTargetPath = RestoreTarget.TargetPath;
                    if (RestoreTarget.IsCustomOption)
                    {
                        CommonOpenFileDialog m = new CommonOpenFileDialog
                        {
                            IsFolderPicker   = true,
                            EnsurePathExists = true,
                            Title            = M3L.GetString(M3L.string_selectNewRestoreDestination)
                        };
                        if (m.ShowDialog() == CommonFileDialogResult.Ok)
                        {
                            //Check empty
                            restoreTargetPath = m.FileName;
                            if (Directory.Exists(restoreTargetPath))
                            {
                                if (Directory.GetFiles(restoreTargetPath).Length > 0 || Directory.GetDirectories(restoreTargetPath).Length > 0)
                                {
                                    Log.Warning($@"The selected restore directory is not empty: {restoreTargetPath}");
                                    //Directory not empty
                                    if (!useNewMethod)
                                    {
                                        M3L.ShowDialog(window,
                                                       M3L.GetString(M3L
                                                                     .string_dialogDirectoryIsNotEmptyLocationToRestoreToMustBeEmpty),
                                                       M3L.GetString(M3L.string_cannotRestoreToThisLocation), MessageBoxButton.OK,
                                                       MessageBoxImage.Error);
                                        return;
                                    }
                                    else
                                    {
                                        // Warn user
                                        var shouldContinue = MessageBoxResult.Yes == M3L.ShowDialog(window,
                                                                                                    M3L.GetString(M3L.string_interp_directoryNotEmptyWillDeleteEverything, restoreTargetPath),
                                                                                                    M3L.GetString(M3L.string_directoryNotEmpty), MessageBoxButton.YesNo, MessageBoxImage.Warning);
                                        if (!shouldContinue)
                                        {
                                            return;
                                        }
                                        Log.Warning($@"The user is continuing to new-gen restore on existing directory anyways");
                                    }
                                }

                                //TODO: PREVENT RESTORING TO DOCUMENTS/BIOWARE
                            }

                            Analytics.TrackEvent(@"Chose to restore game to custom location", new Dictionary <string, string>()
                            {
                                { @"Game", Game.ToString() },
                                { @"New-gen", useNewMethod.ToString() }
                            });
                        }
                        else
                        {
                            return;
                        }
                    }

                    RefreshTargets = true;
                    TaskbarHelper.SetProgress(0);
                    TaskbarHelper.SetProgressState(TaskbarProgressBarState.Normal);
                    nbw.RunWorkerAsync(restoreTargetPath);
                }
            }