-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathApplicationEvents.vb
187 lines (174 loc) · 13.8 KB
/
ApplicationEvents.vb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
Imports Microsoft.Win32
Imports Microsoft.VisualBasic.ControlChars
Imports System.Management
Imports System.IO
Imports System.Text.Encoding
Namespace My
' Los siguientes eventos están disponibles para MyApplication:
'
' Inicio: se desencadena cuando se inicia la aplicación, antes de que se cree el formulario de inicio.
' Apagado: generado después de cerrar todos los formularios de la aplicación. Este evento no se genera si la aplicación termina de forma anómala.
' UnhandledException: generado si la aplicación detecta una excepción no controlada.
' StartupNextInstance: se desencadena cuando se inicia una aplicación de instancia única y la aplicación ya está activa.
' NetworkAvailabilityChanged: se desencadena cuando la conexión de red está conectada o desconectada.
Partial Friend Class MyApplication
Private lastThemeChangeTime As DateTime = DateTime.Now
Private debounceInterval As TimeSpan = TimeSpan.FromSeconds(2)
Private Sub Start(sender As Object, e As EventArgs) Handles Me.Startup
DynaLog.LogMessage("Adding startup event handlers...")
AddHandler Microsoft.Win32.SystemEvents.UserPreferenceChanged, AddressOf SysEvts_UserPreferenceChanged
AddHandler Microsoft.Win32.SystemEvents.DisplaySettingsChanging, AddressOf SysEvts_DisplaySettingsChanging
AddHandler Microsoft.Win32.SystemEvents.DisplaySettingsChanged, AddressOf SysEvts_DisplaySettingsChanged
End Sub
Private Sub CatchEmAll(sender As Object, e As Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs) Handles Me.UnhandledException
DynaLog.LogMessage("Unhandled exception occurred. Gotta catch'em all !")
DynaLog.LogMessage("Exception information:")
DynaLog.LogMessage("- Message: " & e.Exception.Message)
DynaLog.LogMessage("- Code (HRESULT): " & Hex(e.Exception.HResult))
ExceptionForm.ErrorText.Text = e.Exception.ToString() & CrLf & CrLf &
"Error Message: " & e.Exception.Message & CrLf & CrLf &
"Error Code (HRESULT): " & Hex(e.Exception.HResult)
Try
DynaLog.LogMessage("Getting program information for exception report...")
' Get version of DISMTools that threw the exception. Include program version, branch, and (possibly) build time
' in the case of nightly installers
ExceptionForm.ErrorText.AppendText(CrLf & CrLf &
"Program information:" & CrLf &
" - DISMTools Version: " & My.Application.Info.Version.ToString() & CrLf &
" - Preview release? " & If(DISMTools.MainForm.dtBranch.Contains("preview"), "Yes", "No") & CrLf &
" - Branch: " & DISMTools.MainForm.dtBranch & CrLf &
" - Build time: " & DISMTools.PrgAbout.RetrieveLinkerTimestamp(My.Application.Info.DirectoryPath & "\" & My.Application.Info.AssemblyName & ".exe").ToString("yyMMdd-HHmm") & CrLf &
" - Portable copy? " & If(File.Exists(My.Application.Info.DirectoryPath & "\portable"), "Yes", "No") & CrLf)
' Get image information if a project has been loaded
If DISMTools.MainForm.isProjectLoaded And Not DISMTools.MainForm.OnlineManagement Then
DynaLog.LogMessage("Getting information about the image/installation for exception report...")
Try
ExceptionForm.ErrorText.AppendText(CrLf &
"Information about the image loaded in this project:" & CrLf &
" - Image name: " & DISMTools.MainForm.Label46.Text & CrLf &
" - Image description: " & DISMTools.MainForm.Label47.Text & CrLf &
" - Image version: " & DISMTools.MainForm.Label48.Text)
Catch ex As Exception
DynaLog.LogMessage("Could not get image/installation information. Error message: " & ex.Message)
' Don't get this info
End Try
End If
DynaLog.LogMessage("Getting computer, BIOS, OS and processor information for exception report...")
DynaLog.LogMessage("--- NO PERSONALLY IDENTIFIABLE INFORMATION WILL BE INCLUDED IN THE REPORT ---")
DynaLog.LogMessage("---- I ONLY GRAB THIS INFORMATION TO HELP ISOLATE BUGS TO A HW/SW CONFIG ----")
DynaLog.LogMessage("I really care about your privacy and, like you, I hate tracking.")
' Get basic information about the system. This does not include any personally identifiable information (PII) or
' serial numbers that can identify the computer this program is run on
Dim CS_Searcher As ManagementObjectSearcher = New ManagementObjectSearcher("SELECT Manufacturer, Model FROM Win32_ComputerSystem")
Dim BIOS_Searcher As ManagementObjectSearcher = New ManagementObjectSearcher("SELECT Name, Description, SMBIOSBIOSVersion FROM Win32_BIOS")
Dim Proc_Searcher As ManagementObjectSearcher = New ManagementObjectSearcher("SELECT Name, Caption, Manufacturer, Family FROM Win32_Processor")
Dim CS_Results As ManagementObjectCollection = CS_Searcher.Get()
Dim BIOS_Results As ManagementObjectCollection = BIOS_Searcher.Get()
Dim Proc_Results As ManagementObjectCollection = Proc_Searcher.Get()
ExceptionForm.ErrorText.AppendText(CrLf &
"Machine information:" & CrLf)
For Each CS_Result As ManagementObject In CS_Results
ExceptionForm.ErrorText.AppendText(" - Computer manufacturer: " & CS_Result("Manufacturer") & CrLf &
" - Computer model: " & CS_Result("Model") & CrLf)
Next
For Each BIOS_Result As ManagementObject In BIOS_Results
ExceptionForm.ErrorText.AppendText(" - BIOS name/description: " & BIOS_Result("Name") & " " & BIOS_Result("Description") & CrLf &
" - System Management BIOS (SMBIOS) version: " & BIOS_Result("SMBIOSBIOSVersion") & CrLf & CrLf)
Next
ExceptionForm.ErrorText.AppendText("Operating system information:" & CrLf &
" - OS name: " & My.Computer.Info.OSFullName & CrLf &
" - OS version: " & My.Computer.Info.OSVersion & CrLf &
" - OS Platform: " & My.Computer.Info.OSPlatform & CrLf &
" - Is a 64-bit system? " & If(Environment.Is64BitOperatingSystem, "Yes", "No") & CrLf & CrLf &
"Processor information:" & CrLf)
For Each Proc_Result As ManagementObject In Proc_Results
ExceptionForm.ErrorText.AppendText(" - Processor name: " & Proc_Result("Name") & CrLf &
" - Processor caption: " & Proc_Result("Caption") & CrLf &
" - Processor manufacturer: " & Proc_Result("Manufacturer") & CrLf &
" - Processor family (WMI type): " & Proc_Result("Family") & CrLf &
" NOTE: refer to the following website to get the exact family type of your processor:" & CrLf &
" https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-processor" & CrLf & CrLf)
Next
ExceptionForm.ErrorText.AppendText("This information is gathered to help isolate the issue to a specific hardware or software configuration. " &
"No information that can be used to identify the user or the exact system is gathered." & CrLf & CrLf &
"If you don't want to send this information to the developers, paste the text that was copied to the clipboard in a text editor, remove this information, and copy the new text again.")
Catch ex As Exception
DynaLog.LogMessage("Could not get system information. Error message: " & ex.Message)
' Could not get basic machine information
End Try
Try
DynaLog.LogMessage("Saving exception information to the error report...")
If Not Directory.Exists(Path.Combine(Windows.Forms.Application.StartupPath, "logs", "errors")) Then
DynaLog.LogMessage("Creating directory for error reports...")
Directory.CreateDirectory(Path.Combine(Windows.Forms.Application.StartupPath, "logs", "errors"))
End If
File.WriteAllText(Path.Combine(Windows.Forms.Application.StartupPath, "logs", "errors") & "\DT-Error-" & Now.ToString().Replace("/", "-").Trim().Replace(":", "-").Trim() & ".log", ExceptionForm.ErrorText.Text, UTF8)
Catch ex As Exception
DynaLog.LogMessage("Could not create the error report. Error message: " & ex.Message)
' Could not save error information
End Try
ExceptionForm.ShowDialog()
If ExceptionForm.DialogResult = DialogResult.OK Then
DynaLog.LogMessage("DISMTools will continue execution as user decided to do so.")
DynaLog.LogMessage("This is not the most recommended thing as it may happen again.")
e.ExitApplication = False
ElseIf ExceptionForm.DialogResult = DialogResult.Cancel Then
DynaLog.LogMessage("DISMTools will stop execution as user decided to do so.")
e.ExitApplication = True
End If
End Sub
Private Sub SysEvts_UserPreferenceChanged(sender As Object, e As Microsoft.Win32.UserPreferenceChangedEventArgs)
DynaLog.LogMessage("A user preference of type " & e.Category.ToString() & " has changed.")
' Prevent the program from freezing. This is a fix for a very long-standing bug that was introduced with the mounted image detector,
' where the program would randomly freeze and never come back. And, even while the program itself was still responding, its UI thread
' wasn't.
'
' This is a problem with Windows Forms that has been present since .NET Framework 2.0. More on that here:
' https://www.ikriv.com/dev/dotnet/MysteriousHang
'
' Even though this bug took a year and a half to fix, a lot was gathered from previous attempts at fixing this problem:
' 1. It's random
' 2. It affects all versions of Windows supported by this program (Win8.1-Win11, incl. servers)
' 3. It happens when the following conditions occur:
' - The mounted image detector is running
' - This event is triggered
'
' This fixes the problem by temporarily stopping the mounted image detector, doing the event code, and restarting it afterward.
' It causes a temporary freeze, but it always comes back.
DynaLog.LogMessage("Detecting if mounted image detector is busy...")
If DISMTools.MainForm.MountedImageDetectorBW.IsBusy Then
DynaLog.LogMessage("Mounted image detector is busy. Stopping to avoid a permanent freeze...")
DISMTools.MainForm.MountedImageDetectorBW.CancelAsync()
End If
If e.Category = UserPreferenceCategory.General And DISMTools.MainForm.ColorMode = 0 Then
DynaLog.LogMessage("Detecting if the system color theme changed...")
Dim currentTime As DateTime = DateTime.Now
DynaLog.LogMessage("Current system time: " & currentTime.ToString())
DynaLog.LogMessage("Time theme last changed: " & lastThemeChangeTime.ToString())
DynaLog.LogMessage("Time difference in seconds: " & (currentTime - lastThemeChangeTime).TotalSeconds)
DynaLog.LogMessage("Debounce interval: " & debounceInterval.TotalSeconds)
If currentTime - lastThemeChangeTime > debounceInterval Then
DynaLog.LogMessage("Time difference is over debounce interval. Changing color theme...")
DISMTools.MainForm.ChangePrgColors(0)
DynaLog.LogMessage("Setting the time the theme last changed...")
lastThemeChangeTime = currentTime
End If
End If
Try
DynaLog.LogMessage("Restarting mounted image detector...")
Threading.Thread.Sleep(1000)
Call DISMTools.MainForm.MountedImageDetectorBW.RunWorkerAsync()
Threading.Thread.Sleep(250)
Catch ex As Exception
DynaLog.LogMessage("Could not restart mounted image detector. Error message: " & ex.Message)
DISMTools.MainForm.MountedImageDetectorBWRestarterTimer.Enabled = True
End Try
End Sub
Private Sub SysEvts_DisplaySettingsChanged(sender As Object, e As EventArgs)
' Do nothing
End Sub
Private Sub SysEvts_DisplaySettingsChanging(sender As Object, e As EventArgs)
' Do nothing
End Sub
End Class
End Namespace