private void installFromckanToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog open_file_dialog = new OpenFileDialog { Filter = Resources.CKANFileFilter }; if (open_file_dialog.ShowDialog() == DialogResult.OK) { var path = open_file_dialog.FileName; CkanModule module; try { module = CkanModule.FromFile(path); } catch (Kraken kraken) { currentUser.RaiseError(kraken.InnerException == null ? kraken.Message : $"{kraken.Message}: {kraken.InnerException.Message}"); return; } catch (Exception ex) { currentUser.RaiseError(ex.Message); return; } // We'll need to make some registry changes to do this. RegistryManager registry_manager = RegistryManager.Instance(CurrentInstance); // Remove this version of the module in the registry, if it exists. registry_manager.registry.RemoveAvailable(module); // Sneakily add our version in... registry_manager.registry.AddAvailable(module); var changeset = new List <ModChange> { new ModChange( new GUIMod(module, registry_manager.registry, CurrentInstance.VersionCriteria()), GUIModChangeType.Install, null) }; menuStrip1.Enabled = false; RelationshipResolverOptions install_ops = RelationshipResolver.DefaultOpts(); install_ops.with_recommends = false; installWorker.RunWorkerAsync( new KeyValuePair <List <ModChange>, RelationshipResolverOptions>( changeset, install_ops)); changeSet = null; UpdateChangesDialog(null, installWorker); ShowWaitDialog(); } }
private void ConfirmChangesButton_Click(object sender, EventArgs e) { if (m_Changeset == null) { return; } menuStrip1.Enabled = false; RelationshipResolverOptions install_ops = RelationshipResolver.DefaultOpts(); install_ops.with_recommends = false; //Using the changeset passed in can cause issues with versions. // An example is Mechjeb for FAR at 25/06/2015 with a 1.0.2 install. // TODO Work out why this is. var user_change_set = mainModList.ComputeUserChangeSet().ToList(); m_InstallWorker.RunWorkerAsync( new KeyValuePair <List <KeyValuePair <GUIMod, GUIModChangeType> >, RelationshipResolverOptions>( user_change_set, install_ops)); m_Changeset = null; UpdateChangesDialog(null, m_InstallWorker); ShowWaitDialog(); }
/// <summary> /// Initiate the GUI installer flow for one specific module /// </summary> /// <param name="registry">Reference to the registry</param> /// <param name="module">Module to install</param> public async void InstallModuleDriver(IRegistryQuerier registry, CkanModule module) { RelationshipResolverOptions install_ops = RelationshipResolver.DefaultOpts(); install_ops.with_recommends = false; try { var initialChangeSet = new HashSet <ModChange>(); // Install the selected mod initialChangeSet.Add(new ModChange( new GUIMod(module, registry, CurrentInstance.VersionCriteria()), GUIModChangeType.Install, null )); InstalledModule installed = registry.InstalledModule(module.identifier); if (installed != null) { // Already installed, remove it first initialChangeSet.Add(new ModChange( new GUIMod(installed.Module, registry, CurrentInstance.VersionCriteria()), GUIModChangeType.Remove, null )); } List <ModChange> fullChangeSet = new List <ModChange>( await mainModList.ComputeChangeSetFromModList( registry, initialChangeSet, ModuleInstaller.GetInstance(CurrentInstance, Manager.Cache, GUI.user), CurrentInstance.VersionCriteria() ) ); if (fullChangeSet != null && fullChangeSet.Count > 0) { // Resolve the provides relationships in the dependencies installWorker.RunWorkerAsync( new KeyValuePair <List <ModChange>, RelationshipResolverOptions>( fullChangeSet, install_ops ) ); } } catch { // If we failed, do the clean-up normally done by PostInstallMods. HideWaitDialog(false); menuStrip1.Enabled = true; } finally { changeSet = null; } }
/// <summary> /// Initiate the GUI installer flow for one specific module /// </summary> /// <param name="registry">Reference to the registry</param> /// <param name="module">Module to install</param> public async void InstallModuleDriver(IRegistryQuerier registry, CkanModule module) { RelationshipResolverOptions install_ops = RelationshipResolver.DefaultOpts(); install_ops.with_recommends = false; try { // Resolve the provides relationships in the dependencies List <ModChange> fullChangeSet = new List <ModChange>( await mainModList.ComputeChangeSetFromModList( registry, new HashSet <ModChange>() { new ModChange( new GUIMod( module, registry, CurrentInstance.VersionCriteria() ), GUIModChangeType.Install, null ) }, ModuleInstaller.GetInstance(CurrentInstance, GUI.user), CurrentInstance.VersionCriteria() ) ); if (fullChangeSet != null && fullChangeSet.Count > 0) { installWorker.RunWorkerAsync( new KeyValuePair <List <ModChange>, RelationshipResolverOptions>( fullChangeSet, install_ops ) ); } } catch { // If we failed, do the clean-up normally done by PostInstallMods. HideWaitDialog(false); menuStrip1.Enabled = true; } finally { changeSet = null; } }
private void reinstallToolStripMenuItem_Click(object sender, EventArgs e) { GUIMod module = ModInfoTabControl.SelectedModule; if (module == null || !module.IsCKAN) { return; } YesNoDialog reinstallDialog = new YesNoDialog(); string confirmationText = $"Do you want to reinstall {module.Name}?"; if (reinstallDialog.ShowYesNoDialog(confirmationText) == DialogResult.No) { return; } IRegistryQuerier registry = RegistryManager.Instance(CurrentInstance).registry; KspVersionCriteria versCrit = CurrentInstance.VersionCriteria(); // Build the list of changes, first the mod to remove: List <ModChange> toReinstall = new List <ModChange>() { new ModChange(module, GUIModChangeType.Remove, null) }; // Then everything we need to re-install: HashSet <string> goners = registry.FindReverseDependencies( new List <string>() { module.Identifier } ); foreach (string id in goners) { toReinstall.Add(new ModChange( mainModList.full_list_of_mod_rows[id]?.Tag as GUIMod, GUIModChangeType.Install, null )); } // Hand off to centralized [un]installer code installWorker.RunWorkerAsync( new KeyValuePair <List <ModChange>, RelationshipResolverOptions>( toReinstall, RelationshipResolver.DefaultOpts() ) ); }
private void ConfirmChangesButton_Click(object sender, EventArgs e) { menuStrip1.Enabled = false; RelationshipResolverOptions install_ops = RelationshipResolver.DefaultOpts(); install_ops.with_recommends = false; m_InstallWorker.RunWorkerAsync( new KeyValuePair <List <KeyValuePair <CkanModule, GUIModChangeType> >, RelationshipResolverOptions>( m_Changeset, install_ops)); m_Changeset = null; UpdateChangesDialog(null, m_InstallWorker); ShowWaitDialog(); }
private void AuditRecommendations(IRegistryQuerier registry, KspVersionCriteria versionCriteria) { var recommended = new Dictionary <CkanModule, List <string> >(); var suggested = new Dictionary <CkanModule, List <string> >(); var toInstall = new HashSet <CkanModule>(); // Find recommendations and suggestions foreach (var mod in registry.InstalledModules.Select(im => im.Module)) { AddMod(mod.recommends, recommended, mod.identifier, registry, toInstall); AddMod(mod.suggests, suggested, mod.identifier, registry, toInstall); } if (!recommended.Any() && !suggested.Any()) { GUI.user.RaiseError("No recommendations or suggestions found."); return; } // Prompt user to choose installCanceled = false; ShowSelection(recommended, toInstall); ShowSelection(suggested, toInstall, true); tabController.HideTab("ChooseRecommendedModsTabPage"); // Install if (!installCanceled && toInstall.Any()) { installWorker.RunWorkerAsync( new KeyValuePair <List <ModChange>, RelationshipResolverOptions>( toInstall.Select(mod => new ModChange( new GUIMod(mod, registry, versionCriteria), GUIModChangeType.Install, null )).ToList(), RelationshipResolver.DefaultOpts() ) ); } }
private void ConfirmChangesButton_Click(object sender, EventArgs e) { if (changeSet == null) { return; } menuStrip1.Enabled = false; RetryCurrentActionButton.Visible = false; RelationshipResolverOptions install_ops = RelationshipResolver.DefaultOpts(); install_ops.with_recommends = false; //Using the changeset passed in can cause issues with versions. // An example is Mechjeb for FAR at 25/06/2015 with a 1.0.2 install. // TODO Work out why this is. installWorker.RunWorkerAsync( new KeyValuePair <List <ModChange>, RelationshipResolverOptions>( mainModList.ComputeUserChangeSet().ToList(), install_ops ) ); }
private async void installFromckanToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog open_file_dialog = new OpenFileDialog { Filter = Resources.CKANFileFilter }; if (open_file_dialog.ShowDialog() == DialogResult.OK) { var path = open_file_dialog.FileName; CkanModule module; try { module = CkanModule.FromFile(path); } catch (Kraken kraken) { currentUser.RaiseError(kraken.InnerException == null ? kraken.Message : $"{kraken.Message}: {kraken.InnerException.Message}"); return; } catch (Exception ex) { currentUser.RaiseError(ex.Message); return; } // We'll need to make some registry changes to do this. RegistryManager registry_manager = RegistryManager.Instance(CurrentInstance); // Remove this version of the module in the registry, if it exists. registry_manager.registry.RemoveAvailable(module); // Sneakily add our version in... registry_manager.registry.AddAvailable(module); menuStrip1.Enabled = false; RelationshipResolverOptions install_ops = RelationshipResolver.DefaultOpts(); install_ops.with_recommends = false; try { // Resolve the provides relationships in the dependencies List <ModChange> fullChangeSet = new List <ModChange>( await mainModList.ComputeChangeSetFromModList( registry_manager.registry, new HashSet <ModChange>() { new ModChange( new GUIMod( module, registry_manager.registry, CurrentInstance.VersionCriteria() ), GUIModChangeType.Install, null ) }, ModuleInstaller.GetInstance(CurrentInstance, GUI.user), CurrentInstance.VersionCriteria() ) ); if (fullChangeSet != null && fullChangeSet.Count > 0) { installWorker.RunWorkerAsync( new KeyValuePair <List <ModChange>, RelationshipResolverOptions>( fullChangeSet, install_ops ) ); ShowWaitDialog(); } } catch { // If we failed, do the clean-up normally done by PostInstallMods. HideWaitDialog(false); menuStrip1.Enabled = true; } finally { changeSet = null; } } }
// this functions computes a changeset from the user's choices in the GUI private List <KeyValuePair <CkanModule, GUIModChangeType> > ComputeChangeSetFromModList() // this probably needs to be refactored { var changeset = new HashSet <KeyValuePair <CkanModule, GUIModChangeType> >(); // these are the lists var modulesToInstall = new HashSet <string>(); var modulesToRemove = new HashSet <string>(); Registry registry = RegistryManager.Instance(KSPManager.CurrentInstance).registry; foreach (DataGridViewRow row in ModList.Rows) { var mod = (CkanModule)row.Tag; if (mod == null) { continue; } bool isInstalled = registry.IsInstalled(mod.identifier); var isInstalledCell = row.Cells[0] as DataGridViewCheckBoxCell; var isInstalledChecked = (bool)isInstalledCell.Value; if (!isInstalled && isInstalledChecked) { modulesToInstall.Add(mod.identifier); } else if (isInstalled && !isInstalledChecked) { modulesToRemove.Add(mod.identifier); } } RelationshipResolverOptions options = RelationshipResolver.DefaultOpts(); options.with_recommends = false; options.without_toomanyprovides_kraken = true; options.without_enforce_consistency = true; RelationshipResolver resolver = null; try { resolver = new RelationshipResolver(modulesToInstall.ToList(), options, registry); } catch (Exception e) { return(null); } foreach (CkanModule mod in resolver.ModList()) { changeset.Add(new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Install)); } ModuleInstaller installer = ModuleInstaller.Instance; foreach (string moduleName in modulesToRemove) { var reverseDependencies = installer.FindReverseDependencies(moduleName); foreach (string reverseDependency in reverseDependencies) { CkanModule mod = registry.LatestAvailable(reverseDependency); changeset.Add(new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Remove)); } } foreach (DataGridViewRow row in ModList.Rows) { var mod = (CkanModule)row.Tag; if (mod == null) { continue; } bool isInstalled = registry.IsInstalled(mod.identifier); var isInstalledCell = row.Cells[0] as DataGridViewCheckBoxCell; var isInstalledChecked = (bool)isInstalledCell.Value; DataGridViewCell shouldBeUpdatedCell = row.Cells[1]; bool shouldBeUpdated = false; if (shouldBeUpdatedCell is DataGridViewCheckBoxCell && shouldBeUpdatedCell.Value != null) { shouldBeUpdated = (bool)shouldBeUpdatedCell.Value; } if (isInstalled && !isInstalledChecked) { changeset.Add(new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Remove)); } else if (isInstalled && isInstalledChecked && mod.version.IsGreaterThan(registry.InstalledVersion(mod.identifier)) && shouldBeUpdated) { changeset.Add(new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Update)); } } return(changeset.ToList()); }
/// <summary> /// This function returns a changeset based on the selections of the user. /// Currently returns null if a conflict is detected. /// </summary> /// <param name="registry"></param> /// <param name="current_instance"></param> public List <KeyValuePair <CkanModule, GUIModChangeType> > ComputeChangeSetFromModList(Registry registry, KSP current_instance) { var changeset = new HashSet <KeyValuePair <CkanModule, GUIModChangeType> >(); var modulesToInstall = new HashSet <string>(); var modulesToRemove = new HashSet <string>(); foreach (var mod in Modules.Where(mod => mod.IsInstallable())) { if (mod.IsInstalled) { if (!mod.IsInstallChecked) { modulesToRemove.Add(mod.Identifier); changeset.Add(new KeyValuePair <CkanModule, GUIModChangeType>(mod.ToCkanModule(), GUIModChangeType.Remove)); } else if (mod.IsInstallChecked && mod.HasUpdate && mod.IsUpgradeChecked) { changeset.Add(new KeyValuePair <CkanModule, GUIModChangeType>(mod.ToCkanModule(), GUIModChangeType.Update)); } } else if (mod.IsInstallChecked) { modulesToInstall.Add(mod.Identifier); } } RelationshipResolverOptions options = RelationshipResolver.DefaultOpts(); options.with_recommends = false; options.without_toomanyprovides_kraken = true; options.without_enforce_consistency = true; RelationshipResolver resolver; try { resolver = new RelationshipResolver(modulesToInstall.ToList(), options, registry); } catch (Exception) { //TODO FIX this so the UI reacts. return(null); } changeset.UnionWith( resolver.ModList() .Select(mod => new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Install))); ModuleInstaller installer = ModuleInstaller.GetInstance(current_instance, GUI.user); foreach (var reverseDependencies in modulesToRemove.Select(mod => installer.FindReverseDependencies(mod))) { //TODO This would be a good place to have a event that alters the row's graphics to show it will be removed var modules = reverseDependencies.Select(rDep => registry.LatestAvailable(rDep)); changeset.UnionWith( modules.Select(mod => new KeyValuePair <CkanModule, GUIModChangeType>(mod, GUIModChangeType.Remove))); } return(changeset.ToList()); }