Exemplo n.º 1
0
        /// <summary>
        /// Downloads the latest version of this package. If a version is already in the local store, it will be deleted first.
        /// </summary>
        /// <param name="displayErrorMessage">Indicates whether to display error message boxes when an error occurs.</param>
        /// <returns>A task that completes when the latest version has been downloaded.</returns>
        /// <remarks>
        /// This method will invoke, from a worker thread, <see cref="BeforeDownload"/> before doing anything, and <see cref="AfterDownload"/>
        /// if the download successfully completed without exception. In every case, it will also invoke <see cref="UpdateVersionsFromStore"/>
        /// before completing.
        /// </remarks>
        protected Task Download(bool displayErrorMessage)
        {
            BeforeDownload();

            return(Task.Run(async() =>
            {
                IsProcessing = true;

                // Uninstall previous version first, if it exists
                if (LocalPackage != null)
                {
                    try
                    {
                        CurrentProcessStatus = null;
                        using (var progressReport = new ProgressReport(Store, ServerPackage))
                        {
                            progressReport.ProgressChanged += (action, progress) => { Dispatcher.InvokeAsync(() => { UpdateProgress(action, progress); }).Forget(); };
                            progressReport.UpdateProgress(ProgressAction.Delete, -1);
                            await Store.UninstallPackage(LocalPackage, progressReport);
                            CurrentProcessStatus = null;
                        }
                    }
                    catch (Exception e)
                    {
                        if (displayErrorMessage)
                        {
                            var message = $"{UninstallErrorMessage}{e.FormatSummary(true)}";
                            await ServiceProvider.Get <IDialogService>().MessageBox(message, MessageBoxButton.OK, MessageBoxImage.Error);
                            await UpdateVersionsFromStore();
                            IsProcessing = false;
                            return;
                        }

                        IsProcessing = false;
                        throw;
                    }
                }

                // Then download and install the latest version.
                bool downloadCompleted = false;
                try
                {
                    using (var progressReport = new ProgressReport(Store, ServerPackage))
                    {
                        progressReport.ProgressChanged += (action, progress) => { Dispatcher.InvokeAsync(() => { UpdateProgress(action, progress); }).Forget(); };
                        progressReport.UpdateProgress(ProgressAction.Install, -1);
                        MetricsHelper.NotifyDownloadStarting(ServerPackage.Id, ServerPackage.Version.ToString());
                        await Store.InstallPackage(ServerPackage.Id, ServerPackage.Version, progressReport);
                        downloadCompleted = true;
                        MetricsHelper.NotifyDownloadCompleted(ServerPackage.Id, ServerPackage.Version.ToString());
                    }

                    AfterDownload();
                }
                catch (Exception e)
                {
                    if (!downloadCompleted)
                    {
                        MetricsHelper.NotifyDownloadFailed(ServerPackage.Id, ServerPackage.Version.ToString());
                    }

                    // Rollback: try to delete the broken package (i.e. if it is installed with NuGet but had a failure during Install scripts)
                    try
                    {
                        var localPackage = Store.FindLocalPackage(ServerPackage.Id, ServerPackage.Version);
                        if (localPackage != null)
                        {
                            await Store.UninstallPackage(localPackage, null);
                        }
                    }
                    catch
                    {
                        // Note: quite a bad state: rollback (uninstall) failed
                        //       we don't display the message to not confuse the user even more with an intermediate uninstall error message before the install error message
                    }

                    if (displayErrorMessage)
                    {
                        var message = $"{InstallErrorMessage}{e.FormatSummary(true)}";
                        await ServiceProvider.Get <IDialogService>().MessageBox(message, MessageBoxButton.OK, MessageBoxImage.Error);
                        return;
                    }
                    throw;
                }
                finally
                {
                    await UpdateVersionsFromStore();
                    IsProcessing = false;
                }
            }));
        }