diff --git a/CreamInstaller/Components/CustomForm.cs b/CreamInstaller/Components/CustomForm.cs
index 273de14..57ddb43 100644
--- a/CreamInstaller/Components/CustomForm.cs
+++ b/CreamInstaller/Components/CustomForm.cs
@@ -6,14 +6,14 @@ internal class CustomForm : Form
{
internal CustomForm() : base() => Icon = Properties.Resources.Icon;
- internal CustomForm(IWin32Window owner) : this() => Owner = owner as Form;
+ internal CustomForm(IWin32Window owner) : this() => Owner = (owner as Form) ?? ActiveForm;
protected override CreateParams CreateParams // Double buffering for all controls
{
get
{
CreateParams handleParam = base.CreateParams;
- handleParam.ExStyle |= 0x02000000; // WS_EX_COMPOSITED
+ handleParam.ExStyle |= 0x02; // WS_EX_COMPOSITED
return handleParam;
}
}
diff --git a/CreamInstaller/CreamInstaller.csproj b/CreamInstaller/CreamInstaller.csproj
index 5b89a59..a77f8d8 100644
--- a/CreamInstaller/CreamInstaller.csproj
+++ b/CreamInstaller/CreamInstaller.csproj
@@ -5,7 +5,7 @@
True
Resources\ini.ico
true
- 3.4.0.5
+ 3.4.1.0
Resources\ini.ico
LICENSE
2021, pointfeev (https://github.com/pointfeev)
@@ -36,7 +36,7 @@
True
-
+
diff --git a/CreamInstaller/Forms/DialogForm.cs b/CreamInstaller/Forms/DialogForm.cs
index 4ce0447..6767087 100644
--- a/CreamInstaller/Forms/DialogForm.cs
+++ b/CreamInstaller/Forms/DialogForm.cs
@@ -10,10 +10,8 @@ internal partial class DialogForm : CustomForm
{
internal DialogForm(IWin32Window owner) : base(owner) => InitializeComponent();
- internal DialogResult Show(Icon descriptionIcon, string descriptionText, string acceptButtonText, string cancelButtonText = null, Icon customFormIcon = null)
+ internal DialogResult Show(Icon descriptionIcon, string descriptionText, string acceptButtonText, string cancelButtonText = null, string customFormText = null, Icon customFormIcon = null)
{
- if (customFormIcon is not null)
- Icon = customFormIcon;
if (descriptionIcon is null)
descriptionIcon = Icon;
icon.Image = descriptionIcon.ToBitmap();
@@ -25,8 +23,15 @@ internal partial class DialogForm : CustomForm
cancelButton.Visible = false;
}
else cancelButton.Text = cancelButtonText;
- OnResize(null, null);
- Resize += OnResize;
+ if (customFormText is not null)
+ Text = customFormText;
+ else
+ {
+ OnResize(null, null);
+ Resize += OnResize;
+ }
+ if (customFormIcon is not null)
+ Icon = customFormIcon;
return ShowDialog();
}
diff --git a/CreamInstaller/Forms/InstallForm.cs b/CreamInstaller/Forms/InstallForm.cs
index 2258d89..d980c29 100644
--- a/CreamInstaller/Forms/InstallForm.cs
+++ b/CreamInstaller/Forms/InstallForm.cs
@@ -400,7 +400,7 @@ internal partial class InstallForm : CustomForm
}
catch (Exception e)
{
- if (ExceptionHandler.OutputException(e)) goto retry;
+ if (e.HandleException(form: this)) goto retry;
Close();
}
}
diff --git a/CreamInstaller/Forms/MainForm.cs b/CreamInstaller/Forms/MainForm.cs
index e0f5864..20e8f31 100644
--- a/CreamInstaller/Forms/MainForm.cs
+++ b/CreamInstaller/Forms/MainForm.cs
@@ -144,7 +144,7 @@ internal partial class MainForm : CustomForm
}
catch (Exception e)
{
- if (ExceptionHandler.OutputException(e)) goto retry;
+ if (e.HandleException(form: this)) goto retry;
Close();
}
}
diff --git a/CreamInstaller/Forms/SelectForm.cs b/CreamInstaller/Forms/SelectForm.cs
index 5fd6030..77a31da 100644
--- a/CreamInstaller/Forms/SelectForm.cs
+++ b/CreamInstaller/Forms/SelectForm.cs
@@ -706,7 +706,7 @@ internal partial class SelectForm : CustomForm
}
catch (Exception e)
{
- if (ExceptionHandler.OutputException(e)) goto retry;
+ if (e.HandleException(form: this)) goto retry;
Close();
}
}
@@ -786,6 +786,6 @@ internal partial class SelectForm : CustomForm
"\n\nBlocked game names:" + blockedGames +
"\n\nBlocked game sub-directories:" + blockedDirectories +
"\n\nBlocked game sub-directory exceptions (not blocked):" + blockedDirectoryExceptions,
- "OK");
+ "OK", customFormText: "Block Protected Games");
}
}
diff --git a/CreamInstaller/Paradox/ParadoxLauncher.cs b/CreamInstaller/Paradox/ParadoxLauncher.cs
index 4dcc078..165f736 100644
--- a/CreamInstaller/Paradox/ParadoxLauncher.cs
+++ b/CreamInstaller/Paradox/ParadoxLauncher.cs
@@ -55,7 +55,7 @@ internal static class ParadoxLauncher
return dialogForm.Show(SystemIcons.Warning,
$"WARNING: There are no installed games with DLC that can be added to the Paradox Launcher!" +
"\n\nInstalling CreamAPI/ScreamAPI for the Paradox Launcher is pointless, since no DLC will be added to the configuration!",
- "Ignore", "Cancel") != DialogResult.OK;
+ "Ignore", "Cancel", customFormText: "Paradox Launcher") != DialogResult.OK;
}
}
return false;
@@ -131,12 +131,12 @@ internal static class ParadoxLauncher
}
if (neededRepair)
{
- if (form is not InstallForm) dialogForm.Show(form.Icon, "Paradox Launcher successfully repaired!", "OK");
+ if (form is not InstallForm) dialogForm.Show(form.Icon, "Paradox Launcher successfully repaired!", "OK", customFormText: "Paradox Launcher");
return 1;
}
else
{
- if (form is not InstallForm) dialogForm.Show(SystemIcons.Information, "Paradox Launcher does not need to be repaired.", "OK");
+ if (form is not InstallForm) dialogForm.Show(SystemIcons.Information, "Paradox Launcher does not need to be repaired.", "OK", customFormText: "Paradox Launcher");
return 0;
}
}
@@ -144,7 +144,7 @@ internal static class ParadoxLauncher
{
if (form is not InstallForm) dialogForm.Show(SystemIcons.Error, "Paradox Launcher repair failed!"
+ "\n\nAn original Steamworks/Epic Online Services SDK file could not be found."
- + "\nYou must reinstall Paradox Launcher to fix this issue.", "OK");
+ + "\nYou must reinstall Paradox Launcher to fix this issue.", "OK", customFormText: "Paradox Launcher");
return -1;
}
}
diff --git a/CreamInstaller/Program.cs b/CreamInstaller/Program.cs
index 95150f6..19de3ab 100644
--- a/CreamInstaller/Program.cs
+++ b/CreamInstaller/Program.cs
@@ -87,6 +87,9 @@ internal static class Program
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ApplicationExit += new(OnApplicationExit);
+ Application.ThreadException += new((s, e) => e.Exception?.HandleFatalException());
+ Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
+ AppDomain.CurrentDomain.UnhandledException += new((s, e) => (e.ExceptionObject as Exception)?.HandleFatalException());
retry:
try
{
@@ -96,7 +99,7 @@ internal static class Program
}
catch (Exception e)
{
- if (ExceptionHandler.OutputException(e)) goto retry;
+ if (e.HandleException()) goto retry;
Application.Exit();
return;
}
diff --git a/CreamInstaller/Utility/ExceptionHandler.cs b/CreamInstaller/Utility/ExceptionHandler.cs
index 6f923fe..ce8bc2a 100644
--- a/CreamInstaller/Utility/ExceptionHandler.cs
+++ b/CreamInstaller/Utility/ExceptionHandler.cs
@@ -1,15 +1,15 @@
using System;
+using System.Drawing;
using System.Windows.Forms;
namespace CreamInstaller.Utility;
internal static class ExceptionHandler
{
- internal static bool OutputException(Exception e)
+ internal static bool HandleException(this Exception e, Form form = null, string caption = "CreamInstaller encountered an exception", string acceptButtonText = "Retry", string cancelButtonText = "Cancel")
{
- while (e.InnerException is not null)
+ while (e.InnerException is not null) // we usually don't need the outer exceptions
e = e.InnerException;
-
string output = "";
string[] stackTrace = e.StackTrace?.Split('\n');
if (stackTrace is not null && stackTrace.Length > 0)
@@ -18,8 +18,19 @@ internal static class ExceptionHandler
for (int i = 0; i < Math.Min(stackTrace.Length, 3); i++)
{
string line = stackTrace[i];
- if (line is not null)
- output += "\n " + line[line.IndexOf("at")..];
+ int atNum = line.IndexOf("at ");
+ int inNum = line.IndexOf("in ");
+ int ciNum = line.LastIndexOf(@"CreamInstaller\");
+ int lineNum = line.LastIndexOf(":line ");
+ if (line is not null && atNum != -1)
+ output += "\n " + (inNum != -1 ? line[atNum..(inNum - 1)] : line[atNum..])
+ + (inNum != -1 ? ("\n "
+ + (ciNum != -1 ? ("in "
+ + (lineNum != -1 ? line[ciNum..lineNum]
+ + "\n on " + line[(lineNum + 1)..]
+ : line[ciNum..]))
+ : line[inNum..]))
+ : null);
}
}
string[] messageLines = e.Message?.Split('\n');
@@ -27,16 +38,24 @@ internal static class ExceptionHandler
{
if (output.Length > 0)
output += "\n\n";
-
output += "MESSAGE\n";
for (int i = 0; i < messageLines.Length; i++)
{
string line = messageLines[i];
if (line is not null)
- output += "\n " + messageLines[i];
+ output += "\n " + line;
}
}
- return MessageBox.Show(output, caption: "CreamInstaller encountered an exception", buttons: MessageBoxButtons.RetryCancel, icon: MessageBoxIcon.Error) == DialogResult.Retry;
+ using DialogForm dialogForm = new(form ?? Form.ActiveForm);
+ return dialogForm.Show(SystemIcons.Error, output, acceptButtonText, cancelButtonText, customFormText: caption) == DialogResult.OK;
+ }
+
+ internal static void HandleFatalException(this Exception e)
+ {
+ bool? restart = e?.HandleException(caption: "CreamInstaller encountered a fatal exception", acceptButtonText: "Restart");
+ if (restart.HasValue && restart.Value)
+ Application.Restart();
+ Application.Exit();
}
}
diff --git a/CreamInstaller/Utility/HttpClientManager.cs b/CreamInstaller/Utility/HttpClientManager.cs
index 0a9e6c8..3ec3b36 100644
--- a/CreamInstaller/Utility/HttpClientManager.cs
+++ b/CreamInstaller/Utility/HttpClientManager.cs
@@ -55,5 +55,5 @@ internal static class HttpClientManager
}
}
- internal static void Dispose() => HttpClient.Dispose();
+ internal static void Dispose() => HttpClient?.Dispose();
}