88' This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY
99
1010Imports System.ComponentModel
11- Imports System.IO
1211Imports System.Runtime.CompilerServices
13- Imports System.Threading
1412Imports WinNUT_Client_Common
1513
1614Namespace Models
1715 Friend Class UpgradePrefsDialogModel
1816 Implements INotifyPropertyChanged
1917
2018 Private ReadOnly upgradeWorker As New BackgroundWorker With {
21- .WorkerReportsProgress = True
19+ .WorkerReportsProgress = True ,
20+ .WorkerSupportsCancellation = True
2221 }
2322 Private oldPrefs As OldParams.UpgradableParams
23+ Private _parentForm As Form
2424
2525# Region "Properties and backing fields"
2626
@@ -31,7 +31,7 @@ Namespace Models
3131 Private _FormEnabled As Boolean
3232 Private _FormUseWaitCursor As Boolean
3333 Private _ProgressPercent = 0
34- Private _Icon As Bitmap = My.Resources.regedit_exe_14_100_0
34+ Private _Icon As Icon
3535
3636 Public Property ImportPreviousSettigns As Boolean
3737 Get
@@ -123,18 +123,12 @@ Namespace Models
123123 End Set
124124 End Property
125125
126- Public ReadOnly Property UpgradeInProgress As Boolean
127- Get
128- Return upgradeWorker IsNot Nothing AndAlso upgradeWorker.IsBusy
129- End Get
130- End Property
131-
132- Public Property Icon As Bitmap
126+ Public Property Icon As Icon
133127 Get
134128 Return _Icon
135129 End Get
136- Private Set (value As Bitmap )
137- If Not _Icon.Equals(value) Then
130+ Private Set (value As Icon )
131+ If _Icon IsNot Nothing AndAlso Not _Icon.Equals(value) Then
138132 _Icon = value
139133 NotifyPropertyChanged()
140134 End If
@@ -143,8 +137,6 @@ Namespace Models
143137
144138# End Region
145139
146- Public Event WorkComplete As RunWorkerCompletedEventHandler
147-
148140# Region "INotifyPropertyChanged implementation"
149141
150142 ' This method is called by the Set accessor of each property.
@@ -158,25 +150,62 @@ Namespace Models
158150
159151# End Region
160152
161- Friend Sub New ()
162- FormEnabled = True
163- FormUseWaitCursor = False
164- ImportPreviousSettigns = True
165- BackupPreviousSettings = True
153+ Friend Sub New (parentForm As Form)
154+ _parentForm = parentForm
166155
167156 AddHandler upgradeWorker.DoWork, AddressOf ProcessUpgradeWork
168157 AddHandler upgradeWorker.ProgressChanged, AddressOf UpgradeProgressChanged
169158 AddHandler upgradeWorker.RunWorkerCompleted, AddressOf UpgradeWorkComplete
170159 End Sub
171160
161+ Friend Sub InitializeProperties()
162+ FormEnabled = True
163+ FormUseWaitCursor = False
164+ ImportPreviousSettigns = True
165+ BackupPreviousSettings = True
166+ Icon = My.Resources.WinNut
167+ End Sub
168+
172169 Friend Sub BeginUpgradeWorkAsync()
170+ Dim workerArgs As New UpgradeWorkerArguments()
171+
172+ If BackupPreviousSettings Then
173+ ' Capture user's backup location preference on this thread before starting background worker.
174+ Dim saveFileDialog = New SaveFileDialog() With {
175+ .FileName = "WinNUT-Prefs-Export" ,
176+ .Filter = "Windows Registry files (*.reg)|*.reg|All files (*.*)|*.*" ,
177+ .InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
178+ .Title = My.Resources.UpgradePrefsDialog_BackupLocationTitle
179+ }
180+
181+ Dim dialogRes = saveFileDialog.ShowDialog()
182+
183+ If dialogRes = DialogResult.Cancel Then
184+ LogFile.LogTracing( "User cancelled upgrade prefs process while selecting backup target." ,
185+ LogLvl.LOG_NOTICE, Me )
186+ Return
187+ End If
188+
189+ workerArgs.BackupPath = saveFileDialog.FileName
190+ End If
191+
173192 FormEnabled = False
174193 FormUseWaitCursor = True
175- upgradeWorker.RunWorkerAsync()
194+ upgradeWorker.RunWorkerAsync(workerArgs )
176195 End Sub
177196
178- Friend Sub CancelUpgradeWork()
179- upgradeWorker.CancelAsync()
197+ Friend Sub CancelButtonClicked()
198+ LogFile.LogTracing( "Handling Cancel button click..." , LogLvl.LOG_DEBUG, Me )
199+
200+ If upgradeWorker IsNot Nothing AndAlso upgradeWorker.IsBusy Then
201+ LogFile.LogTracing( "Requesting cancellation of upgradeWorker." , LogLvl.LOG_NOTICE, Me )
202+ upgradeWorker.CancelAsync()
203+ Else
204+ LogFile.LogTracing( "Exiting out of upgrade dialog." , LogLvl.LOG_NOTICE, Me )
205+ _parentForm.DialogResult = DialogResult.Cancel
206+ My.Settings.UpgradePrefsCompleted = True
207+ _parentForm.Close()
208+ End If
180209 End Sub
181210
182211 Private Sub CalculateOKButtonState( Optional sender As Object = Nothing , Optional args As PropertyChangedEventArgs = Nothing ) _
@@ -196,39 +225,64 @@ Namespace Models
196225 ''' <param name="sender"></param>
197226 ''' <param name="e"></param>
198227 Private Sub ProcessUpgradeWork(sender As Object , e As DoWorkEventArgs)
228+ Dim args As UpgradeWorkerArguments = e.Argument
229+
199230 If Not e.Cancel AndAlso ImportPreviousSettigns Then
200231 DoImportWork()
201- Thread.Sleep( 2000 )
202232 End If
203233
204234 If Not e.Cancel AndAlso BackupPreviousSettings Then
205- DoBackupWork()
206- Thread.Sleep( 2000 )
235+ DoBackupWork(args.BackupPath)
207236 End If
208237
209238 If Not e.Cancel AndAlso DeletePreviousSettings Then
210239 DoDeleteWork()
211- Thread.Sleep( 2000 )
212240 End If
213241 End Sub
214242
243+ ''' <summary>
244+ ''' Execution of <see cref="ProcessUpgradeWork(Object, DoWorkEventArgs)"/> has ended and returned to the
245+ ''' UI thread.
246+ ''' </summary>
247+ ''' <param name="sender"></param>
248+ ''' <param name="e"></param>
215249 Private Sub UpgradeWorkComplete(sender As Object , e As RunWorkerCompletedEventArgs)
216250 oldPrefs = Nothing
217251
218- If e.Cancelled Then
219- LogFile.LogTracing( "Upgrade work was cancelled." , LogLvl.LOG_WARNING, Me , My.Resources.UpgradePrefsDialog_Cancelled)
220- End If
252+ FormEnabled = True
253+ FormUseWaitCursor = False
221254
222255 If e.Error IsNot Nothing Then
223- LogFile.LogTracing( "Error encountered while doing upgrade work: " & e.Error.ToString(), LogLvl.LOG_ERROR, Me ,
224- String .Format(My.Resources.UpgradePrefsDialog_ErrorEncountered, e.Error.Message))
256+ ProgressPercent = 0
257+ Dim localError = String .Format(My.Resources.UpgradePrefsDialog_ErrorEncountered, e.Error.Message)
258+ LogFile.LogTracing( "UpgradeWorkComplete with error: " & vbNewLine & e.Error.ToString(),
259+ LogLvl.LOG_ERROR, Me , localError)
260+ MessageBox.Show(localError)
261+ Return
262+ End If
263+
264+ If e.Cancelled Then
265+ ProgressPercent = 0
266+ LogFile.LogTracing( "Upgrade work was cancelled." , LogLvl.LOG_WARNING, Me , My.Resources.UpgradePrefsDialog_Cancelled)
267+ Return
225268 End If
226269
227270 ProgressPercent = 100
228271
229- RaiseEvent WorkComplete(sender, e)
272+ My.Settings.UpgradePrefsCompleted = True
273+ _parentForm.Close()
230274 End Sub
231275
276+ ''' <summary>
277+ ''' Reports progress from within the BackgroundWorker thread, back to the calling thread.
278+ ''' WARNING: This is not a reliably quick way to synchronize information back to the calling thread.
279+ ''' From testing, the <see cref="ProcessUpgradeWork"/> routine moves much faster than the main thread.
280+ ''' </summary>
281+ ''' <param name="percentComplete"></param>
282+ ''' <param name="logMsg"></param>
283+ ''' <param name="logLevel"></param>
284+ ''' <param name="sender"></param>
285+ ''' <param name="logRes"></param>
232286 Private Sub ReportProgress(percentComplete As Integer , logMsg As String , logLevel As LogLvl, sender As Object ,
233287 Optional logRes As String = Nothing )
234288 upgradeWorker.ReportProgress(percentComplete,
@@ -289,26 +343,12 @@ Namespace Models
289343 ''' <summary>
290344 ''' Performs synchronous work to backup Registry data. Throws exceptions if any error occurs.
291345 ''' </summary>
292- Private Sub DoBackupWork()
293- ReportProgress( 0 , "Beginning backup procedure." , LogLvl.LOG_NOTICE, Me )
294-
295- Dim saveFileDialog = New SaveFileDialog() With {
296- .DefaultExt = "reg" ,
297- .FileName = "WinNUT-Prefs-Export" ,
298- .InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
299- .Title = My.Resources.UpgradePrefsDialog_BackupLocationTitle
300- }
301- Dim dialogRes = saveFileDialog.ShowDialog()
302-
303- If dialogRes = DialogResult.Cancel Then
304- Throw New InvalidOperationException( "User opted to cancel the backup file dialog." )
305- End If
306-
307- Dim fileLoc = Path.GetDirectoryName(saveFileDialog.FileName) & "\\" & saveFileDialog.FileName
308- ReportProgress( 50 , "Beginning reg export process to " & fileLoc, LogLvl.LOG_NOTICE, Me )
309- OldParams.WinNUT_Params.ExportParams(fileLoc)
346+ ''' <param name="targetPath">Full path and filename where registry items will be backed up to.</param>
347+ Private Sub DoBackupWork(targetPath As String )
348+ ReportProgress( 0 , "Beginning reg export process to " & targetPath, LogLvl.LOG_NOTICE, Me )
349+ OldParams.WinNUT_Params.ExportParams(targetPath)
310350 ReportProgress( 100 , "reg export process exited. Backup complete." , LogLvl.LOG_NOTICE, Me ,
311- String .Format(My.Resources.UpgradePrefsDialog_BackupProcedureCompleted, fileLoc ))
351+ String .Format(My.Resources.UpgradePrefsDialog_BackupProcedureCompleted, targetPath ))
312352 End Sub
313353
314354 Private Sub DoDeleteWork()
@@ -334,6 +374,10 @@ Namespace Models
334374 End Sub
335375 End Class
336376
377+ Private Class UpgradeWorkerArguments
378+ Public Property BackupPath As String
379+ End Class
380+
337381 End Class
338382
339383End Namespace
0 commit comments