' Author: Taner Riffat
' Date Written: June 2008
Imports System.Threading
Imports System.IO
Imports System.Diagnostics.Process
Imports System.Windows
Public Class Backup
' Declare the FileCopy class. This class will create 3 threads to copy, count and mirror files
' and raise events for each, so the events must be handled to update the form with status data.
Dim WithEvents CopyFiles As FileCopy
' Declare delegate handlers for the copy, count, mirror and backup events
Public Delegate Sub CopyHandler(ByVal FilePath As String, ByVal FileSize As Long, ByVal FileCount As Long)
Public Delegate Sub CountHandler(ByVal FileCount As Long, ByVal FolderCount As Long)
Public Delegate Sub MirrorHandler(ByVal FilePath As String, ByVal FileCount As Long, ByVal FolderCount As Long)
Public Delegate Sub MirrorStartedHandler()
Public Delegate Sub BackupHandler()
Public Delegate Sub WorkingHandler()
' Private variables
Private _totalFiles As Long = 0
Private _totalFolders As Long = 0
Private _copiedFiles As Long = 0
Private _rootDir As String = ""
Private _logFile As String
Private _stopped As Boolean = False
Private _copyStatus As String = "Status: Copying and Counting. "
Private _deletedCount As Long = 0
Private Sub BrowseFrom_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BrowseFrom.Click
FolderBrowserDialog1.ShowDialog()
FromPathTextbox.Text = FolderBrowserDialog1.SelectedPath
If FromPathTextbox.Text <> "" And ToPathTextbox.Text <> "" Then
StartCopy.Enabled = True
End If
End Sub
Private Sub BrowseTo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BrowseTo.Click
FolderBrowserDialog1.ShowDialog()
ToPathTextbox.Text = FolderBrowserDialog1.SelectedPath
If FromPathTextbox.Text <> "" And ToPathTextbox.Text <> "" Then
StartCopy.Enabled = True
End If
End Sub
Private Sub StartCopy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartCopy.Click
' If mirrorcopy then warn the user.
If MirrorCopy.Checked Then
If Not WarnUser() Then Exit Sub
End If
' Reset variables
_stopped = False
' Create the FileCopy class which will initiate the threads
CopyFiles = New FileCopy
' Set parameter properties
CopyFiles.MirrorCopy = MirrorCopy.CheckState
CopyFiles.QuietLog = QuietLog.CheckState
CopyFiles.FromPath = FromPathTextbox.Text
CopyFiles.ToPath = ToPathTextbox.Text
CopyFiles.InitialMessage = "*** MODE IS WINFORMS ***"
If CopyFiles.MirrorCopy Then
CopyFiles.InitialMessage = "*** MODE IS WINFORMS - MIRROR COPY IS SET ***"
End If
If CopyFiles.QuietLog Then
CopyFiles.InitialMessage += vbCrLf & "Logging is quiet - not verbose."
Else
CopyFiles.InitialMessage += vbCrLf & "Logging is not quiet - its verbose."
End If
' Initiate the copy, count and mirror threads from the FileCopy class
CopyFiles.StartCopy()
WorkingBar.Minimum = 0
WorkingBar.Maximum = 100
WorkingLabel.Visible = True
WorkingBar.Visible = True
' Reset form controls
StartCopy.Enabled = False
Panel1.Enabled = False
StopCopy.Enabled = True
ViewLog.Enabled = True
End Sub
Private Sub StopCopy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StopCopy.Click
CopyFiles.StopThreads()
CopyFiles = Nothing
ProgressBar1.Maximum = 0
ProgressBar1.Value = 0
FileStatusTextbox.Text = ""
CopyStatusLabel.Text = "Status: Not Started"
StartCopy.Enabled = True
Panel1.Enabled = True
StopCopy.Enabled = False
WorkingLabel.Visible = False
WorkingBar.Visible = False
WorkingBar.Value = 0
_copyStatus = "Status: Copying and Counting. "
_deletedCount = 0
' Stopping threads (using abort) is, on occasion, prone to a time delay so use a flag to ensure
' any "leftover" events raised by child threads are ignored by this form (parent thread).
_stopped = True
End Sub
Private Sub CopyStatus(ByVal FilePath As String, ByVal FileSize As Long, ByVal FileCount As Long)
' Exit if the copy has been stopped (cancelled) as a child thread may still raise one last event
' due to a delay that sometimes occurs when the abort method to stop a child thread is used.
If _stopped Then Exit Sub
' Show current file
FileStatusTextbox.Text = "Copying: " & FilePath & ". Filesize is " & FileSize.ToString & " megabytes."
If MirrorCopy.Checked Then
FileStatusTextbox.Text += vbCrLf & vbCrLf & "WARNING. This is a mirror copy, it will DELETE files from the To Folder."
FileStatusTextbox.Text += "Press the Cancel Copy button now if you don't want to do a mirror copy!"
End If
' Update progressbar
If ProgressBar1.Maximum <> 0 Then ProgressBar1.Value = _totalFiles - (_totalFiles - FileCount)
End Sub
Private Sub CopyCompleted(ByVal FilePath As String, ByVal FileSize As Long, ByVal FileCount As Long)
CopyStatusLabel.Text = "Status: Copy Finsihed. Copied " + _totalFiles.ToString + " files in " + _totalFolders.ToString + " folders."
FileStatusTextbox.Text = "Copy completed successfully."
ProgressBar1.Value = ProgressBar1.Maximum
End Sub
Private Sub CountStatus(ByVal FileCount As Long, ByVal FolderCount As Long)
' Exit if the copy has been stopped (cancelled) as a child thread may still raise one last event
' due to a delay that sometimes occurs when the abort method to stop a child thread is used.
If _stopped Then Exit Sub
' Display current count
CopyStatusLabel.Text = _copyStatus & "So far there are " + FileCount.ToString + " files in " + FolderCount.ToString + " folders."
End Sub
Private Sub CountCompleted(ByVal FileCount As Long, ByVal FolderCount As Long)
' Display current count
_copyStatus = "Status: Copying. "
CopyStatusLabel.Text = _copyStatus & "There are " + FileCount.ToString + " files in " + FolderCount.ToString + " folders."
' Save totals when finished counting for CopyStatus()
_totalFiles = FileCount
_totalFolders = FolderCount
ProgressBar1.Maximum = _totalFiles
ProgressBar1.Value = 0
End Sub
Private Sub MirrorStarted()
_copyStatus = "Status: Mirroring. Counting files first."
FileStatusTextbox.Text = "No files to process just yet, please wait." & vbCrLf & vbCrLf
FileStatusTextbox.Text += "WARNING: This is a mirror copy and it will DELETE files from the To Folder! "
FileStatusTextbox.Text += "Check that your From Folder and To Folder is correct. You can prevent files from being "
FileStatusTextbox.Text += "deleted if you press the Cancel Copy button now!! "
ProgressBar1.Value = 0
End Sub
Private Sub MirrorStatus(ByVal FilePath As String, ByVal FileCount As Long, ByVal FolderCount As Long)
' Exit if the copy has been stopped (cancelled) as a child thread may still raise one last event
' due to a delay that sometimes occurs when the abort method to stop a child thread is used.
If _stopped Then Exit Sub
CopyStatusLabel.Text = "Status: Mirroring. Looking for redundant files and folders. Files left to read " + (_totalFiles - FileCount).ToString
If FilePath <> "" Then
FileStatusTextbox.Text = "Mirroring: Found and deleted file " & FilePath.ToString & " from To Folder."
_deletedCount += 1
End If
' Update progressbar
If ProgressBar1.Maximum <> 0 Then ProgressBar1.Value = _totalFiles - (_totalFiles - FileCount)
End Sub
Private Sub MirrorCompleted(ByVal FilePath As String, ByVal FolderCount As Long, ByVal FileCount As Long)
ProgressBar1.Value = ProgressBar1.Maximum
CopyStatusLabel.Text = "Mirror copy completed. Folders read " + FolderCount.ToString + ". Files read " + FileCount.ToString
FileStatusTextbox.Text = "Mirror copy deleted " & _deletedCount & " files from the " & """" & "To Folder" & """" & "."
End Sub
Private Sub BackupCompleted()
CopyStatusLabel.Text = "Backup copy completed."
CopyFiles.StopThreads()
CopyFiles = Nothing
WorkingLabel.Visible = False
WorkingBar.Visible = False
WorkingBar.Value = 0
StartCopy.Enabled = True
Panel1.Enabled = True
StopCopy.Enabled = False
End Sub
Private Sub CopyFiles_CopyStatus(ByVal sender As Object, ByVal e As BackupEventArgs) Handles CopyFiles.CopyStatus
' BeginInvoke causes asynchronous execution to begin at the address
' specified by the delegate. Simply put, it transfers execution of
' this method back to the main thread. Any parameters required by
' the method contained at the delegate are wrapped in an object and
' passed.
Me.BeginInvoke(New CopyHandler(AddressOf CopyStatus), New Object() {e.FilePath, e.FileSize, e.FileCount})
End Sub
Private Sub CopyFiles_CopyCompleted(ByVal sender As Object, ByVal e As BackupEventArgs) Handles CopyFiles.CopyCompleted
' BeginInvoke causes asynchronous execution to begin at the address
' specified by the delegate. Simply put, it transfers execution of
' this method back to the main thread. Any parameters required by
' the method contained at the delegate are wrapped in an object and
' passed.
Me.BeginInvoke(New CopyHandler(AddressOf CopyCompleted), New Object() {e.FilePath, e.FileSize, e.FileCount})
End Sub
Private Sub CopyFiles_CountStatus(ByVal sender As Object, ByVal e As BackupEventArgs) Handles CopyFiles.CountStatus
' BeginInvoke causes asynchronous execution to begin at the address
' specified by the delegate. Simply put, it transfers execution of
' this method back to the main thread. Any parameters required by
' the method contained at the delegate are wrapped in an object and
' passed.
Me.BeginInvoke(New CountHandler(AddressOf CountStatus), New Object() {e.FileCount, e.FolderCount})
End Sub
Private Sub CopyFiles_CountCompleted(ByVal sender As Object, ByVal e As BackupEventArgs) Handles CopyFiles.CountCompleted
' BeginInvoke causes asynchronous execution to begin at the address
' specified by the delegate. Simply put, it transfers execution of
' this method back to the main thread. Any parameters required by
' the method contained at the delegate are wrapped in an object and
' passed.
Me.BeginInvoke(New CountHandler(AddressOf CountCompleted), New Object() {e.FileCount, e.FolderCount})
End Sub
Private Sub CopyFiles_MirrorStarted() Handles CopyFiles.MirrorStarted
' BeginInvoke causes asynchronous execution to begin at the address
' specified by the delegate. Simply put, it transfers execution of
' this method back to the main thread. Any parameters required by
' the method contained at the delegate are wrapped in an object and
' passed.
Me.BeginInvoke(New MirrorStartedHandler(AddressOf MirrorStarted))
End Sub
Private Sub CopyFiles_MirrorStatus(ByVal sender As Object, ByVal e As BackupEventArgs) Handles CopyFiles.MirrorStatus
' BeginInvoke causes asynchronous execution to begin at the address
' specified by the delegate. Simply put, it transfers execution of
' this method back to the main thread. Any parameters required by
' the method contained at the delegate are wrapped in an object and
' passed.
Me.BeginInvoke(New MirrorHandler(AddressOf MirrorStatus), New Object() {e.FilePath, e.FileCount, e.FolderCount})
End Sub
Private Sub CopyFiles_MirrorCompleted(ByVal sender As Object, ByVal e As BackupEventArgs) Handles CopyFiles.MirrorCompleted
' BeginInvoke causes asynchronous execution to begin at the address
' specified by the delegate. Simply put, it transfers execution of
' this method back to the main thread. Any parameters required by
' the method contained at the delegate are wrapped in an object and
' passed.
Me.BeginInvoke(New MirrorHandler(AddressOf MirrorCompleted), New Object() {e.FilePath, e.FileCount, e.FolderCount})
End Sub
Private Sub CopyFiles_BackupCompleted(ByVal sender As Object, ByVal e As BackupEventArgs) Handles CopyFiles.BackupCompleted
' BeginInvoke causes asynchronous execution to begin at the address
' specified by the delegate. Simply put, it transfers execution of
' this method back to the main thread. Any parameters required by
' the method contained at the delegate are wrapped in an object and
' passed.
Me.BeginInvoke(New BackupHandler(AddressOf BackupCompleted))
End Sub
Private Sub ViewLog_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ViewLog.Click
Try
Start(_logFile)
Catch ex As System.ComponentModel.Win32Exception
MessageBox.Show("Log file has not been created because there are no errors")
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub Help_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Help.Click
Try
Process.Start("Help.pdf")
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Function WarnUser() As Boolean
' If the "Dont show this warning message again" has not been checked then MirrorWarning
' will be True, so show the mirror warning dialog
If My.Settings.MirrorWarning Then
' Show the warning dialog
Dim WarnForm As New MirrorWarning
WarnForm.ShowDialog()
If WarnForm.MirrorCopy Then
' Means the user clicked "YES" to running the mirror copy
WarnForm.Close()
Return True
Else
' Means the user clicked "NO" to running the mirror copy
WarnForm.Close()
Return False
End If
End If
' If the "Dont show this warning message again" has been checked on a previous occassion
' then return True to indicate the user has been warned and its okay to start the mirror copy.
Return True
End Function
Private Sub Backup_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.CenterToScreen()
End Sub
Private Sub CopyFiles_LogFileCreated(ByVal sender As Object, ByVal LogFileName As String) Handles CopyFiles.LogFileCreated
_logFile = LogFileName
ViewLog.Enabled = True
End Sub
'Private Sub Working_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles Working.Elapsed
' 'Me.BeginInvoke(New WorkingHandler(AddressOf WorkingStatus))
'End Sub
'Private Sub WorkingStatus()
' 'If WorkingBar.Value < 100 Then
' ' WorkingBar.Value += 10
' 'Else
' ' WorkingBar.Value = 0
' 'End If
'End Sub
End Class