Files
GBM/GBM/Forms/frmMain.vb
Michael J. Seiferling 19802a5883 Updated for issue 25
2015-12-09 12:00:10 -06:00

1505 lines
56 KiB
VB.net

'Name: frmMain
'Description: Game Backup Monitor Main Screen
'Author: Michael J. Seiferling
Public Class frmMain
'Used to denote the current status of the app
Private Enum eStatus As Integer
Running = 1
Paused = 2
Stopped = 3
End Enum
'Used to denote the currently running operation
Private Enum eOperation As Integer
None = 1
Backup = 2
Restore = 3
End Enum
Private iProcessType As System.Reflection.ProcessorArchitecture = System.Reflection.AssemblyName.GetAssemblyName(Application.ExecutablePath()).ProcessorArchitecture
Private sVersion As String = "Version: " & My.Application.Info.Version.Major & "." & _
My.Application.Info.Version.Minor & " Beta (" & [Enum].GetName(GetType(System.Reflection.ProcessorArchitecture), iProcessType) & ")"
Private sRevision As String = "Build: " & My.Application.Info.Version.Build & "." & My.Application.Info.Version.Revision
Const sConstCopyright As String = "2015 Michael J. Seiferling"
Private eCurrentStatus As eStatus = eStatus.Stopped
Private eCurrentOperation As eOperation = eOperation.None
Private bCancelledByUser As Boolean = False
Private bShutdown As Boolean = False
Private bMenuEnabled As Boolean = True
Private bLockdown As Boolean = True
Private bFirstRun As Boolean = False
Private bProcessIsAdmin As Boolean = False
Private bLogToggle As Boolean = False
Private bAllowIcon As Boolean = False
Private bAllowDetails As Boolean = False
Private oPriorImage As Image
Private sPriorPath As String
Private sPriorCompany As String
Private sPriorVersion As String
WithEvents oFileWatcher As New System.IO.FileSystemWatcher
WithEvents tmScanTimer As New Timer
Public WithEvents oProcess As New mgrProcesses
Public WithEvents oBackup As New mgrBackup
Public WithEvents oRestore As New mgrRestore
Public hshScanList As Hashtable
Public oSettings As New mgrSettings
Delegate Sub UpdateLogCallBack(ByVal sLogUpdate As String, ByVal bTrayUpdate As Boolean, ByVal objIcon As System.Windows.Forms.ToolTipIcon, ByVal bTimeStamp As Boolean)
Delegate Sub WorkingGameInfoCallBack(ByVal sTitle As String, ByVal sStatus1 As String, ByVal sStatus2 As String, ByVal sStatus3 As String)
Delegate Sub UpdateStatusCallBack(ByVal sStatus As String)
Delegate Sub SetLastActionCallBack(ByVal sString As String)
Delegate Sub OperationEndedCallBack()
Delegate Sub RestoreCompletedCallBack()
'Handlers
Private Sub SetLastAction(ByVal sMessage As String) Handles oBackup.SetLastAction, oRestore.SetLastAction
'Thread Safe
If lblLastAction.InvokeRequired = True Then
Dim d As New SetLastActionCallBack(AddressOf SetLastAction)
Me.Invoke(d, New Object() {sMessage})
Else
Dim sPattern As String = "h:mm tt"
lblLastActionTitle.Visible = True
lblLastAction.Text = sMessage & " at " & TimeOfDay.ToString(sPattern)
End If
End Sub
Private Sub SetRestoreInfo(ByVal oRestoreInfo As clsBackup) Handles oRestore.UpdateRestoreInfo
Dim sStatus1 As String
Dim sStatus2 As String
Dim sStatus3 As String
'Build Info
sStatus1 = IO.Path.GetFileName(oRestoreInfo.FileName)
sStatus2 = "Updated by " & oRestoreInfo.UpdatedBy & " on " & oRestoreInfo.DateUpdated
If oRestoreInfo.AbsolutePath Then
sStatus3 = oRestoreInfo.RestorePath
Else
sStatus3 = oRestoreInfo.RelativeRestorePath
End If
WorkingGameInfo("Restore in progress...", sStatus1, sStatus2, sStatus3)
UpdateStatus("Restore in progress...")
End Sub
Private Sub SetBackupInfo(ByVal oGame As clsGame) Handles oBackup.UpdateBackupInfo
Dim sStatus1 As String
Dim sStatus2 As String
Dim sStatus3 As String
'Build Info
sStatus1 = oGame.CroppedName
If oGame.AbsolutePath Then
sStatus2 = oGame.Path
Else
sStatus2 = oGame.ProcessPath & "\" & oGame.Path
End If
sStatus3 = String.Empty
WorkingGameInfo("Backup in Progress...", sStatus1, sStatus2, sStatus3)
UpdateStatus("Backup in progress...")
End Sub
Private Sub OperationStarted(Optional ByVal bPause As Boolean = True)
'Thread Safe
If Me.InvokeRequired = True Then
Dim d As New OperationEndedCallBack(AddressOf OperationEnded)
Me.Invoke(d, New Object() {})
Else
btnCancelOperation.Visible = True
LockDownMenuEnable()
If bPause Then PauseScan()
End If
End Sub
Private Sub OperationEnded(Optional ByVal bResume As Boolean = True)
'Thread Safe
If Me.InvokeRequired = True Then
Dim d As New OperationEndedCallBack(AddressOf OperationEnded)
Me.Invoke(d, New Object() {})
Else
ResetGameInfo(True)
btnCancelOperation.Visible = False
btnCancelOperation.Enabled = True
eCurrentOperation = eOperation.None
LockDownMenuEnable()
If bResume Then ResumeScan()
End If
End Sub
Private Sub OperationCancel()
Select Case eCurrentOperation
Case eOperation.None
'Nothing
Case eOperation.Backup
oBackup.CancelOperation = True
btnCancelOperation.Enabled = False
Case eOperation.Restore
oRestore.CancelOperation = True
btnCancelOperation.Enabled = False
End Select
End Sub
Private Sub ExecuteBackup(ByVal oBackupList As List(Of clsGame))
'Init Backup Settings
oBackup.Settings = oSettings
oBackup.DoBackup(oBackupList)
OperationEnded()
End Sub
Private Sub ExecuteRestore(ByVal oRestoreList As List(Of clsBackup))
'Init Restore Settings
oRestore.Settings = oSettings
oRestore.DoRestore(oRestoreList)
OperationEnded()
End Sub
Private Sub RunRestore(ByVal oRestoreList As List(Of clsGame))
Dim oBackupData As SortedList = mgrManifest.ReadManifest(mgrSQLite.Database.Remote)
Dim oGame As clsGame
Dim oReadyList As New List(Of clsBackup)
Dim oRestoreInfo As clsBackup
Dim bTriggerReload As Boolean = False
eCurrentOperation = eOperation.Restore
OperationStarted()
'Build Restore List
For Each oGame In oRestoreList
oRestoreInfo = oBackupData(oGame.Name)
If mgrRestore.CheckPath(oRestoreInfo, oGame, bTriggerReload) Then
oReadyList.Add(oRestoreInfo)
Else
UpdateLog(oRestoreInfo.Name & " restore was cancelled due to a restore path issue.", False, ToolTipIcon.Error, True)
End If
Next
'Reload the monitor list if any game data was changed during the path checks
If bTriggerReload Then LoadGameSettings()
'Run restores
If oReadyList.Count > 0 Then
Dim oThread As New System.Threading.Thread(AddressOf ExecuteRestore)
oThread.IsBackground = True
oThread.Start(oReadyList)
Else
OperationEnded()
End If
End Sub
Private Sub RunManualBackup(ByVal oBackupList As List(Of clsGame))
Dim oGame As clsGame
Dim bNoAuto As Boolean
Dim oReadyList As New List(Of clsGame)
eCurrentOperation = eOperation.Backup
OperationStarted()
'Build Backup List
For Each oGame In oBackupList
bNoAuto = False
gMonStripStatusButton.Enabled = False
UpdateLog("A manaul backup of " & oGame.Name & " was triggered.", False)
If oGame.AbsolutePath = False Then
If oGame.ProcessPath = String.Empty Then
If mgrCommon.IsProcessNotSearchable(oGame) Then bNoAuto = True
oGame.ProcessPath = mgrPath.ProcessPathSearch(oGame.Name, oGame.TrueProcess, oGame.Name & " uses a relative path and has never been detected on this computer.", bNoAuto)
End If
If oGame.ProcessPath <> String.Empty Then
oReadyList.Add(oGame)
Else
UpdateLog(oGame.Name & " backup was cancelled due to unknown path.", True, ToolTipIcon.Error, True)
End If
Else
oReadyList.Add(oGame)
End If
Next
'Run backups
If oReadyList.Count > 0 Then
Dim oThread As New System.Threading.Thread(AddressOf ExecuteBackup)
oThread.IsBackground = True
oThread.Start(oReadyList)
Else
OperationEnded()
End If
End Sub
Private Function DoMultiGameCheck() As Boolean
Dim oResult As DialogResult
If oProcess.Duplicate = True Then
Dim frm As New frmChooseGame
frm.Process = oProcess
oResult = frm.ShowDialog()
If oResult = DialogResult.OK Then
Dim sProcessPath As String
'Reload settings
LoadGameSettings()
'Retain the process path from old object
sProcessPath = oProcess.GameInfo.ProcessPath
oProcess.GameInfo = frm.Game
'Set the process path into the new object
oProcess.GameInfo.ProcessPath = sProcessPath
'A game was set, return and continue
Return True
Else
'No game was set, return to cancel
Return False
End If
Else
'The game is not a duplicate, return and continue
Return True
End If
End Function
Private Sub RunBackup()
Dim bDoBackup As Boolean
Dim oReadyList As New List(Of clsGame)
eCurrentOperation = eOperation.Backup
OperationStarted(False)
If SupressBackup() Then
bDoBackup = False
UpdateLog(oProcess.GameInfo.Name & " backup was cancelled due to session length.", False)
SetLastAction(oProcess.GameInfo.CroppedName & " backup was cancelled due to session length")
OperationEnded()
Else
If oProcess.GameInfo.MonitorOnly = False Then
If oSettings.DisableConfirmation Then
bDoBackup = True
Else
If MsgBox("Do you wish to backup data from " & oProcess.GameInfo.Name & "?", MsgBoxStyle.YesNo, "Game Backup Monitor") = MsgBoxResult.Yes Then
bDoBackup = True
Else
bDoBackup = False
UpdateLog(oProcess.GameInfo.Name & " backup was cancelled.", False)
SetLastAction(oProcess.GameInfo.CroppedName & " backup was cancelled")
OperationEnded()
End If
End If
Else
bDoBackup = False
UpdateLog(oProcess.GameInfo.Name & " is set to monitor only.", False)
SetLastAction(oProcess.GameInfo.CroppedName & " monitoring ended")
OperationEnded()
End If
End If
If bDoBackup Then
'Run the backup
oReadyList.Add(oProcess.GameInfo)
Dim trd As New System.Threading.Thread(AddressOf ExecuteBackup)
trd.IsBackground = True
trd.Start(oReadyList)
End If
End Sub
Private Sub CheckRestore()
Dim slRestoreData As SortedList = mgrRestore.CompareManifests()
Dim sNotification As String
If slRestoreData.Count > 0 Then
If slRestoreData.Count > 1 Then
sNotification = slRestoreData.Count & " Games Pending Restore"
Else
sNotification = slRestoreData.Count & " Game Pending Restore"
End If
gMonNotification.Image = My.Resources.Inbox
gMonTrayNotification.Image = My.Resources.Inbox
gMonNotification.Text = sNotification
gMonTrayNotification.Text = sNotification
gMonNotification.Visible = True
gMonTrayNotification.Visible = True
End If
End Sub
'Functions to handle monitor list features
Private Sub ImportMonitorList()
Dim sLocation As String
PauseScan()
sLocation = mgrCommon.OpenFileBrowser("Choose a valid xml file to import", "xml", "XML", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), False)
If sLocation <> String.Empty Then
If mgrMonitorList.DoImport(sLocation) Then
LoadGameSettings()
If oSettings.Sync Then mgrMonitorList.SyncMonitorLists()
End If
End If
ResumeScan()
End Sub
Private Sub ExportMonitorList()
Dim sLocation As String
PauseScan()
sLocation = mgrCommon.SaveFileBrowser("Choose a location for the export file", "xml", "XML", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Game Backup Monitor Export " & Date.Now.ToString("dd-MMM-yyyy"))
If sLocation <> String.Empty Then
mgrMonitorList.ExportMonitorList(sLocation)
End If
ResumeScan()
End Sub
Private Sub DownloadOfficialList()
PauseScan()
If MsgBox("Would you like to import from the latest pre-configured game list?", MsgBoxStyle.YesNo, "Game Backup Monitor") = MsgBoxResult.Yes Then
If mgrMonitorList.DoImport(mgrPath.OfficialImportURL) Then
LoadGameSettings()
If oSettings.Sync Then mgrMonitorList.SyncMonitorLists()
End If
End If
ResumeScan()
End Sub
'Functions handling the display of game information
Private Sub SetIcon()
Dim sIcon As String
Dim fbBrowser As New OpenFileDialog
fbBrowser.Title = "Choose icon for " & oProcess.GameInfo.Name
fbBrowser.DefaultExt = "ico"
fbBrowser.Filter = "Icon files (*.ico)|*.ico"
Try
fbBrowser.InitialDirectory = IO.Path.GetDirectoryName(oProcess.FoundProcess.MainModule.FileName)
Catch ex As Exception
fbBrowser.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
End Try
fbBrowser.Multiselect = False
If fbBrowser.ShowDialog() = Windows.Forms.DialogResult.OK Then
sIcon = fbBrowser.FileName
If IO.File.Exists(sIcon) Then
oProcess.GameInfo.Icon = sIcon
pbIcon.Image = Image.FromFile(sIcon)
mgrMonitorList.DoListUpdate(oProcess.GameInfo)
End If
End If
End Sub
Private Sub ResetGameInfo(Optional ByVal bKeepInfo As Boolean = False)
If bKeepInfo And Not oProcess.GameInfo Is Nothing Then
lblGameTitle.Text = "Last Game: " & oProcess.GameInfo.CroppedName
pbIcon.Image = oPriorImage
lblStatus1.Text = sPriorPath
lblStatus2.Text = sPriorCompany
lblStatus3.Text = sPriorVersion
If oSettings.TimeTracking Then
lblTimeTitle.Visible = True
lblTimeSpent.Visible = True
End If
Else
pbIcon.Image = My.Resources.Searching
lblGameTitle.Text = "No Game Detected"
lblStatus1.Text = String.Empty
lblStatus2.Text = String.Empty
lblStatus3.Text = String.Empty
lblTimeTitle.Visible = False
lblTimeSpent.Visible = False
End If
If eCurrentStatus = eStatus.Stopped Then
UpdateStatus("Not Scanning")
Else
UpdateStatus("No Game Detected")
End If
End Sub
Private Sub WorkingGameInfo(ByVal sTitle As String, ByVal sStatus1 As String, ByVal sStatus2 As String, ByVal sStatus3 As String)
'Thread Safe (If one control requires an invoke assume they all do)
If pbIcon.InvokeRequired = True Then
Dim d As New WorkingGameInfoCallBack(AddressOf WorkingGameInfo)
Me.Invoke(d, New Object() {sTitle, sStatus1, sStatus2, sStatus3})
Else
lblTimeTitle.Visible = False
lblTimeSpent.Visible = False
pbIcon.Image = My.Resources.Working
lblGameTitle.Text = sTitle
lblStatus1.Text = sStatus1
lblStatus2.Text = sStatus2
lblStatus3.Text = sStatus3
End If
End Sub
Private Sub SetGameInfo(Optional ByVal bMulti As Boolean = False)
Dim sFileName As String = String.Empty
Dim sFileVersion As String = String.Empty
Dim sCompanyName As String = String.Empty
'Wipe Game Info
lblStatus1.Text = String.Empty
lblStatus2.Text = String.Empty
lblStatus3.Text = String.Empty
'Get Game Details
If bMulti Then
bAllowIcon = False
bAllowDetails = False
lblGameTitle.Text = "Multiple Games"
lblTimeTitle.Visible = False
lblTimeSpent.Visible = False
pbIcon.Image = My.Resources.Unknown
lblStatus1.Text = "Game details are unavailable."
Else
bAllowIcon = True
bAllowDetails = True
lblGameTitle.Text = oProcess.GameInfo.CroppedName
Try
Dim ic As Icon = System.Drawing.Icon.ExtractAssociatedIcon(oProcess.FoundProcess.MainModule.FileName)
pbIcon.Image = ic.ToBitmap
'Set Game Details
sFileName = oProcess.FoundProcess.MainModule.FileName
sFileVersion = oProcess.FoundProcess.MainModule.FileVersionInfo.FileVersion
sCompanyName = oProcess.FoundProcess.MainModule.FileVersionInfo.CompanyName
Catch ex As Exception
pbIcon.Image = My.Resources.Unknown
End Try
'Check for a custom icon & details
If IO.File.Exists(oProcess.GameInfo.Icon) Then
pbIcon.Image = Image.FromFile(oProcess.GameInfo.Icon)
End If
If sFileName = String.Empty Then
If oProcess.GameInfo.ProcessPath <> String.Empty Then
sFileName = oProcess.GameInfo.ProcessPath & " (Executable Path)"
End If
End If
If oProcess.GameInfo.Version <> String.Empty Then
sFileVersion = oProcess.GameInfo.Version
End If
If oProcess.GameInfo.Company <> String.Empty Then
sCompanyName = oProcess.GameInfo.Company
End If
'Do Time Update
If oSettings.TimeTracking Then
UpdateTimeSpent(oProcess.GameInfo.Hours, 0)
Else
lblTimeTitle.Visible = False
lblTimeSpent.Visible = False
End If
'Set Details
If sFileName = String.Empty Then
lblStatus1.Text = "N/A"
Else
lblStatus1.Text = sFileName
End If
If sCompanyName = String.Empty Then
lblStatus2.Text = "N/A"
Else
lblStatus2.Text = sCompanyName
End If
If sFileVersion = String.Empty Then
lblStatus3.Text = "N/A"
Else
lblStatus3.Text = sFileVersion
End If
End If
'Set Prior Info
oPriorImage = pbIcon.Image
sPriorPath = lblStatus1.Text
sPriorCompany = lblStatus2.Text
sPriorVersion = lblStatus3.Text
End Sub
Private Sub UpdateTimeSpent(ByVal dTotalTime As Double, ByVal dSessionTime As Double)
Dim sTotalTime As String
Dim sSessionTime As String
If dTotalTime < 1 Then
sTotalTime = Math.Round((dTotalTime * 100) * 0.6) & " minutes [Total]"
Else
sTotalTime = Math.Round(dTotalTime, 1) & " hours [Total]"
End If
If dSessionTime < 1 Then
sSessionTime = Math.Round((dSessionTime * 100) * 0.6) & " minutes [Session]"
Else
sSessionTime = Math.Round(dSessionTime, 1) & " hours [Session]"
End If
If dSessionTime > 0 Then
lblTimeSpent.Text = sSessionTime & " | " & sTotalTime
Else
lblTimeSpent.Text = sTotalTime
End If
lblTimeTitle.Visible = True
lblTimeSpent.Visible = True
End Sub
Private Sub HandleTimeSpent()
Dim dCurrentHours As Double
If oProcess.GameInfo.Hours > 0 Then
dCurrentHours = oProcess.GameInfo.Hours
dCurrentHours = dCurrentHours + oProcess.TimeSpent.TotalHours
Else
dCurrentHours = oProcess.TimeSpent.TotalHours
End If
oProcess.GameInfo.Hours = Math.Round(dCurrentHours, 5)
'Update original object with the new hours without reloading entire list.
If hshScanList.Contains(oProcess.GameInfo.ProcessName) Then
DirectCast(hshScanList.Item(oProcess.GameInfo.ProcessName), clsGame).Hours = oProcess.GameInfo.Hours
End If
mgrMonitorList.DoListUpdate(oProcess.GameInfo)
If oSettings.Sync Then mgrMonitorList.SyncMonitorLists()
UpdateTimeSpent(dCurrentHours, oProcess.TimeSpent.TotalHours)
End Sub
Private Function SupressBackup() As Boolean
Dim iSession As Integer
If oSettings.SupressBackup Then
iSession = Math.Ceiling(oProcess.TimeSpent.TotalMinutes)
If iSession > oSettings.SupressBackupThreshold Then
Return False
Else
Return True
End If
Else
Return False
End If
End Function
'Functions handling the opening of other windows
Private Sub OpenAbout()
MsgBox("Game Backup Monitor" & vbCrLf & sVersion & vbCrLf & sRevision & vbCrLf & Chr(169) & sConstCopyright & vbCrLf & vbCrLf &
"This program comes with ABSOLUTELY NO WARRANTY." & vbCrLf &
"This is free software, and you are welcome to redistribute it under certain conditions." & vbCrLf & vbCrLf &
"See gpl-3.0.html in the program folder for details.", MsgBoxStyle.Information, "Game Backup Monitor")
End Sub
Private Sub OpenTags()
Dim frm As New frmTags
PauseScan()
frm.ShowDialog()
If oSettings.Sync Then mgrMonitorList.SyncMonitorLists()
ResumeScan()
End Sub
Private Sub OpenGameManager(Optional ByVal bPendingRestores As Boolean = False)
Dim frm As New frmGameManager
PauseScan()
frm.BackupFolder = oSettings.BackupFolder
frm.PendingRestores = bPendingRestores
frm.ShowDialog()
LoadGameSettings()
If oSettings.Sync Then mgrMonitorList.SyncMonitorLists()
ResumeScan()
'Handle backup trigger
If frm.TriggerBackup Then
RunManualBackup(frm.BackupList)
End If
'Handle restore trigger
If frm.TriggerRestore Then
RunRestore(frm.RestoreList)
End If
End Sub
Private Sub OpenSettings()
Dim frm As New frmSettings
frm.Settings = oSettings
PauseScan()
If frm.ShowDialog() = Windows.Forms.DialogResult.OK Then
oSettings = frm.Settings
'Set Remote Database Location
mgrPath.RemoteDatabaseLocation = oSettings.BackupFolder
SetupSyncWatcher()
LoadGameSettings()
End If
ResumeScan()
End Sub
Private Sub OpenGameWizard()
Dim frm As New frmAddWizard
PauseScan()
frm.GameData = mgrMonitorList.ReadList(mgrMonitorList.eListTypes.FullList)
frm.ShowDialog()
LoadGameSettings()
If oSettings.Sync Then mgrMonitorList.SyncMonitorLists()
ResumeScan()
End Sub
Private Sub OpenCustomVariables()
Dim frm As New frmVariableManager
PauseScan()
frm.ShowDialog()
mgrPath.CustomVariablesReload()
If oSettings.Sync Then mgrMonitorList.SyncMonitorLists()
ResumeScan()
End Sub
Private Sub OpenStartupWizard()
Dim frm As New frmStartUpWizard()
frm.Settings = oSettings
PauseScan()
frm.ShowDialog()
LoadAndVerify()
bFirstRun = False
ResumeScan()
End Sub
Private Sub OpenWebSite()
Process.Start(mgrPath.OfficialWebURL)
End Sub
Private Sub OpenOnlineManual()
Process.Start(mgrPath.OfficialManualURL)
End Sub
Private Sub OpenCheckforUpdates()
Process.Start(mgrPath.OfficialUpdatesURL)
End Sub
Private Sub CheckForNewBackups()
If oSettings.RestoreOnLaunch Then
CheckRestore()
End If
End Sub
'Functions handling the loading/sync of settings
Private Sub LoadGameSettings()
'Load Monitor List
hshScanList = mgrMonitorList.ReadList(mgrMonitorList.eListTypes.ScanList)
UpdateLog("Game List (" & hshScanList.Keys.Count & ") Loaded.", False)
End Sub
Private Sub StartSyncWatcher()
If oSettings.Sync Then
oFileWatcher.EnableRaisingEvents = True
End If
End Sub
Private Sub StopSyncWatcher()
If oSettings.Sync Then
oFileWatcher.EnableRaisingEvents = False
End If
End Sub
Private Sub SetupSyncWatcher()
If oSettings.Sync Then
oFileWatcher.Path = oSettings.BackupFolder
oFileWatcher.Filter = "gbm.s3db"
oFileWatcher.NotifyFilter = IO.NotifyFilters.LastWrite
End If
End Sub
Private Sub HandleSyncWatcher() Handles oFileWatcher.Changed
If oSettings.Sync Then
UpdateLog("The master game list has been changed by a program other than GBM.", False, ToolTipIcon.Info, True)
SyncGameSettings()
LoadGameSettings()
CheckForNewBackups()
End If
End Sub
Private Sub SyncGameSettings()
'Sync Monitor List
If oSettings.Sync Then mgrMonitorList.SyncMonitorLists(False)
End Sub
Private Sub LocalDatabaseCheck()
Dim oLocalDatabase As New mgrSQLite(mgrSQLite.Database.Local)
oLocalDatabase.DatabaseUpgrade()
End Sub
Private Sub RemoteDatabaseCheck()
Dim oRemoteDatabase As New mgrSQLite(mgrSQLite.Database.Remote)
oRemoteDatabase.DatabaseUpgrade()
End Sub
Private Sub LoadAndVerify()
'The application cannot continue if this fails
If Not oBackup.CheckForUtilities(mgrPath.Utility7zLocation) Then
MsgBox("7-Zip was not found in the Game Backup Monitor utilities folder. The application cannot continue.", MsgBoxStyle.Critical, "Game Backup Monitor")
bShutdown = True
Me.Close()
End If
'Local Database Check
VerifyDBVersion(mgrSQLite.Database.Local)
LocalDatabaseCheck()
'Load Settings
oSettings.LoadSettings()
If Not bFirstRun Then
'The application cannot continue if this fails
If Not VerifyBackupLocation() Then
bShutdown = True
Me.Close()
End If
'Remote Database Check
VerifyDBVersion(mgrSQLite.Database.Remote)
RemoteDatabaseCheck()
'Sync Game Settings
SyncGameSettings()
End If
'Setup Sync Watcher
SetupSyncWatcher()
'Load Game Settings
LoadGameSettings()
'Verify the "Start with Windows" setting
If oSettings.StartWithWindows Then
If Not VerifyStartWithWindows() Then
UpdateLog("GBM is running from a new location, the Windows startup entry has been updated.", False, ToolTipIcon.Info)
End If
End If
End Sub
'Functions that handle buttons, menus and other GUI features on this form
Private Sub ToggleLog()
If bLogToggle = False Then
txtLog.Visible = True
Me.Size = New System.Drawing.Size(540, 410)
bLogToggle = True
btnLogToggle.Text = "Hide &Log"
txtLog.Select(txtLog.TextLength, 0)
txtLog.ScrollToCaret()
Else
txtLog.Visible = False
Me.Size = New System.Drawing.Size(540, 225)
bLogToggle = False
btnLogToggle.Text = "Show &Log"
End If
End Sub
Private Sub ToggleState()
'Toggle State with Tray Clicks
If Me.WindowState = FormWindowState.Minimized Then
Me.Visible = True
Me.ShowInTaskbar = True
Me.WindowState = FormWindowState.Normal
Me.Focus()
Else
Me.Visible = False
Me.ShowInTaskbar = False
Me.WindowState = FormWindowState.Minimized
End If
End Sub
Private Sub ScanToggle()
Select Case eCurrentStatus
Case eStatus.Running
HandleScan()
Case eStatus.Paused
Dim sGame As String = oProcess.GameInfo.Name
If bProcessIsAdmin Then
MsgBox(sGame & " is running as Administrator and GBM is not." &
vbCrLf & "You cannot cancel monitoring at this time." _
& vbCrLf & vbCrLf & "Run GBM as Administrator to prevent this issue.", MsgBoxStyle.Exclamation, "Game Backup Monitor")
RestartAsAdmin()
Exit Sub
End If
If oProcess.Duplicate Then
sGame = "the unknown game"
End If
If MsgBox("Do you wish to cancel the monitoring of " & sGame & "?" & vbCrLf & vbCrLf & "Warning: When monitoring is cancelled, session time is NOT saved.", MsgBoxStyle.YesNo, "Game Backup Monitor") = MsgBoxResult.Yes Then
UpdateLog("Monitoring of " & sGame & " was cancelled.", False)
SetLastAction("Monitoring of " & oProcess.GameInfo.CroppedName & " was cancelled")
bwMonitor.CancelAsync()
StopScan()
If oProcess.Duplicate Then
ResetGameInfo()
Else
ResetGameInfo(True)
End If
End If
Case eStatus.Stopped
HandleScan()
End Select
End Sub
Private Sub ShutdownApp(Optional ByVal bPrompt As Boolean = True)
Dim bClose As Boolean = False
If bPrompt Then
If MsgBox("Are you sure you want to exit? Your games will no longer be monitored.", MsgBoxStyle.YesNo, "Game Backup Monitor") = MsgBoxResult.Yes Then
bClose = True
End If
Else
bClose = True
End If
If bClose Then
'Close Application
bShutdown = True
tmScanTimer.Stop()
If bwMonitor.IsBusy() Then bwMonitor.CancelAsync()
Me.Close()
End If
End Sub
Private Sub ToggleMenuItems(ByVal bEnable As Boolean, ByVal oDropDownItems As ToolStripMenuItem)
'Control names are exempt from being disabled
Dim sExempt() As String = {"gMonFileMonitor", "gMonFileExit"}
Dim oExempt As New List(Of String)(sExempt)
For Each mi As Object In oDropDownItems.DropDownItems
If mi.GetType().Equals(GetType(ToolStripMenuItem)) Then
mi = DirectCast(mi, ToolStripMenuItem)
If Not oExempt.Contains(mi.Name) Then
mi.Enabled = bEnable
End If
End If
Next
End Sub
Private Sub LockDownMenuEnable()
If bLockdown Then
gMonStripStatusButton.Enabled = False
gMonFileMonitor.Enabled = False
gMonFileExit.Enabled = False
gMonTrayMon.Enabled = False
gMonTrayExit.Enabled = False
bLockdown = False
Else
gMonStripStatusButton.Enabled = True
gMonFileMonitor.Enabled = True
gMonFileExit.Enabled = True
gMonTrayMon.Enabled = True
gMonTrayExit.Enabled = True
bLockdown = True
End If
End Sub
Private Sub ToggleMenuEnable()
If bMenuEnabled Then
ToggleMenuItems(False, gMonFile)
ToggleMenuItems(False, gMonSetup)
ToggleMenuItems(False, gMonSetupAddWizard)
ToggleMenuItems(False, gMonHelp)
ToggleMenuItems(False, gMonTools)
ToggleMenuItems(False, gMonTraySetup)
ToggleMenuItems(False, gMonTrayTools)
gMonTraySettings.Enabled = False
bMenuEnabled = False
Else
ToggleMenuItems(True, gMonFile)
ToggleMenuItems(True, gMonSetup)
ToggleMenuItems(True, gMonSetupAddWizard)
ToggleMenuItems(True, gMonHelp)
ToggleMenuItems(True, gMonTools)
ToggleMenuItems(True, gMonTraySetup)
ToggleMenuItems(True, gMonTrayTools)
gMonTraySettings.Enabled = True
bMenuEnabled = True
End If
End Sub
Private Sub ToggleMenuText()
Select Case eCurrentStatus
Case eStatus.Running
gMonFileMonitor.Text = "Stop &Monitoring"
gMonTrayMon.Text = "Stop &Monitoring"
Case eStatus.Stopped
gMonFileMonitor.Text = "Start &Monitoring"
gMonTrayMon.Text = "Start &Monitoring"
Case eStatus.Paused
gMonFileMonitor.Text = "Cancel &Monitoring"
gMonTrayMon.Text = "Cancel &Monitoring"
End Select
End Sub
Public Sub UpdateStatus(sStatus As String)
'Thread Safe (If one control requires an invoke assume they all do)
If gMonStatusStrip.InvokeRequired = True Then
Dim d As New UpdateStatusCallBack(AddressOf UpdateStatus)
Me.Invoke(d, New Object() {sStatus})
Else
gMonStripTxtStatus.Text = sStatus
gMonTray.Text = sStatus
End If
End Sub
Public Sub UpdateLog(sLogUpdate As String, Optional bTrayUpdate As Boolean = True, Optional objIcon As System.Windows.Forms.ToolTipIcon = ToolTipIcon.Info, Optional bTimeStamp As Boolean = True) Handles oBackup.UpdateLog, oRestore.UpdateLog
'Thread Safe (If one control requires an invoke assume they all do)
If txtLog.InvokeRequired = True Then
Dim d As New UpdateLogCallBack(AddressOf UpdateLog)
Me.Invoke(d, New Object() {sLogUpdate, bTrayUpdate, objIcon, bTimeStamp})
Else
'Clear the log if we are approaching the limit
If txtLog.TextLength > 32000 Then
txtLog.Text = String.Empty
End If
'We shouldn't allow any one message to be greater than 255 characters if that same message is pushed to the tray icon
If sLogUpdate.Length > 255 And bTrayUpdate Then
sLogUpdate = sLogUpdate.Substring(0, 252) & "..."
End If
If txtLog.Text <> String.Empty Then
txtLog.AppendText(vbCrLf)
End If
If bTimeStamp Then
txtLog.AppendText("[" & Date.Now & "] " & sLogUpdate)
Else
txtLog.AppendText(sLogUpdate)
End If
txtLog.Select(txtLog.TextLength, 0)
txtLog.ScrollToCaret()
gMonTray.BalloonTipText = sLogUpdate
gMonTray.BalloonTipIcon = objIcon
If bTrayUpdate Then gMonTray.ShowBalloonTip(5000)
End If
Application.DoEvents()
End Sub
Private Sub SetForm()
If mgrCommon.IsElevated Then
gMonStripAdminButton.Image = My.Resources.Admin
gMonStripAdminButton.ToolTipText = "GBM is running with Administrator privileges."
Else
gMonStripAdminButton.Image = My.Resources.User
gMonStripAdminButton.ToolTipText = "GBM is running with normal privileges. Click to restart as Administrator."
End If
btnCancelOperation.Visible = False
txtLog.Visible = False
lblLastActionTitle.Visible = False
lblLastAction.Text = String.Empty
Me.Size = New System.Drawing.Size(540, 225)
AddHandler mgrMonitorList.UpdateLog, AddressOf UpdateLog
ResetGameInfo()
End Sub
'Functions that control the scanning for games
Private Sub StartScan()
tmScanTimer.Interval = 5000
tmScanTimer.Start()
End Sub
Private Sub HandleScan()
If eCurrentStatus = eStatus.Running Then
StopSyncWatcher()
tmScanTimer.Stop()
eCurrentStatus = eStatus.Stopped
UpdateStatus("Not Scanning")
gMonStripStatusButton.Image = My.Resources.Stopped
gMonTray.Icon = My.Resources.GBM_Tray_Stopped
Else
StartScan()
StartSyncWatcher()
eCurrentStatus = eStatus.Running
UpdateStatus("No Game Detected")
gMonStripStatusButton.Image = My.Resources.Ready
gMonTray.Icon = My.Resources.GBM_Tray_Ready
End If
ToggleMenuText()
End Sub
Private Sub PauseScan()
If eCurrentStatus = eStatus.Running Then
StopSyncWatcher()
tmScanTimer.Stop()
eCurrentStatus = eStatus.Paused
UpdateStatus("Not Scanning")
gMonStripStatusButton.Image = My.Resources.Detected
gMonTray.Icon = My.Resources.GBM_Tray_Detected
End If
ToggleMenuText()
ToggleMenuEnable()
End Sub
Private Sub ResumeScan()
If eCurrentStatus = eStatus.Running Or eCurrentStatus = eStatus.Paused Then
StartScan()
StartSyncWatcher()
eCurrentStatus = eStatus.Running
gMonStripStatusButton.Image = My.Resources.Ready
gMonTray.Icon = My.Resources.GBM_Tray_Ready
UpdateStatus("No Game Detected")
End If
ToggleMenuText()
ToggleMenuEnable()
End Sub
Private Sub StopScan()
StopSyncWatcher()
tmScanTimer.Stop()
eCurrentStatus = eStatus.Stopped
UpdateStatus("Not Scanning")
gMonStripStatusButton.Image = My.Resources.Stopped
gMonTray.Icon = My.Resources.GBM_Tray_Stopped
ToggleMenuText()
ToggleMenuEnable()
End Sub
'Functions to handle verification
Private Sub VerifyCustomPathVariables()
Dim sGames As String = String.Empty
If Not mgrPath.VerifyCustomVariables(hshScanList, sGames) Then
MsgBox("The following monitored game(s) contain a custom path variable that is not set." & vbCrLf & sGames & vbCrLf & vbCrLf & "You will encounter backup/restore errors with these games until the variables are set.", MsgBoxStyle.Critical, "Game Backup Monitor")
End If
End Sub
Private Function VerifyBackupLocation() As Boolean
Dim sBackupPath As String = oSettings.BackupFolder
If mgrPath.VerifyBackupPath(sBackupPath) Then
If oSettings.BackupFolder <> sBackupPath Then
oSettings.BackupFolder = sBackupPath
oSettings.SaveSettings()
oSettings.LoadSettings()
If oSettings.Sync Then mgrMonitorList.HandleBackupLocationChange()
End If
Return True
Else
Return False
End If
End Function
Private Sub VerifyGameDataPath()
'Important: This function cannot access mgrPath for settings, as that will trigger a database creation and destroy the reason for this function
Dim sSettingsRoot As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) & "\gbm"
Dim sDBLocation As String = sSettingsRoot & "\gbm.s3db"
If Not IO.Directory.Exists(sSettingsRoot) Then
Try
IO.Directory.CreateDirectory(sSettingsRoot)
Catch ex As Exception
MsgBox("An error occured creating application settings folder. The application cannot proceed." & vbCrLf & vbCrLf & ex.Message, MsgBoxStyle.Critical, "Game Backup Monitor")
bShutdown = True
Me.Close()
End Try
End If
If Not IO.File.Exists(sDBLocation) Then bFirstRun = True
End Sub
Private Sub VerifyDBVersion(ByVal iDB As mgrSQLite.Database)
Dim oDatabase As New mgrSQLite(iDB)
Dim iDBVer As Integer
If Not oDatabase.CheckDBVer(iDBVer) Then
Select Case iDB
Case mgrSQLite.Database.Local
MsgBox("Your local GBM data (Version " & iDBVer & ") is too new for your version of GBM (Version " & mgrCommon.AppVersion & ")." & vbCrLf & vbCrLf & "Please upgrade GBM or restore the settings file appropriate for your version. The application cannot proceed.", MsgBoxStyle.Critical, "Game Backup Monitor")
Case mgrSQLite.Database.Remote
MsgBox("The GBM data (Version " & iDBVer & ") in your backup folder is too new for your version of GBM (Version " & mgrCommon.AppVersion & ")." & vbCrLf & vbCrLf & "All computers sharing a backup folder must use the same version of GBM. The application cannot proceed.", MsgBoxStyle.Critical, "Game Backup Monitor")
End Select
bShutdown = True
Me.Close()
End If
End Sub
Private Function VerifyStartWithWindows() As Boolean
Dim oKey As Microsoft.Win32.RegistryKey
Dim sAppName As String = Application.ProductName
Dim sAppPath As String = Application.ExecutablePath
Dim sRegPath As String
oKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", True)
sRegPath = oKey.GetValue(sAppName, String.Empty).ToString.Replace("""", "")
oKey.Close()
If sAppPath.ToLower <> sRegPath.ToLower Then
oKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", True)
oKey.SetValue(sAppName, """" & sAppPath & """")
oKey.Close()
Return False
Else
Return True
End If
End Function
Private Sub CheckForSavedDuplicate()
For Each o As clsGame In oProcess.DuplicateList
If o.ProcessPath.ToLower = oProcess.GameInfo.ProcessPath.ToLower Then
oProcess.GameInfo = o
oProcess.Duplicate = False
End If
Next
End Sub
Private Function CheckForSavedPath() As Boolean
If oProcess.GameInfo.ProcessPath <> String.Empty Then
Return True
End If
Return False
End Function
'Functions to handle other features
Private Sub RestartAsAdmin()
If mgrCommon.IsElevated Then
MsgBox("Game Backup Monitor is already running as Administrator.", MsgBoxStyle.Information, "Game Backup Monitor")
Else
If MsgBox("Do you want to restart Game Backup Monitor as Administrator?", MsgBoxStyle.YesNo, "Game Backup Monitor") = MsgBoxResult.Yes Then
mgrCommon.RestartAsAdmin()
bShutdown = True
ShutdownApp(False)
End If
End If
End Sub
Private Sub SyncManifest()
Dim slItems As SortedList
PauseScan()
If MsgBox("This removes orphaned backup information from the local manifest." & vbCrLf & vbCrLf &
"Do you want to sync the local backup manfiest with the current backup folder?" & vbCrLf & vbCrLf &
"Not recommended if alternating between more than one backup folder.", MsgBoxStyle.YesNo _
, "Game Backup Monitor") = MsgBoxResult.Yes Then
slItems = mgrRestore.SyncLocalManifest()
If slItems.Count > 0 Then
For Each oItem As clsBackup In slItems.Values
UpdateLog(oItem.Name & " entry removed from local manfiest.", False)
Next
MsgBox(slItems.Count & " entries removed from the local manifest.")
Else
MsgBox("No orphaned entries found. Local manifest is already in sync.")
End If
End If
ResumeScan()
End Sub
Private Sub CompactDatabases()
Dim oLocalDatabase As mgrSQLite
Dim oRemoteDatabase As mgrSQLite
PauseScan()
If MsgBox("This will rebuild all databases and shrink them to an optimal size." & vbCrLf &
"This should only be used if your gbm.s3db files are becoming very large." & vbCrLf & vbCrLf &
"Do you wish to continue?", MsgBoxStyle.YesNo, "Game Backup Monitor") = MsgBoxResult.Yes Then
oLocalDatabase = New mgrSQLite(mgrSQLite.Database.Local)
oRemoteDatabase = New mgrSQLite(mgrSQLite.Database.Remote)
UpdateLog("Local Database Vacuum Initialized: " & oLocalDatabase.GetDBSize & " KB", False)
oLocalDatabase.CompactDatabase()
UpdateLog("Local Database Vacuum Completed: " & oLocalDatabase.GetDBSize & " KB", False)
UpdateLog("Remote Database Vacuum Initialized: " & oRemoteDatabase.GetDBSize & " KB", False)
oRemoteDatabase.CompactDatabase()
UpdateLog("Remote Database Vacuum Completed: " & oRemoteDatabase.GetDBSize & " KB", False)
End If
ResumeScan()
End Sub
'Event Handlers
Private Sub gMonFileMonitor_Click(sender As Object, e As EventArgs) Handles gMonFileMonitor.Click
ScanToggle()
End Sub
Private Sub gMonTrayMon_Click(sender As System.Object, e As System.EventArgs) Handles gMonTrayMon.Click
ScanToggle()
End Sub
Private Sub gMonTray_MouseClick(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles gMonTray.MouseDoubleClick
ToggleState()
End Sub
Private Sub gMonTrayShow_Click(sender As System.Object, e As System.EventArgs) Handles gMonTrayShow.Click
ToggleState()
End Sub
Private Sub FileExit_Click(sender As Object, e As EventArgs) Handles gMonFileExit.Click, gMonTrayExit.Click
ShutdownApp()
End Sub
Private Sub FileSettings_Click(sender As Object, e As EventArgs) Handles gMonFileSettings.Click, gMonTraySettings.Click
OpenSettings()
End Sub
Private Sub SetupGameManager_Click(sender As Object, e As EventArgs) Handles gMonSetupGameManager.Click, gMonTraySetupGameManager.Click
OpenGameManager()
End Sub
Private Sub gMonToolsSync_Click(sender As Object, e As EventArgs) Handles gMonToolsSyncMan.Click, gMonTrayToolsSyncMan.Click
SyncManifest()
End Sub
Private Sub gMonToolsCompact_Click(sender As Object, e As EventArgs) Handles gMonToolsCompact.Click, gMonTrayToolsCompact.Click
CompactDatabases()
End Sub
Private Sub gMonToolsGameExportList_Click(sender As Object, e As EventArgs) Handles gMonToolsGameExportList.Click, gMonTrayToolsGameExportList.Click
ExportMonitorList()
End Sub
Private Sub gMonToolsGameImportList_Click(sender As Object, e As EventArgs) Handles gMonToolsGameImportList.Click, gMonTrayToolsGameImportList.Click
ImportMonitorList()
End Sub
Private Sub gMonToolsGameImportOfficialList_Click(sender As Object, e As EventArgs) Handles gMonToolsGameImportOfficialList.Click, gMonTrayToolsGameImportOfficialList.Click
DownloadOfficialList()
End Sub
Private Sub gMonSetupAddWizard_Click(sender As Object, e As EventArgs) Handles gMonSetupAddWizard.Click, gMonTraySetupAddWizard.Click
OpenGameWizard()
End Sub
Private Sub SetupCustomVariables_Click(sender As Object, e As EventArgs) Handles gMonSetupCustomVariables.Click, gMonTraySetupCustomVariables.Click
OpenCustomVariables()
End Sub
Private Sub gMonSetupTags_Click(sender As Object, e As EventArgs) Handles gMonSetupTags.Click, gMonTraySetupTags.Click
OpenTags()
End Sub
Private Sub gMonHelpAbout_Click(sender As Object, e As EventArgs) Handles gMonHelpAbout.Click
OpenAbout()
End Sub
Private Sub gMonHelpWebSite_Click(sender As Object, e As EventArgs) Handles gMonHelpWebSite.Click
OpenWebSite()
End Sub
Private Sub gMonHelpManual_Click(sender As Object, e As EventArgs) Handles gMonHelpManual.Click
OpenOnlineManual()
End Sub
Private Sub gMonHelpCheckforUpdates_Click(sender As Object, e As EventArgs) Handles gMonHelpCheckforUpdates.Click
OpenCheckforUpdates()
End Sub
Private Sub gMonNotification_Click(sender As Object, e As EventArgs) Handles gMonNotification.Click, gMonTrayNotification.Click
gMonNotification.Visible = False
gMonTrayNotification.Visible = False
OpenGameManager(True)
End Sub
Private Sub btnLogToggle_Click(sender As Object, e As EventArgs) Handles btnLogToggle.Click
ToggleLog()
End Sub
Private Sub gMonStripSplitButton_ButtonClick(sender As Object, e As EventArgs) Handles gMonStripStatusButton.ButtonClick
ScanToggle()
End Sub
Private Sub pbIcon_Click(sender As Object, e As EventArgs) Handles pbIcon.Click
If bAllowIcon Then
SetIcon()
End If
End Sub
Private Sub gMonTray_BalloonTipClicked(sender As System.Object, e As System.EventArgs) Handles gMonTray.BalloonTipClicked
Me.Visible = True
Me.ShowInTaskbar = True
Me.WindowState = FormWindowState.Normal
Me.Focus()
End Sub
Private Sub btnCancelOperation_Click(sender As Object, e As EventArgs) Handles btnCancelOperation.Click
OperationCancel()
End Sub
Private Sub gMonStripAdminButton_ButtonClick(sender As Object, e As EventArgs) Handles gMonStripAdminButton.ButtonClick
RestartAsAdmin()
End Sub
Private Sub frmMain_Activated(sender As System.Object, e As System.EventArgs) Handles MyBase.Activated
txtLog.Select(txtLog.TextLength, 0)
txtLog.ScrollToCaret()
End Sub
Private Sub Main_FormClosing(sender As System.Object, e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
'Intercept Exit & Minimize
If bShutdown = False Then
e.Cancel = True
Me.Visible = False
Me.ShowInTaskbar = False
Me.WindowState = FormWindowState.Minimized
End If
End Sub
Private Sub ScanTimerEventProcessor(myObject As Object, ByVal myEventArgs As EventArgs) Handles tmScanTimer.Tick
Dim bNeedsPath As Boolean = False
Dim bContinue As Boolean = True
Dim bAskForRestart As Boolean = False
Dim iErrorCode As Integer = 0
Dim sErrorMessage As String = String.Empty
If oProcess.SearchRunningProcesses(hshScanList, bNeedsPath, iErrorCode) Then
PauseScan()
If bNeedsPath Then
bContinue = False
If iErrorCode = 5 Then
If oProcess.Duplicate Then
sErrorMessage = "Multiple possible games have been detected running as Administrator and GBM is not, GBM cannot detect the path to identify your game or save your backup." & vbCrLf & vbCrLf &
"Please run GBM as Administrator to properly detect and backup this game."
MsgBox(sErrorMessage, MsgBoxStyle.Critical, "Game Backup Monitor")
bAskForRestart = True
Else
If Not CheckForSavedPath() Then
sErrorMessage = oProcess.GameInfo.Name & " is running as Administrator and GBM is not, GBM cannot detect the required information to save your backup."
oProcess.GameInfo.ProcessPath = mgrPath.ProcessPathSearch(oProcess.GameInfo.Name, oProcess.GameInfo.ProcessName, sErrorMessage)
If oProcess.GameInfo.ProcessPath <> String.Empty Then
'Update and reload
mgrMonitorList.DoListUpdate(oProcess.GameInfo)
LoadGameSettings()
bContinue = True
End If
Else
bContinue = True
End If
End If
ElseIf iErrorCode = 299 Then
If oProcess.Duplicate Then
sErrorMessage = "Multiple possible 64-bit games have been detected, GBM cannot detect the path to identify your game or save your backup." & vbCrLf & vbCrLf &
"Please install the 64-bit version of GBM to detect and backup this game properly."
MsgBox(sErrorMessage, MsgBoxStyle.Critical, "Game Backup Monitor")
Else
If Not CheckForSavedPath() Then
sErrorMessage = oProcess.GameInfo.Name & " is a 64-bit game, GBM cannot detect the required information to save your backup."
oProcess.GameInfo.ProcessPath = mgrPath.ProcessPathSearch(oProcess.GameInfo.Name, oProcess.GameInfo.ProcessName, sErrorMessage)
If oProcess.GameInfo.ProcessPath <> String.Empty Then
'Update and reload
mgrMonitorList.DoListUpdate(oProcess.GameInfo)
LoadGameSettings()
bContinue = True
End If
Else
bContinue = True
End If
End If
End If
End If
If bContinue = True Then
CheckForSavedDuplicate()
If oProcess.Duplicate Then
UpdateLog("Multiple Games Detected", oSettings.ShowDetectionToolTips)
UpdateStatus("Multiple Games Detected")
SetGameInfo(True)
Else
UpdateLog(oProcess.GameInfo.Name & " Detected", oSettings.ShowDetectionToolTips)
UpdateStatus(oProcess.GameInfo.CroppedName & " Detected")
SetGameInfo()
End If
oProcess.StartTime = Now
bwMonitor.RunWorkerAsync()
Else
StopScan()
If bAskForRestart Then
RestartAsAdmin()
End If
End If
End If
End Sub
Private Sub bwMonitor_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles bwMonitor.DoWork
Try
Do While Not (oProcess.FoundProcess.HasExited Or bwMonitor.CancellationPending)
System.Threading.Thread.Sleep(3000)
Loop
If bwMonitor.CancellationPending Then
bCancelledByUser = True
End If
Catch ex As Exception
bProcessIsAdmin = True
oProcess.FoundProcess.WaitForExit()
bProcessIsAdmin = False
End Try
End Sub
Private Sub bwMain_RunWorkerCompleted(sender As System.Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwMonitor.RunWorkerCompleted
oProcess.EndTime = Now
If Not bCancelledByUser Then
If DoMultiGameCheck() Then
UpdateLog(oProcess.GameInfo.Name & " has ended.", False)
If oSettings.TimeTracking Then HandleTimeSpent()
RunBackup()
Else
UpdateLog("The unidentified game has ended.", False)
ResetGameInfo()
ResumeScan()
End If
End If
bCancelledByUser = False
oProcess.StartTime = Now : oProcess.EndTime = Now
End Sub
Private Sub Main_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
SetForm()
VerifyGameDataPath()
LoadAndVerify()
VerifyCustomPathVariables()
If oSettings.StartToTray Then
Me.Visible = False
Me.ShowInTaskbar = False
Me.WindowState = FormWindowState.Minimized
End If
If oSettings.MonitorOnStartup Then
eCurrentStatus = eStatus.Stopped
Else
eCurrentStatus = eStatus.Running
End If
HandleScan()
CheckForNewBackups()
End Sub
Private Sub frmMain_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
If bFirstRun Then
OpenStartupWizard()
End If
End Sub
Private Sub txtGameInfo_Enter(sender As Object, e As EventArgs)
btnLogToggle.Focus()
End Sub
End Class