Skip to content

Commit 07d1786

Browse files
committed
Add a better crash dialog for when UniGetUI is missing required files
1 parent 92bfb97 commit 07d1786

7 files changed

Lines changed: 143 additions & 84 deletions

File tree

cli-arguments.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
| `--enable-setting key` | Enables the boolean setting _key_* | 3.2.0+ |
1616
| `--disable-setting key` | Disables the boolean setting _key_* | 3.2.0+ |
1717
| `--set-setting-value key value` | Sets the value _value_ to the non-boolean setting _key_. To clear a non-boolean setting, `--disable-setting` can be used* | 3.2.0+ |
18+
| `--no-corrupt-dialog` | Will show a verbose error message (the error report) instead of a simplified message dialog | 3.2.1+ |
1819

1920

2021
\*After modifying the settings, you must ensure that any running instance of UniGetUI is restarted for the changes to take effect

src/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
66
<!-- IF BUILD FAILS DUE TO MISSING Microsoft.Management.Deployment NAMESPACE,
77
TOGGLE THE LAST NUMBER OF THE LINE BELOW 1 UNIT UP OR DOWN, AND REBUILD-->
8-
<WindowsSdkPackageVersion>10.0.26100.57</WindowsSdkPackageVersion>
8+
<WindowsSdkPackageVersion>10.0.26100.56</WindowsSdkPackageVersion>
99

1010
<SdkVersion>8.0.407</SdkVersion>
1111
<Authors>Martí Climent and the contributors</Authors>

src/UniGetUI.Core.Tools/Tools.cs

Lines changed: 5 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -207,80 +207,6 @@ public static string RandomString(int length)
207207
return new string(chars.ToArray());
208208
}
209209

210-
public static void ReportFatalException(Exception e)
211-
{
212-
Debugger.Break();
213-
string LangName = "Unknown";
214-
try
215-
{
216-
LangName = LanguageEngine.Locale;
217-
}
218-
catch
219-
{
220-
// ignored
221-
}
222-
223-
string Error_String = $@"
224-
Windows version: {Environment.OSVersion.VersionString}
225-
Language: {LangName}
226-
APP Version: {CoreData.VersionName}
227-
APP Build number: {CoreData.BuildNumber}
228-
Executable: {Environment.ProcessPath}
229-
230-
Crash HResult: 0x{(uint)e.HResult:X} ({(uint)e.HResult}, {e.HResult})
231-
Crash Message: {e.Message}
232-
233-
Crash Traceback:
234-
{e.StackTrace}";
235-
236-
try
237-
{
238-
int i = 0;
239-
while (e.InnerException is not null)
240-
{
241-
i++;
242-
e = e.InnerException;
243-
Error_String += $@"
244-
245-
246-
---------------------
247-
Inner exception ({i}):
248-
Crash HResult: 0x{(uint)e.HResult:X} ({(uint)e.HResult}, {e.HResult})
249-
Crash Message: {e.Message}
250-
251-
Crash Traceback:
252-
{e.StackTrace}";
253-
}
254-
255-
if (i == 0)
256-
{
257-
Error_String += $"\n\n\nNo inner exceptions found";
258-
}
259-
} catch
260-
{
261-
// ignore
262-
}
263-
264-
Console.WriteLine(Error_String);
265-
266-
string ErrorBody = "https://www.marticliment.com/error-report/?appName=UniGetUI^&errorBody=" +
267-
Uri.EscapeDataString(Error_String.Replace("\n", "{l}"));
268-
269-
Console.WriteLine(ErrorBody);
270-
271-
using Process cmd = new();
272-
cmd.StartInfo.FileName = "cmd.exe";
273-
cmd.StartInfo.RedirectStandardInput = true;
274-
cmd.StartInfo.RedirectStandardOutput = true;
275-
cmd.StartInfo.CreateNoWindow = true;
276-
cmd.StartInfo.UseShellExecute = false;
277-
cmd.Start();
278-
cmd.StandardInput.WriteLine("start " + ErrorBody);
279-
cmd.StandardInput.WriteLine("exit");
280-
cmd.WaitForExit();
281-
Environment.Exit(1);
282-
}
283-
284210
/// <summary>
285211
/// Launches a .bat or .cmd file for the given filename
286212
/// </summary>
@@ -750,5 +676,10 @@ public static async void ShowFileOnExplorer(string path)
750676
await p.WaitForExitAsync();
751677
p.Dispose();
752678
}
679+
680+
public static string GetCurrentLocale()
681+
{
682+
return LanguageEngine?.Locale ?? "Unset/Unknown";
683+
}
753684
}
754685
}

src/UniGetUI/App.xaml.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public MainApp()
8888
}
8989
catch (Exception e)
9090
{
91-
CoreTools.ReportFatalException(e);
91+
CrashHandler.ReportFatalException(e);
9292
}
9393
}
9494

@@ -119,7 +119,7 @@ private void RegisterErrorHandling()
119119
Logger.Error(" -");
120120
if (Environment.GetCommandLineArgs().Contains("--report-all-errors") || RaiseExceptionAsFatal || MainWindow is null)
121121
{
122-
CoreTools.ReportFatalException(e.Exception);
122+
CrashHandler.ReportFatalException(e.Exception);
123123
}
124124
else
125125
{
@@ -235,7 +235,7 @@ private async Task LoadComponentsAsync()
235235
}
236236
catch (Exception e)
237237
{
238-
CoreTools.ReportFatalException(e);
238+
CrashHandler.ReportFatalException(e);
239239
}
240240
}
241241

src/UniGetUI/CLIHandler.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public static class CLIHandler
1010
public const string MIGRATE_WINGETUI_TO_UNIGETUI = "--migrate-wingetui-to-unigetui";
1111
public const string UNINSTALL_WINGETUI = "--uninstall-wingetui";
1212
public const string UNINSTALL_UNIGETUI = "--uninstall-unigetui";
13+
public const string NO_CORRUPT_DIALOG = "--no-corrupt-dialog";
1314

1415
public const string IMPORT_SETTINGS = "--import-settings";
1516
public const string EXPORT_SETTINGS = "--export-settings";

src/UniGetUI/CrashHandler.cs

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
using System.Diagnostics;
2+
using Microsoft.UI;
3+
using UniGetUI.Core.Data;
4+
using UniGetUI.Core.Language;
5+
using UniGetUI.Core.Tools;
6+
7+
namespace UniGetUI;
8+
9+
public static class CrashHandler
10+
{
11+
private const uint MB_ICONSTOP = 0x00000010;
12+
13+
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
14+
private static extern int MessageBox(IntPtr hWnd, string lpText, string lpCaption, uint uType);
15+
16+
private static bool _reportMissingFiles()
17+
{
18+
try
19+
{
20+
var errorMessage = "UniGetUI has detected that some required files are missing."
21+
+ "\n\nThis might be caused by an incomplete installation or corrupted files. Please reinstall UniGetUI."
22+
+ "\n\nRun UniGetUI with the parameter '--no-corrupt-dialog' to get more details about the crash.";
23+
24+
var title = "UniGetUI - Missing Files";
25+
26+
MessageBox(IntPtr.Zero, errorMessage, title, MB_ICONSTOP);
27+
return true;
28+
}
29+
catch
30+
{
31+
return false;
32+
}
33+
}
34+
35+
public static void ReportFatalException(Exception e)
36+
{
37+
Debugger.Break();
38+
39+
40+
if (!Environment.GetCommandLineArgs().Contains(CLIHandler.NO_CORRUPT_DIALOG))
41+
{
42+
Exception? fileEx = e;
43+
while (fileEx is not null)
44+
{
45+
if (fileEx.ToString().Contains("Could not load file or assembly"))
46+
{
47+
if (_reportMissingFiles())
48+
{
49+
Environment.Exit(1);
50+
}
51+
}
52+
fileEx = fileEx.InnerException;
53+
}
54+
}
55+
56+
string LangName = "Unknown";
57+
try
58+
{
59+
LangName = CoreTools.GetCurrentLocale();
60+
}
61+
catch
62+
{
63+
// ignored
64+
}
65+
66+
string Error_String = $@"
67+
Windows version: {Environment.OSVersion.VersionString}
68+
Language: {LangName}
69+
APP Version: {CoreData.VersionName}
70+
APP Build number: {CoreData.BuildNumber}
71+
Executable: {Environment.ProcessPath}
72+
73+
Crash HResult: 0x{(uint)e.HResult:X} ({(uint)e.HResult}, {e.HResult})
74+
Crash Message: {e.Message}
75+
76+
Crash Traceback:
77+
{e.StackTrace}";
78+
79+
try
80+
{
81+
int i = 0;
82+
while (e.InnerException is not null)
83+
{
84+
i++;
85+
e = e.InnerException;
86+
Error_String += $@"
87+
88+
89+
---------------------
90+
Inner exception ({i}):
91+
Crash HResult: 0x{(uint)e.HResult:X} ({(uint)e.HResult}, {e.HResult})
92+
Crash Message: {e.Message}
93+
94+
Crash Traceback:
95+
{e.StackTrace}";
96+
}
97+
98+
if (i == 0)
99+
{
100+
Error_String += $"\n\n\nNo inner exceptions found";
101+
}
102+
} catch
103+
{
104+
// ignore
105+
}
106+
107+
Console.WriteLine(Error_String);
108+
109+
string ErrorBody = "https://www.marticliment.com/error-report/?appName=UniGetUI^&errorBody=" +
110+
Uri.EscapeDataString(Error_String.Replace("\n", "{l}"));
111+
112+
Console.WriteLine(ErrorBody);
113+
114+
using Process cmd = new();
115+
cmd.StartInfo.FileName = "cmd.exe";
116+
cmd.StartInfo.RedirectStandardInput = true;
117+
cmd.StartInfo.RedirectStandardOutput = true;
118+
cmd.StartInfo.CreateNoWindow = true;
119+
cmd.StartInfo.UseShellExecute = false;
120+
cmd.Start();
121+
cmd.StandardInput.WriteLine("start " + ErrorBody);
122+
cmd.StandardInput.WriteLine("exit");
123+
cmd.WaitForExit();
124+
Environment.Exit(1);
125+
}
126+
}

src/UniGetUI/EntryPoint.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Microsoft.UI.Dispatching;
2+
using Microsoft.UI.Xaml;
23
using Microsoft.Windows.AppLifecycle;
34
using UniGetUI.Core.Data;
45
using UniGetUI.Core.Logging;
@@ -62,7 +63,7 @@ private static void Main(string[] args)
6263
}
6364
catch (Exception e)
6465
{
65-
CoreTools.ReportFatalException(e);
66+
CrashHandler.ReportFatalException(e);
6667
}
6768
}
6869

@@ -95,18 +96,17 @@ Welcome to UniGetUI Version {CoreData.VersionName}
9596
// If this is the main instance, start the app
9697
if (!isRedirect)
9798
{
98-
Microsoft.UI.Xaml.Application.Start((_) =>
99+
Application.Start((_) =>
99100
{
100-
DispatcherQueueSynchronizationContext context = new(
101-
DispatcherQueue.GetForCurrentThread());
101+
DispatcherQueueSynchronizationContext context = new(DispatcherQueue.GetForCurrentThread());
102102
SynchronizationContext.SetSynchronizationContext(context);
103103
var app = new MainApp();
104104
});
105105
}
106106
}
107107
catch (Exception e)
108108
{
109-
CoreTools.ReportFatalException(e);
109+
CrashHandler.ReportFatalException(e);
110110
}
111111
}
112112

@@ -126,7 +126,7 @@ private static async Task<bool> DecideRedirection()
126126
{
127127
keyInstance.Activated += async (_, e) =>
128128
{
129-
if (MainApp.Current is MainApp baseInstance)
129+
if (Application.Current is MainApp baseInstance)
130130
{
131131
await baseInstance.ShowMainWindowFromRedirectAsync(e);
132132
}

0 commit comments

Comments
 (0)