v3.4.1.0
- Added fatal exception handling - Vastly improved exception output formatting - Other minor visual changes and refactoring
This commit is contained in:
parent
31621d8677
commit
79e7bc73ed
10 changed files with 54 additions and 27 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<UseWindowsForms>True</UseWindowsForms>
|
||||
<ApplicationIcon>Resources\ini.ico</ApplicationIcon>
|
||||
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
|
||||
<Version>3.4.0.5</Version>
|
||||
<Version>3.4.1.0</Version>
|
||||
<PackageIcon>Resources\ini.ico</PackageIcon>
|
||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||
<Copyright>2021, pointfeev (https://github.com/pointfeev)</Copyright>
|
||||
|
@ -36,7 +36,7 @@
|
|||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Gameloop.Vdf" Version="0.6.2" />
|
||||
<PackageReference Include="Gameloop.Vdf" Version="0.6.1" />
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.42" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Onova" Version="2.6.2" />
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,5 +55,5 @@ internal static class HttpClientManager
|
|||
}
|
||||
}
|
||||
|
||||
internal static void Dispose() => HttpClient.Dispose();
|
||||
internal static void Dispose() => HttpClient?.Dispose();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue