Пример #1
0
        private void PostUpdateRepo(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                switch (e.Error)
                {
                case ReinstallModuleKraken rmk:
                    // Re-enable the UI for the install flow
                    Util.Invoke(this, SwitchEnabledState);
                    // Hand off to the full installer flow
                    installWorker.RunWorkerAsync(
                        new KeyValuePair <List <ModChange>, RelationshipResolverOptions>(
                            rmk.Modules
                            .Select(m => new ModChange(m, GUIModChangeType.Update, null))
                            .ToList(),
                            RelationshipResolver.DependsOnlyOpts()
                            )
                        );
                    // Don't mess with the UI, let the install flow control it
                    return;
                }
            }

            var resultPair = e.Result as KeyValuePair <RepoUpdateResult, Dictionary <string, bool> >?;
            RepoUpdateResult?         result     = resultPair?.Key;
            Dictionary <string, bool> oldModules = resultPair?.Value;

            switch (result)
            {
            case RepoUpdateResult.NoChanges:
                AddStatusMessage(Properties.Resources.MainRepoUpToDate);
                HideWaitDialog(true);
                // Load rows if grid empty, otherwise keep current
                if (ManageMods.ModGrid.Rows.Count < 1)
                {
                    ManageMods.UpdateModsList();
                }
                break;

            case RepoUpdateResult.Failed:
                AddStatusMessage(Properties.Resources.MainRepoFailed);
                HideWaitDialog(false);
                break;

            case RepoUpdateResult.Updated:
            default:
                ManageMods.UpdateModsList(oldModules);
                AddStatusMessage(Properties.Resources.MainRepoSuccess);
                ShowRefreshQuestion();
                HideWaitDialog(true);
                UpgradeNotification();
                break;
            }

            tabController.HideTab("WaitTabPage");
            Util.Invoke(this, SwitchEnabledState);
            Util.Invoke(this, RecreateDialogs);
            Util.Invoke(this, ManageMods.ModGrid.Select);
        }
Пример #2
0
 private void Changeset_OnCancelChanges(bool reset)
 {
     if (reset)
     {
         ManageMods.ClearChangeSet();
         UpdateChangesDialog(null);
     }
     tabController.ShowTab("ManageModsTabPage");
 }
Пример #3
0
        private void CompatibleGameVersionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CompatibleGameVersionsDialog dialog = new CompatibleGameVersionsDialog(
                Instance.manager.CurrentInstance,
                !actuallyVisible
                );

            if (dialog.ShowDialog() != DialogResult.Cancel)
            {
                // This takes a while, so don't do it if they cancel out
                ManageMods.UpdateModsList();
            }
        }
Пример #4
0
        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            // Only close the window, when the user has access to the "Exit" of the menu.
            if (!menuStrip1.Enabled)
            {
                e.Cancel = true;
                return;
            }

            if (!ManageMods.AllowClose())
            {
                e.Cancel = true;
                return;
            }

            // Copy window location to app settings
            configuration.WindowLoc = WindowState == FormWindowState.Normal ? Location : RestoreBounds.Location;

            // Copy window size to app settings if not maximized
            configuration.WindowSize = WindowState == FormWindowState.Normal ? Size : RestoreBounds.Size;

            //copy window maximized state to app settings
            configuration.IsWindowMaximised = WindowState == FormWindowState.Maximized;

            // Copy panel position to app settings
            configuration.PanelPosition = splitContainer1.SplitterDistance;

            // Copy metadata panel split height to app settings
            configuration.ModInfoPosition = ModInfo.ModMetaSplitPosition;

            // Save the active filter
            configuration.ActiveFilter      = (int)ManageMods.mainModList.ModFilter;
            configuration.CustomLabelFilter = ManageMods.mainModList.CustomLabelFilter?.Name;

            // Save settings.
            configuration.Save();

            if (needRegistrySave)
            {
                using (var transaction = CkanTransaction.CreateTransactionScope())
                {
                    // Save registry
                    RegistryManager.Instance(CurrentInstance).Save(false);
                    transaction.Complete();
                }
            }

            base.OnFormClosing(e);
        }
Пример #5
0
        private void minimizeNotifyIcon_BalloonTipClicked(object sender, EventArgs e)
        {
            // Unminimize
            OpenWindow();

            // Check all the upgrade checkboxes
            ManageMods.MarkAllUpdates();

            // Install
            installWorker.RunWorkerAsync(
                new KeyValuePair <List <ModChange>, RelationshipResolverOptions>(
                    ManageMods.mainModList.ComputeUserChangeSet(RegistryManager.Instance(Main.Instance.CurrentInstance).registry).ToList(),
                    RelationshipResolver.DependsOnlyOpts()
                    )
                );
        }
Пример #6
0
        private void ImportModules()
        {
            // Prompt the user to select one or more ZIP files
            OpenFileDialog dlg = new OpenFileDialog()
            {
                Title            = Properties.Resources.MainImportTitle,
                AddExtension     = true,
                CheckFileExists  = true,
                CheckPathExists  = true,
                InitialDirectory = FindDownloadsPath(CurrentInstance),
                DefaultExt       = "zip",
                Filter           = Properties.Resources.MainImportFilter,
                Multiselect      = true
            };

            if (dlg.ShowDialog() == DialogResult.OK &&
                dlg.FileNames.Length > 0)
            {
                // Show WaitTabPage (status page) and lock it.
                tabController.RenameTab("WaitTabPage", Properties.Resources.MainImportWaitTitle);
                tabController.ShowTab("WaitTabPage");
                tabController.SetTabLock(true);

                try
                {
                    new ModuleInstaller(CurrentInstance, Manager.Cache, currentUser).ImportFiles(
                        GetFiles(dlg.FileNames),
                        currentUser,
                        (CkanModule mod) => ManageMods.MarkModForInstall(mod.identifier, false),
                        RegistryManager.Instance(CurrentInstance).registry
                        );
                }
                finally
                {
                    // Put GUI back the way we found it
                    tabController.SetTabLock(false);
                    tabController.HideTab("WaitTabPage");
                }
            }
        }
Пример #7
0
        private void PostUpdateRepo(object sender, RunWorkerCompletedEventArgs e)
        {
            var resultPair = e.Result as KeyValuePair <RepoUpdateResult, Dictionary <string, bool> >?;
            RepoUpdateResult?         result     = resultPair?.Key;
            Dictionary <string, bool> oldModules = resultPair?.Value;

            switch (result)
            {
            case RepoUpdateResult.NoChanges:
                AddStatusMessage(Properties.Resources.MainRepoUpToDate);
                HideWaitDialog(true);
                // Load rows if grid empty, otherwise keep current
                if (ManageMods.ModGrid.Rows.Count < 1)
                {
                    ManageMods.UpdateModsList();
                }
                break;

            case RepoUpdateResult.Failed:
                AddStatusMessage(Properties.Resources.MainRepoFailed);
                HideWaitDialog(false);
                break;

            case RepoUpdateResult.Updated:
            default:
                ManageMods.UpdateModsList(oldModules);
                AddStatusMessage(Properties.Resources.MainRepoSuccess);
                ShowRefreshQuestion();
                HideWaitDialog(true);
                UpgradeNotification();
                break;
            }

            tabController.HideTab("WaitTabPage");
            Util.Invoke(this, SwitchEnabledState);
            Util.Invoke(this, RecreateDialogs);
            Util.Invoke(this, ManageMods.ModGrid.Select);
        }
Пример #8
0
        private void SetupDefaultSearch()
        {
            var def = configuration.DefaultSearches;

            if (def == null || def.Count < 1)
            {
                // Fall back to old setting
                ManageMods.Filter(ModList.FilterToSavedSearch(
                                      (GUIModFilter)configuration.ActiveFilter,
                                      ManageMods.mainModList.ModuleTags.Tags.GetOrDefault(configuration.TagFilter),
                                      ManageMods.mainModList.ModuleLabels.LabelsFor(CurrentInstance.Name)
                                      .FirstOrDefault(l => l.Name == configuration.CustomLabelFilter)
                                      ));
                // Clear the old filter so it doesn't get pulled forward again
                configuration.ActiveFilter = (int)GUIModFilter.All;
            }
            else
            {
                var labels   = ManageMods.mainModList.ModuleLabels.LabelsFor(CurrentInstance.Name).ToList();
                var searches = def.Select(s => ModSearch.Parse(s, labels)).ToList();
                ManageMods.SetSearches(searches);
            }
        }
Пример #9
0
        private void PostInstallMods(object sender, RunWorkerCompletedEventArgs e)
        {
            tabController.SetTabLock(false);

            if (e.Error != null)
            {
                switch (e.Error)
                {
                case DependencyNotSatisfiedKraken exc:
                    currentUser.RaiseMessage(Properties.Resources.MainInstallDepNotSatisfied, exc.parent, exc.module);
                    break;

                case ModuleNotFoundKraken exc:
                    currentUser.RaiseMessage(Properties.Resources.MainInstallNotFound, exc.module);
                    break;

                case BadMetadataKraken exc:
                    currentUser.RaiseMessage(Properties.Resources.MainInstallBadMetadata, exc.module, exc.Message);
                    break;

                case FileExistsKraken exc:
                    if (exc.owningModule != null)
                    {
                        currentUser.RaiseMessage(
                            Properties.Resources.MainInstallFileExists,
                            exc.filename, exc.installingModule, exc.owningModule,
                            Meta.GetVersion()
                            );
                    }
                    else
                    {
                        currentUser.RaiseMessage(
                            Properties.Resources.MainInstallUnownedFileExists,
                            exc.installingModule, exc.filename
                            );
                    }
                    currentUser.RaiseMessage(Properties.Resources.MainInstallGameDataReverted);
                    break;

                case InconsistentKraken exc:
                    currentUser.RaiseMessage(exc.InconsistenciesPretty);
                    break;

                case CancelledActionKraken exc:
                    currentUser.RaiseMessage(exc.Message);
                    installCanceled = true;
                    break;

                case MissingCertificateKraken exc:
                    currentUser.RaiseMessage(exc.ToString());
                    break;

                case DownloadThrottledKraken exc:
                    string msg = exc.ToString();
                    currentUser.RaiseMessage(msg);
                    if (YesNoDialog(string.Format(Properties.Resources.MainInstallOpenSettingsPrompt, msg),
                                    Properties.Resources.MainInstallOpenSettings,
                                    Properties.Resources.MainInstallNo))
                    {
                        // Launch the URL describing this host's throttling practices, if any
                        if (exc.infoUrl != null)
                        {
                            Utilities.ProcessStartURL(exc.infoUrl.ToString());
                        }
                        // Now pretend they clicked the menu option for the settings
                        Enabled = false;
                        new SettingsDialog(currentUser).ShowDialog();
                        Enabled = true;
                    }
                    break;

                case ModuleDownloadErrorsKraken exc:
                    currentUser.RaiseMessage(exc.ToString());
                    currentUser.RaiseError(exc.ToString());
                    break;

                case DirectoryNotFoundKraken exc:
                    currentUser.RaiseMessage("\r\n{0}", exc.Message);
                    break;

                case ModuleIsDLCKraken exc:
                    string dlcMsg = string.Format(Properties.Resources.MainInstallCantInstallDLC, exc.module.name);
                    currentUser.RaiseMessage(dlcMsg);
                    currentUser.RaiseError(dlcMsg);
                    break;
                }

                FailWaitDialog(
                    Properties.Resources.MainInstallErrorInstalling,
                    Properties.Resources.MainInstallKnownError,
                    Properties.Resources.MainInstallFailed,
                    false
                    );
            }
            else
            {
                // The Result property throws if InstallMods threw (!!!)
                KeyValuePair <bool, ModChanges> result = (KeyValuePair <bool, ModChanges>)e.Result;
                if (!installCanceled)
                {
                    // Rebuilds the list of GUIMods
                    ManageMods.UpdateModsList(null);

                    if (modChangedCallback != null)
                    {
                        foreach (var mod in result.Value)
                        {
                            modChangedCallback(mod.Mod, mod.ChangeType);
                        }
                    }

                    // install successful
                    AddStatusMessage(Properties.Resources.MainInstallSuccess);
                    HideWaitDialog(true);
                }
                else
                {
                    // User cancelled the installation
                    if (result.Key)
                    {
                        FailWaitDialog(
                            Properties.Resources.MainInstallCancelTooLate,
                            Properties.Resources.MainInstallCancelAfterInstall,
                            Properties.Resources.MainInstallProcessComplete,
                            true
                            );
                    }
                    else
                    {
                        FailWaitDialog(
                            Properties.Resources.MainInstallProcessCanceled,
                            Properties.Resources.MainInstallCanceledManually,
                            Properties.Resources.MainInstallInstallCanceled,
                            false
                            );
                    }
                }
            }

            Util.Invoke(this, () => Enabled = true);
            Util.Invoke(menuStrip1, () => menuStrip1.Enabled = true);
        }
Пример #10
0
        /// <summary>
        /// React to switching to a new game instance
        /// </summary>
        /// <param name="allowRepoUpdate">true if a repo update is allowed if needed (e.g. on initial load), false otherwise</param>
        private void CurrentInstanceUpdated(bool allowRepoUpdate)
        {
            CurrentInstance.Scan();
            Util.Invoke(this, () =>
            {
                Text = $"CKAN {Meta.GetVersion()} - {CurrentInstance.game.ShortName} {CurrentInstance.Version()}    --    {CurrentInstance.GameDir().Replace('/', Path.DirectorySeparatorChar)}";
                StatusInstanceLabel.Text = string.Format(
                    Properties.Resources.StatusInstanceLabelText,
                    CurrentInstance.Name,
                    CurrentInstance.game.ShortName,
                    CurrentInstance.Version()?.ToString()
                    );
            });

            configuration = GUIConfiguration.LoadOrCreateConfiguration(
                Path.Combine(CurrentInstance.CkanDir(), "GUIConfig.xml")
                );

            if (CurrentInstance.CompatibleVersionsAreFromDifferentGameVersion)
            {
                new CompatibleGameVersionsDialog(CurrentInstance, !actuallyVisible)
                .ShowDialog();
            }

            (RegistryManager.Instance(CurrentInstance).registry as Registry)
            ?.BuildTagIndex(ManageMods.mainModList.ModuleTags);

            bool repoUpdateNeeded = configuration.RefreshOnStartup ||
                                    !RegistryManager.Instance(CurrentInstance).registry.HasAnyAvailable();

            if (allowRepoUpdate)
            {
                // If not allowing, don't do anything
                if (repoUpdateNeeded)
                {
                    // Update the filters after UpdateRepo() completed.
                    // Since this happens with a backgroundworker, Filter() is added as callback for RunWorkerCompleted.
                    // Remove it again after it ran, else it stays there and is added again and again.
                    void filterUpdate(object sender, RunWorkerCompletedEventArgs e)
                    {
                        ManageMods.Filter(
                            (GUIModFilter)configuration.ActiveFilter,
                            ManageMods.mainModList.ModuleTags.Tags.GetOrDefault(configuration.TagFilter),
                            ManageMods.mainModList.ModuleLabels.LabelsFor(CurrentInstance.Name)
                            .FirstOrDefault(l => l.Name == configuration.CustomLabelFilter)
                            );
                        m_UpdateRepoWorker.RunWorkerCompleted -= filterUpdate;
                    }

                    m_UpdateRepoWorker.RunWorkerCompleted += filterUpdate;

                    ManageMods.ModGrid.Rows.Clear();
                    UpdateRepo();
                }
                else
                {
                    ManageMods.UpdateModsList();
                    ManageMods.Filter(
                        (GUIModFilter)configuration.ActiveFilter,
                        ManageMods.mainModList.ModuleTags.Tags.GetOrDefault(configuration.TagFilter),
                        ManageMods.mainModList.ModuleLabels.LabelsFor(CurrentInstance.Name)
                        .FirstOrDefault(l => l.Name == configuration.CustomLabelFilter)
                        );
                }
            }
            ManageMods.InstanceUpdated(CurrentInstance);
        }
Пример #11
0
        protected override void OnLoad(EventArgs e)
        {
            SetStartPosition();
            Size        = configuration.WindowSize;
            WindowState = configuration.IsWindowMaximised ? FormWindowState.Maximized : FormWindowState.Normal;

            if (!configuration.CheckForUpdatesOnLaunchNoNag && AutoUpdate.CanUpdate)
            {
                log.Debug("Asking user if they wish for auto-updates");
                if (new AskUserForAutoUpdatesDialog().ShowDialog() == DialogResult.OK)
                {
                    configuration.CheckForUpdatesOnLaunch = true;
                }

                configuration.CheckForUpdatesOnLaunchNoNag = true;
                configuration.Save();
            }

            bool autoUpdating = CheckForCKANUpdate();

            CheckTrayState();
            InitRefreshTimer();

            m_UpdateRepoWorker = new BackgroundWorker {
                WorkerReportsProgress = false, WorkerSupportsCancellation = true
            };

            m_UpdateRepoWorker.RunWorkerCompleted += PostUpdateRepo;
            m_UpdateRepoWorker.DoWork             += UpdateRepo;

            installWorker = new BackgroundWorker {
                WorkerReportsProgress = true, WorkerSupportsCancellation = true
            };
            installWorker.RunWorkerCompleted += PostInstallMods;
            installWorker.DoWork             += InstallMods;

            URLHandlers.RegisterURLHandler(configuration, currentUser);

            CurrentInstanceUpdated(!autoUpdating);

            if (commandLineArgs.Length >= 2)
            {
                var identifier = commandLineArgs[1];
                if (identifier.StartsWith("//"))
                {
                    identifier = identifier.Substring(2);
                }
                else if (identifier.StartsWith("ckan://"))
                {
                    identifier = identifier.Substring(7);
                }

                if (identifier.EndsWith("/"))
                {
                    identifier = identifier.Substring(0, identifier.Length - 1);
                }

                log.Debug("Attempting to select mod from startup parameters");
                ManageMods.FocusMod(identifier, true, true);
                ManageMods.ModGrid.Refresh();
                log.Debug("Failed to select mod from startup parameters");
            }

            var pluginsPath = Path.Combine(CurrentInstance.CkanDir(), "Plugins");

            if (!Directory.Exists(pluginsPath))
            {
                Directory.CreateDirectory(pluginsPath);
            }

            pluginController = new PluginController(pluginsPath);

            CurrentInstance.game.RebuildSubdirectories(CurrentInstance);

            log.Info("GUI started");
            base.OnLoad(e);
        }
Пример #12
0
        /// <summary>
        /// React to switching to a new game instance
        /// </summary>
        /// <param name="allowRepoUpdate">true if a repo update is allowed if needed (e.g. on initial load), false otherwise</param>
        private void CurrentInstanceUpdated(bool allowRepoUpdate)
        {
            log.Debug("Current instance updated, scanning");
            CurrentInstance.Scan();
            Util.Invoke(this, () =>
            {
                Text = $"CKAN {Meta.GetVersion()} - {CurrentInstance.game.ShortName} {CurrentInstance.Version()}    --    {CurrentInstance.GameDir().Replace('/', Path.DirectorySeparatorChar)}";
                StatusInstanceLabel.Text = string.Format(
                    Properties.Resources.StatusInstanceLabelText,
                    CurrentInstance.Name,
                    CurrentInstance.game.ShortName,
                    CurrentInstance.Version()?.ToString()
                    );
            });

            if (CurrentInstance.CompatibleVersionsAreFromDifferentGameVersion)
            {
                new CompatibleGameVersionsDialog(CurrentInstance, !actuallyVisible)
                .ShowDialog();
            }

            // This will throw RegistryInUseKraken if locked by another process
            var regMgr   = RegistryManager.Instance(CurrentInstance);
            var registry = regMgr.registry;

            if (!string.IsNullOrEmpty(regMgr.previousCorruptedMessage) &&
                !string.IsNullOrEmpty(regMgr.previousCorruptedPath))
            {
                errorDialog.ShowErrorDialog(Properties.Resources.MainCorruptedRegistry,
                                            regMgr.previousCorruptedPath, regMgr.previousCorruptedMessage,
                                            Path.Combine(Path.GetDirectoryName(regMgr.previousCorruptedPath) ?? "", regMgr.LatestInstalledExportFilename()));
                regMgr.previousCorruptedMessage = null;
                regMgr.previousCorruptedPath    = null;
            }
            registry.BuildTagIndex(ManageMods.mainModList.ModuleTags);

            configuration = GUIConfiguration.LoadOrCreateConfiguration(
                Path.Combine(CurrentInstance.CkanDir(), "GUIConfig.xml"));

            bool repoUpdateNeeded = configuration.RefreshOnStartup ||
                                    !RegistryManager.Instance(CurrentInstance).registry.HasAnyAvailable();

            if (allowRepoUpdate)
            {
                // If not allowing, don't do anything
                if (repoUpdateNeeded)
                {
                    // Update the filters after UpdateRepo() completed.
                    // Since this happens with a backgroundworker, Filter() is added as callback for RunWorkerCompleted.
                    // Remove it again after it ran, else it stays there and is added again and again.
                    void filterUpdate(object sender, RunWorkerCompletedEventArgs e)
                    {
                        SetupDefaultSearch();
                        m_UpdateRepoWorker.RunWorkerCompleted -= filterUpdate;
                    }

                    m_UpdateRepoWorker.RunWorkerCompleted += filterUpdate;

                    ManageMods.ModGrid.Rows.Clear();
                    UpdateRepo();
                }
                else
                {
                    SetupDefaultSearch();
                    ManageMods.UpdateModsList();
                }
            }
            ManageMods.InstanceUpdated(CurrentInstance);
        }
Пример #13
0
 private void updatesToolStripMenuItem_Click(object sender, EventArgs e)
 {
     OpenWindow();
     ManageMods.MarkAllUpdates();
 }
Пример #14
0
        protected override void OnLoad(EventArgs e)
        {
            SetStartPosition();
            Size        = configuration.WindowSize;
            WindowState = configuration.IsWindowMaximised ? FormWindowState.Maximized : FormWindowState.Normal;

            if (!configuration.CheckForUpdatesOnLaunchNoNag && AutoUpdate.CanUpdate)
            {
                log.Debug("Asking user if they wish for auto-updates");
                if (new AskUserForAutoUpdatesDialog().ShowDialog() == DialogResult.OK)
                {
                    configuration.CheckForUpdatesOnLaunch = true;
                }

                configuration.CheckForUpdatesOnLaunchNoNag = true;
                configuration.Save();
            }

            bool autoUpdating = false;

            if (configuration.CheckForUpdatesOnLaunch && AutoUpdate.CanUpdate)
            {
                try
                {
                    log.Info("Making auto-update call");
                    AutoUpdate.Instance.FetchLatestReleaseInfo();
                    var latest_version  = AutoUpdate.Instance.latestUpdate.Version;
                    var current_version = new ModuleVersion(Meta.GetVersion());

                    if (AutoUpdate.Instance.IsFetched() && latest_version.IsGreaterThan(current_version))
                    {
                        log.Debug("Found higher ckan version");
                        var release_notes = AutoUpdate.Instance.latestUpdate.ReleaseNotes;
                        var dialog        = new NewUpdateDialog(latest_version.ToString(), release_notes);
                        if (dialog.ShowDialog() == DialogResult.OK)
                        {
                            UpdateCKAN();
                            autoUpdating = true;
                        }
                    }
                }
                catch (Exception exception)
                {
                    currentUser.RaiseError(Properties.Resources.MainAutoUpdateFailed, exception.Message);
                    log.Error("Error in auto-update", exception);
                }
            }

            CheckTrayState();
            InitRefreshTimer();

            m_UpdateRepoWorker = new BackgroundWorker {
                WorkerReportsProgress = false, WorkerSupportsCancellation = true
            };

            m_UpdateRepoWorker.RunWorkerCompleted += PostUpdateRepo;
            m_UpdateRepoWorker.DoWork             += UpdateRepo;

            installWorker = new BackgroundWorker {
                WorkerReportsProgress = true, WorkerSupportsCancellation = true
            };
            installWorker.RunWorkerCompleted += PostInstallMods;
            installWorker.DoWork             += InstallMods;

            URLHandlers.RegisterURLHandler(configuration, currentUser);

            CurrentInstanceUpdated(!autoUpdating);

            if (commandLineArgs.Length >= 2)
            {
                var identifier = commandLineArgs[1];
                if (identifier.StartsWith("//"))
                {
                    identifier = identifier.Substring(2);
                }
                else if (identifier.StartsWith("ckan://"))
                {
                    identifier = identifier.Substring(7);
                }

                if (identifier.EndsWith("/"))
                {
                    identifier = identifier.Substring(0, identifier.Length - 1);
                }

                log.Debug("Attempting to select mod from startup parameters");
                ManageMods.FocusMod(identifier, true, true);
                ManageMods.ModGrid.Refresh();
                log.Debug("Failed to select mod from startup parameters");
            }

            var pluginsPath = Path.Combine(CurrentInstance.CkanDir(), "Plugins");

            if (!Directory.Exists(pluginsPath))
            {
                Directory.CreateDirectory(pluginsPath);
            }

            pluginController = new PluginController(pluginsPath);

            CurrentInstance.RebuildKSPSubDir();

            log.Info("GUI started");
            base.OnLoad(e);
        }