Пример #1
0
        private void InstallMods(object sender, DoWorkEventArgs e) // this probably needs to be refactored
        {
            installCanceled = false;

            ClearLog();

            var opts =
                (KeyValuePair <ModChanges, RelationshipResolverOptions>)e.Argument;

            IRegistryQuerier registry  = RegistryManager.Instance(manager.CurrentInstance).registry;
            ModuleInstaller  installer = ModuleInstaller.GetInstance(CurrentInstance, GUI.user);

            // setup progress callback

            toInstall = new HashSet <string>();
            var toUninstall = new HashSet <string>();
            var toUpgrade   = new HashSet <string>();

            // First compose sets of what the user wants installed, upgraded, and removed.
            foreach (ModChange change in opts.Key)
            {
                switch (change.ChangeType)
                {
                case GUIModChangeType.Remove:
                    toUninstall.Add(change.Mod.Identifier);
                    break;

                case GUIModChangeType.Update:
                    toUpgrade.Add(change.Mod.Identifier);
                    break;

                case GUIModChangeType.Install:
                    toInstall.Add(change.Mod.Identifier);
                    break;
                }
            }

            // Now work on satisifying dependencies.

            var recommended = new Dictionary <string, List <string> >();
            var suggested   = new Dictionary <string, List <string> >();

            foreach (var change in opts.Key)
            {
                if (change.ChangeType == GUIModChangeType.Install)
                {
                    AddMod(change.Mod.ToModule().recommends, recommended, change.Mod.Identifier, registry);
                    AddMod(change.Mod.ToModule().suggests, suggested, change.Mod.Identifier, registry);
                }
            }

            ShowSelection(recommended);
            ShowSelection(suggested, true);

            tabController.HideTab("ChooseRecommendedModsTabPage");

            if (installCanceled)
            {
                tabController.HideTab("WaitTabPage");
                tabController.ShowTab("ManageModsTabPage");
                e.Result = new KeyValuePair <bool, ModChanges>(false, opts.Key);
                return;
            }

            // Now let's make all our changes.

            tabController.RenameTab("WaitTabPage", "Status log");
            tabController.ShowTab("WaitTabPage");
            tabController.SetTabLock(true);


            var downloader = new NetAsyncModulesDownloader(GUI.user);

            cancelCallback = () =>
            {
                downloader.CancelDownload();
                installCanceled = true;
            };

            GUI.user.RaiseMessage("About to install...\r\n");

            // FIXME: here we should heat up the cache with any mods we're going to install, because
            // when this transaction types out it f***s up everything else.
            var resolvedMods = installer.ResolveModules(toInstall, opts.Value);

            foreach (var module in resolvedMods.CachedModules)
            {
                GUI.user.RaiseMessage(" * {0} {1}(cached)", module.name, module.version);
            }

            foreach (var module in resolvedMods.UncachedModules)
            {
                GUI.user.RaiseMessage(" * {0} {1}", module.name, module.version);
            }

            if (!GUI.user.RaiseYesNoDialog("\r\nContinue?"))
            {
                throw new CancelledActionKraken("User declined install list");
            }

            GUI.user.RaiseMessage(String.Empty); // Just to look tidy.

            installer.EnsureCache(resolvedMods.UncachedModules);

            //Transaction is needed here to revert changes when an installation is cancelled
            //TODO: Cancellation should be handelt in the ModuleInstaller
            using (var transaction = CkanTransaction.CreateTransactionScope())
            {
                //Set the result to false/failed in case we return
                e.Result = new KeyValuePair <bool, ModChanges>(false, opts.Key);
                SetDescription("Uninstalling selected mods");
                if (!WasSuccessful(() => installer.UninstallList(toUninstall)))
                {
                    return;
                }
                if (installCanceled)
                {
                    return;
                }

                SetDescription("Updating selected mods");
                if (!WasSuccessful(() => installer.Upgrade(toUpgrade, downloader)))
                {
                    return;
                }
                if (installCanceled)
                {
                    return;
                }

                // TODO: We should be able to resolve all our provisioning conflicts
                // before we start installing anything. CKAN.SanityChecker can be used to
                // pre-check if our changes are going to be consistent.

                bool resolvedAllProvidedMods = false;

                while (!resolvedAllProvidedMods)
                {
                    if (installCanceled)
                    {
                        e.Result = new KeyValuePair <bool, ModChanges>(false, opts.Key);
                        return;
                    }
                    var ret = InstallList(resolvedMods, opts.Value);
                    if (!ret)
                    {
                        // install failed for some reason, error message is already displayed to the user
                        e.Result = new KeyValuePair <bool, ModChanges>(false, opts.Key);
                        return;
                    }
                    resolvedAllProvidedMods = true;
                }

                if (!installCanceled)
                {
                    transaction.Complete();
                }
            }

            e.Result = new KeyValuePair <bool, ModChanges>(!installCanceled, opts.Key);
        }