From f4491ee8f2f21263322778a9f1b61000a00b2b90 Mon Sep 17 00:00:00 2001 From: pointfeev Date: Fri, 6 Aug 2021 21:29:43 -0500 Subject: [PATCH] Update 1.0.5 - Fixed unhandled exception when Paradox Launcher is not installed. - Added better exception handling and file backups during installation. - Added an explanation for when no CreamAPI-applicable programs or games are found. - Increased the minimum size of the installation window. - Added program/game reselection from the installation window. - Added error dialogs for when selected programs are currently running. - Multiple other aesthetic changes. --- CreamInstaller/CreamInstaller.csproj | 2 +- CreamInstaller/InstallForm.Designer.cs | 30 ++- CreamInstaller/InstallForm.cs | 252 +++++++++++++++++-------- CreamInstaller/MainForm.cs | 2 +- CreamInstaller/Program.cs | 2 + CreamInstaller/ProgramSelection.cs | 14 ++ CreamInstaller/SelectForm.Designer.cs | 15 ++ CreamInstaller/SelectForm.cs | 68 +++++-- 8 files changed, 282 insertions(+), 103 deletions(-) diff --git a/CreamInstaller/CreamInstaller.csproj b/CreamInstaller/CreamInstaller.csproj index 2f3db1a..1888d46 100644 --- a/CreamInstaller/CreamInstaller.csproj +++ b/CreamInstaller/CreamInstaller.csproj @@ -6,7 +6,7 @@ true ini.ico true - 1.0.4 + 1.0.5 ini.ico Automatically downloads and installs CreamAPI files for programs/games. diff --git a/CreamInstaller/InstallForm.Designer.cs b/CreamInstaller/InstallForm.Designer.cs index b62e61e..28f1de0 100644 --- a/CreamInstaller/InstallForm.Designer.cs +++ b/CreamInstaller/InstallForm.Designer.cs @@ -36,6 +36,7 @@ namespace CreamInstaller this.retryButton = new System.Windows.Forms.Button(); this.cancelButton = new System.Windows.Forms.Button(); this.logTextBox = new System.Windows.Forms.RichTextBox(); + this.reselectButton = new System.Windows.Forms.Button(); this.SuspendLayout(); // // userProgressBar @@ -44,7 +45,7 @@ namespace CreamInstaller | System.Windows.Forms.AnchorStyles.Right))); this.userProgressBar.Location = new System.Drawing.Point(12, 27); this.userProgressBar.Name = "userProgressBar"; - this.userProgressBar.Size = new System.Drawing.Size(460, 23); + this.userProgressBar.Size = new System.Drawing.Size(500, 23); this.userProgressBar.TabIndex = 1; // // userInfoLabel @@ -53,7 +54,7 @@ namespace CreamInstaller | System.Windows.Forms.AnchorStyles.Right))); this.userInfoLabel.Location = new System.Drawing.Point(12, 9); this.userInfoLabel.Name = "userInfoLabel"; - this.userInfoLabel.Size = new System.Drawing.Size(460, 15); + this.userInfoLabel.Size = new System.Drawing.Size(500, 15); this.userInfoLabel.TabIndex = 2; this.userInfoLabel.Text = "Loading . . . "; // @@ -61,7 +62,7 @@ namespace CreamInstaller // this.acceptButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.acceptButton.Enabled = false; - this.acceptButton.Location = new System.Drawing.Point(397, 226); + this.acceptButton.Location = new System.Drawing.Point(437, 286); this.acceptButton.Name = "acceptButton"; this.acceptButton.Size = new System.Drawing.Size(75, 23); this.acceptButton.TabIndex = 3; @@ -73,7 +74,7 @@ namespace CreamInstaller // this.retryButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.retryButton.Enabled = false; - this.retryButton.Location = new System.Drawing.Point(316, 226); + this.retryButton.Location = new System.Drawing.Point(356, 286); this.retryButton.Name = "retryButton"; this.retryButton.Size = new System.Drawing.Size(75, 23); this.retryButton.TabIndex = 2; @@ -84,7 +85,7 @@ namespace CreamInstaller // cancelButton // this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.cancelButton.Location = new System.Drawing.Point(12, 226); + this.cancelButton.Location = new System.Drawing.Point(12, 286); this.cancelButton.Name = "cancelButton"; this.cancelButton.Size = new System.Drawing.Size(75, 23); this.cancelButton.TabIndex = 1; @@ -102,17 +103,29 @@ namespace CreamInstaller this.logTextBox.Name = "logTextBox"; this.logTextBox.ReadOnly = true; this.logTextBox.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.ForcedBoth; - this.logTextBox.Size = new System.Drawing.Size(460, 164); + this.logTextBox.Size = new System.Drawing.Size(500, 224); this.logTextBox.TabIndex = 4; this.logTextBox.TabStop = false; this.logTextBox.Text = ""; this.logTextBox.WordWrap = false; // + // reselectButton + // + this.reselectButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.reselectButton.Location = new System.Drawing.Point(135, 286); + this.reselectButton.Name = "reselectButton"; + this.reselectButton.Size = new System.Drawing.Size(175, 23); + this.reselectButton.TabIndex = 5; + this.reselectButton.Text = "Reselect Programs / Games"; + this.reselectButton.UseVisualStyleBackColor = true; + this.reselectButton.Click += new System.EventHandler(this.OnReselect); + // // InstallForm // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(484, 261); + this.ClientSize = new System.Drawing.Size(524, 321); + this.Controls.Add(this.reselectButton); this.Controls.Add(this.logTextBox); this.Controls.Add(this.cancelButton); this.Controls.Add(this.retryButton); @@ -123,7 +136,7 @@ namespace CreamInstaller this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; this.MinimizeBox = false; - this.MinimumSize = new System.Drawing.Size(500, 300); + this.MinimumSize = new System.Drawing.Size(540, 360); this.Name = "InstallForm"; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; @@ -141,6 +154,7 @@ namespace CreamInstaller private System.Windows.Forms.Button retryButton; private System.Windows.Forms.Button cancelButton; private System.Windows.Forms.RichTextBox logTextBox; + private System.Windows.Forms.Button reselectButton; } } diff --git a/CreamInstaller/InstallForm.cs b/CreamInstaller/InstallForm.cs index 7bf1af8..3af910f 100644 --- a/CreamInstaller/InstallForm.cs +++ b/CreamInstaller/InstallForm.cs @@ -12,6 +12,8 @@ namespace CreamInstaller { public partial class InstallForm : Form { + public bool Reselecting = false; + public InstallForm(IWin32Window owner) { Owner = owner as Form; @@ -37,7 +39,130 @@ namespace CreamInstaller } } - private async Task Install() + private async Task OperateFor(ProgramSelection selection) + { + UpdateProgress(0); + UpdateUser("Downloading CreamAPI files for " + selection.ProgramName + " . . . ", LogColor.Operation); + Program.OutputFile = selection.ProgramDirectory + "\\" + selection.DownloadNode.Name; + if (File.Exists(Program.OutputFile)) + { + try + { + File.Delete(Program.OutputFile); + } + catch + { + throw new Exception($"Unable to delete old archive file: {Program.OutputFile}"); + } + } + Progress progress = new Progress(delegate (double progress) + { + if (!Program.Canceled) + { + UpdateUser($"Downloading CreamAPI files for {selection.ProgramName} . . . {(int)progress}%", LogColor.Operation, log: false); + UpdateProgress((int)progress); + } + }); + Program.CancellationTokenSource = new CancellationTokenSource(); + Program.OutputTask = Program.MegaApiClient.DownloadFileAsync(selection.DownloadNode, Program.OutputFile, progress, Program.CancellationTokenSource.Token); + await Program.OutputTask; + UpdateUser($"Downloaded file: {Program.OutputFile}", LogColor.Resource); + UpdateProgress(100); + + UpdateProgress(0); + UpdateUser("Searching for CreamAPI files in downloaded archive . . . ", LogColor.Operation); + string resourcePath = null; + List resources = new List(); + Program.OutputArchive = ZipFile.OpenRead(Program.OutputFile); + int currentEntryCount = 0; + foreach (ZipArchiveEntry entry in Program.OutputArchive.Entries) + { + currentEntryCount++; + if (entry.Name == "steam_api64.dll") + { + resourcePath = Path.GetDirectoryName(entry.FullName); + UpdateUser("Got CreamAPI file path: " + resourcePath, LogColor.Resource); + } + UpdateProgress((currentEntryCount / (Program.OutputArchive.Entries.Count * 2)) * 100); + } + foreach (ZipArchiveEntry entry in Program.OutputArchive.Entries) + { + currentEntryCount++; + if (!string.IsNullOrEmpty(entry.Name) && Path.GetDirectoryName(entry.FullName) == resourcePath) + { + resources.Add(entry); + UpdateUser("Found CreamAPI file: " + entry.Name, LogColor.Resource); + } + UpdateProgress((currentEntryCount / (Program.OutputArchive.Entries.Count * 2)) * 100); + } + if (resources.Count < 1) + { + throw new Exception($"Unable to find CreamAPI files in downloaded archive: {Program.OutputFile}"); + } + UpdateProgress(100); + + UpdateProgress(0); + UpdateUser("Installing CreamAPI files for " + selection.ProgramName + " . . . ", LogColor.Operation); + int currentFileCount = 0; + foreach (string directory in selection.SteamApiDllDirectories) + { + Dictionary changesToRevert = new(); + foreach (ZipArchiveEntry entry in resources) + { + currentFileCount++; + string file = directory + "\\" + entry.Name; + if (File.Exists(file)) + { + string backup = file + Program.BackupFileExtension; + File.Copy(file, backup, true); + changesToRevert.Add(file, backup); + } + else + { + changesToRevert.Add(file, string.Empty); + } + try + { + entry.ExtractToFile(file, true); + } + catch + { + foreach (KeyValuePair keyValuePair in changesToRevert) + { + file = keyValuePair.Key; + string backup = keyValuePair.Value; + if (string.IsNullOrEmpty(backup)) + { + File.Delete(file); + UpdateUser("Deleted CreamAPI file: " + file, LogColor.Warning); + } + else if (file.IsFilePathLocked()) + { + File.Delete(backup); + } + else + { + File.Move(backup, file, true); + UpdateUser("Reversed changes to Steam API file: " + file, LogColor.Warning); + } + } + throw new Exception($"Unable to overwrite Steam API file: {file}"); + } + UpdateUser("Installed file: " + file, LogColor.Resource); + UpdateProgress((currentFileCount / (resources.Count * selection.SteamApiDllDirectories.Count)) * 100); + } + foreach (KeyValuePair keyValuePair in changesToRevert) + { + string file = keyValuePair.Key; + string backup = keyValuePair.Value; + if (!string.IsNullOrEmpty(backup)) + File.Delete(backup); + } + } + UpdateProgress(100); + } + + private async Task Operate() { foreach (ProgramSelection selection in Program.ProgramSelections.ToList()) { @@ -46,94 +171,49 @@ namespace CreamInstaller Program.Cleanup(cancel: false, logout: false); - UpdateProgress(0); - UpdateUser("Downloading CreamAPI files for " + selection.ProgramName + " . . . ", LogColor.Operation); - Program.OutputFile = selection.ProgramDirectory + "\\" + selection.DownloadNode.Name; - if (File.Exists(Program.OutputFile)) + bool Check() { - try + if (selection.ProgramIsRunning) { - File.Delete(Program.OutputFile); + if (new DialogForm(this).Show(Program.ApplicationName, SystemIcons.Error, + $"ERROR: {selection.ProgramName} is currently running!" + + "\n\nPlease close the program/game to continue . . .", + "Retry", "Cancel") == DialogResult.OK) + return Check(); } - catch + else { - throw new Exception("Unable to delete old archive file for " + selection.ProgramName); + return true; } + return false; } - Progress progress = new Progress(delegate (double progress) + if (!Check()) { - if (!Program.Canceled) - { - UpdateUser($"Downloading CreamAPI files for {selection.ProgramName} . . . {(int)progress}%", LogColor.Operation, log: false); - UpdateProgress((int)progress); - } - }); - Program.CancellationTokenSource = new CancellationTokenSource(); - Program.OutputTask = Program.MegaApiClient.DownloadFileAsync(selection.DownloadNode, Program.OutputFile, progress, Program.CancellationTokenSource.Token); - await Program.OutputTask; - UpdateProgress(100); + throw new Exception("The operation was canceled."); + } - UpdateProgress(0); - UpdateUser("Searching for CreamAPI files in downloaded archive . . . ", LogColor.Operation); - string resourcePath = null; - List resources = new List(); - Program.OutputArchive = ZipFile.OpenRead(Program.OutputFile); - int currentEntryCount = 0; - foreach (ZipArchiveEntry entry in Program.OutputArchive.Entries) + try { - currentEntryCount++; - if (entry.Name == "steam_api64.dll") - { - resourcePath = Path.GetDirectoryName(entry.FullName); - UpdateUser("Got CreamAPI file path: " + resourcePath, LogColor.Resource); - } - UpdateProgress((currentEntryCount / (Program.OutputArchive.Entries.Count * 2)) * 100); - } - foreach (ZipArchiveEntry entry in Program.OutputArchive.Entries) - { - currentEntryCount++; - if (!string.IsNullOrEmpty(entry.Name) && Path.GetDirectoryName(entry.FullName) == resourcePath) - { - resources.Add(entry); - UpdateUser("Found CreamAPI file: " + entry.Name, LogColor.Resource); - } - UpdateProgress((currentEntryCount / (Program.OutputArchive.Entries.Count * 2)) * 100); - } - if (resources.Count < 1) - { - throw new Exception("Unable to find CreamAPI files in downloaded archive for " + selection.ProgramName); - } - UpdateProgress(100); + await OperateFor(selection); - UpdateProgress(0); - UpdateUser("Installing CreamAPI files for " + selection.ProgramName + " . . . ", LogColor.Operation); - int currentFileCount = 0; - foreach (string directory in selection.SteamApiDllDirectories) - { - foreach (ZipArchiveEntry entry in resources) - { - currentFileCount++; - string file = directory + "\\" + entry.Name; - UpdateUser(file, LogColor.Resource); - if (File.Exists(file)) - { - try - { - File.Delete(file); - } - catch - { - throw new Exception("Unable to delete Steam API files for " + selection.ProgramName); - } - } - entry.ExtractToFile(file); - UpdateProgress((currentFileCount / (resources.Count * selection.SteamApiDllDirectories.Count)) * 100); - } + UpdateUser($"Operation succeeded for {selection.ProgramName}.", LogColor.Success); + selection.Remove(); } - UpdateProgress(100); + catch (Exception exception) + { + UpdateUser($"Operation failed for {selection.ProgramName}: " + exception.Message, LogColor.Error); + } + } - UpdateUser("CreamAPI successfully downloaded and installed for " + selection.ProgramName, LogColor.Success); - Program.ProgramSelections.Remove(selection); + Program.Cleanup(logout: false); + + if (Program.ProgramSelections.Count == 1) + { + throw new Exception($"Operation failed for {Program.ProgramSelections.First().ProgramName}."); + } + else if (Program.ProgramSelections.Count > 1) + { + throw new Exception($"Operation failed for {Program.ProgramSelections.Count} programs."); } } @@ -145,20 +225,20 @@ namespace CreamInstaller acceptButton.Enabled = false; retryButton.Enabled = false; cancelButton.Enabled = true; + reselectButton.Enabled = false; try { - await Install(); - Program.Cleanup(); - UpdateUser("CreamAPI successfully downloaded and installed for " + ProgramCount + " program(s)", LogColor.Success); + await Operate(); + UpdateUser("CreamAPI successfully downloaded and installed for " + ProgramCount + " program(s).", LogColor.Success); } catch (Exception exception) { - Program.Cleanup(logout: false); - UpdateUser("Operation failed: " + exception.Message, LogColor.Error); + UpdateUser("CreamAPI download and/or installation failed: " + exception.Message, LogColor.Error); retryButton.Enabled = true; } acceptButton.Enabled = true; cancelButton.Enabled = false; + reselectButton.Enabled = true; } private void OnLoad(object sender, EventArgs e) @@ -170,6 +250,7 @@ namespace CreamInstaller private void OnAccept(object sender, EventArgs e) { + Program.Cleanup(logout: false); Close(); } @@ -183,5 +264,12 @@ namespace CreamInstaller { Program.Cleanup(logout: false); } + + private void OnReselect(object sender, EventArgs e) + { + Program.Cleanup(logout: false); + Reselecting = true; + Close(); + } } } diff --git a/CreamInstaller/MainForm.cs b/CreamInstaller/MainForm.cs index 4d051a0..764ec0b 100644 --- a/CreamInstaller/MainForm.cs +++ b/CreamInstaller/MainForm.cs @@ -104,7 +104,7 @@ namespace CreamInstaller } catch (ApiException) { - if (new DialogForm(this).Show(Program.ApplicationName, SystemIcons.Warning, + if (new DialogForm(this).Show(Program.ApplicationName, SystemIcons.Error, $"ERROR: Failed logging into MEGA!" + "\n\nMEGA is likely offline, please try again later. . .", "Retry", "Cancel") == DialogResult.OK) diff --git a/CreamInstaller/Program.cs b/CreamInstaller/Program.cs index 92a225f..90631de 100644 --- a/CreamInstaller/Program.cs +++ b/CreamInstaller/Program.cs @@ -28,6 +28,8 @@ namespace CreamInstaller public static string CurrentProcessFilePath = CurrentProcess.MainModule.FileName; public static string CurrentProcessDirectory = CurrentProcessFilePath.Substring(0, CurrentProcessFilePath.LastIndexOf("\\")); + public static string BackupFileExtension = ".creaminstaller.backup"; + [STAThread] static void Main() { diff --git a/CreamInstaller/ProgramSelection.cs b/CreamInstaller/ProgramSelection.cs index 89e25d2..529bef4 100644 --- a/CreamInstaller/ProgramSelection.cs +++ b/CreamInstaller/ProgramSelection.cs @@ -10,6 +10,20 @@ namespace CreamInstaller public List SteamApiDllDirectories; public INode DownloadNode; + public bool ProgramIsRunning + { + get + { + foreach (string directory in SteamApiDllDirectories) + { + string file = directory + "\\steam_api64.dll"; + if (file.IsFilePathLocked()) + return true; + } + return false; + } + } + public ProgramSelection() { Program.ProgramSelections.Add(this); diff --git a/CreamInstaller/SelectForm.Designer.cs b/CreamInstaller/SelectForm.Designer.cs index 5a23442..eb75b46 100644 --- a/CreamInstaller/SelectForm.Designer.cs +++ b/CreamInstaller/SelectForm.Designer.cs @@ -38,6 +38,7 @@ namespace CreamInstaller this.label1 = new System.Windows.Forms.Label(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.allCheckBox = new System.Windows.Forms.CheckBox(); + this.noneFoundLabel = new System.Windows.Forms.Label(); this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); this.progressBar1 = new System.Windows.Forms.ProgressBar(); this.label2 = new System.Windows.Forms.Label(); @@ -80,6 +81,7 @@ namespace CreamInstaller | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox1.Controls.Add(this.allCheckBox); + this.groupBox1.Controls.Add(this.noneFoundLabel); this.groupBox1.Controls.Add(this.flowLayoutPanel1); this.groupBox1.Location = new System.Drawing.Point(12, 12); this.groupBox1.Name = "groupBox1"; @@ -103,6 +105,18 @@ namespace CreamInstaller this.allCheckBox.UseVisualStyleBackColor = true; this.allCheckBox.CheckedChanged += new System.EventHandler(this.OnAllCheckBoxChanged); // + // noneFoundLabel + // + this.noneFoundLabel.Dock = System.Windows.Forms.DockStyle.Fill; + this.noneFoundLabel.Enabled = false; + this.noneFoundLabel.Location = new System.Drawing.Point(3, 19); + this.noneFoundLabel.Name = "noneFoundLabel"; + this.noneFoundLabel.Size = new System.Drawing.Size(454, 170); + this.noneFoundLabel.TabIndex = 0; + this.noneFoundLabel.Text = "No CreamAPI-applicable programs or games were found on your computer!"; + this.noneFoundLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.noneFoundLabel.Visible = false; + // // flowLayoutPanel1 // this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; @@ -169,6 +183,7 @@ namespace CreamInstaller private System.Windows.Forms.ProgressBar progressBar1; private System.Windows.Forms.Label label2; private System.Windows.Forms.CheckBox allCheckBox; + private Label noneFoundLabel; } } diff --git a/CreamInstaller/SelectForm.cs b/CreamInstaller/SelectForm.cs index db8d727..d70e481 100644 --- a/CreamInstaller/SelectForm.cs +++ b/CreamInstaller/SelectForm.cs @@ -8,6 +8,7 @@ using Gameloop.Vdf; using Gameloop.Vdf.Linq; using System.Threading.Tasks; using System.Drawing; +using System.Linq; namespace CreamInstaller { @@ -60,14 +61,14 @@ namespace CreamInstaller if (steamApiDllDirectories is null) steamApiDllDirectories = new(); string file = gameDirectory + "\\steam_api64.dll"; - if (File.Exists(file) && !file.IsFilePathLocked()) - { + if (File.Exists(file)) steamApiDllDirectories.Add(gameDirectory); - } foreach (string _directory in Directory.GetDirectories(gameDirectory)) { GetSteamApiDllDirectoriesFromGameDirectory(_directory, steamApiDllDirectories); } + if (!steamApiDllDirectories.Any()) + return null; return steamApiDllDirectories; } @@ -113,11 +114,13 @@ namespace CreamInstaller { progress.Report(++curProgress); string rootDirectory; - List directories; + List directories = null; if (node.Name == "Paradox Launcher") { rootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); - directories = GetSteamApiDllDirectoriesFromGameDirectory(rootDirectory + "\\Programs\\Paradox Interactive"); + string launcherDirectory = rootDirectory + "\\Programs\\Paradox Interactive"; + if (Directory.Exists(launcherDirectory)) + directories = GetSteamApiDllDirectoriesFromGameDirectory(launcherDirectory); } else { @@ -211,20 +214,63 @@ namespace CreamInstaller label2.Hide(); progressBar1.Hide(); - allCheckBox.Enabled = true; - foreach (CheckBox checkBox in checkBoxes) - checkBox.Enabled = true; + if (Program.ProgramSelections.Any()) + { + allCheckBox.Enabled = true; + foreach (CheckBox checkBox in checkBoxes) + checkBox.Enabled = true; - acceptButton.Enabled = true; + acceptButton.Enabled = true; + } + else + { + noneFoundLabel.Visible = true; + } + } private void OnAccept(object sender, EventArgs e) { if (Program.ProgramSelections.Count > 0) { + foreach (ProgramSelection selection in Program.ProgramSelections) + { + bool Check() + { + if (selection.ProgramIsRunning) + { + if (new DialogForm(this).Show(Program.ApplicationName, SystemIcons.Error, + $"ERROR: {selection.ProgramName} is currently running!" + + "\n\nPlease close the program/game to continue . . .", + "Retry", "Cancel") == DialogResult.OK) + return Check(); + } + else + { + return true; + } + return false; + } + if (!Check()) + return; + } + Hide(); - new InstallForm(this).ShowDialog(); - Close(); + InstallForm installForm = new InstallForm(this); + installForm.ShowDialog(); + if (installForm.Reselecting) + { + foreach (CheckBox checkBox in checkBoxes) + { + checkBox.Checked = !checkBox.Checked; + checkBox.Checked = !checkBox.Checked; // to fire CheckChanged + } + int X = (installForm.Location.X + installForm.Size.Width / 2) - Size.Width / 2; + int Y = (installForm.Location.Y + installForm.Size.Height / 2) - Size.Height / 2; + Location = new Point(X, Y); + Show(); + } + else Close(); } }