Files
GBM/GBM/Forms/frmMain.vb
2018-09-14 12:33:14 -06:00

2096 lines
78 KiB
VB.net

Imports GBM.My.Resources
Imports System.IO
'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 eCurrentStatus As eStatus = eStatus.Stopped
Private eCurrentOperation As eOperation = eOperation.None
Private bCancelledByUser As Boolean = False
Private bShutdown As Boolean = False
Private bInitFail As Boolean = False
Private bPathDetectionFailure As Boolean = False
Private sPathDetectionError As String = String.Empty
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 bShowToggle As Boolean = True
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
Private iRestoreTimeOut As Integer
Private oChildProcesses As New Hashtable
Private wState As FormWindowState = FormWindowState.Normal
'Developer Debug Flags
Private bProcessDebugMode As Boolean = False
WithEvents oFileWatcher As New FileSystemWatcher
'Timers - There may only be one System.Windows.Forms.Timer and it must be tmScanTimer.
WithEvents tmScanTimer As New Timer
WithEvents tmRestoreCheck As New System.Timers.Timer
WithEvents tmFileWatcherQueue As New System.Timers.Timer
Public WithEvents oProcess As New mgrProcessDetection
Public WithEvents oBackup As New mgrBackup
Public WithEvents oRestore As New mgrRestore
Public hshScanList As Hashtable
Public oSettings As New mgrSettings
Delegate Sub UpdateNotifierCallBack(ByVal iCount As Integer)
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.TrimEnd(".") & " " & mgrCommon.FormatString(frmMain_AtTime, 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 = Path.GetFileName(oRestoreInfo.FileName)
sStatus2 = mgrCommon.FormatString(frmMain_UpdatedBy, New String() {oRestoreInfo.UpdatedBy, oRestoreInfo.DateUpdated})
If oRestoreInfo.AbsolutePath Then
sStatus3 = oRestoreInfo.RestorePath
Else
sStatus3 = oRestoreInfo.RelativeRestorePath
End If
WorkingGameInfo(frmMain_RestoreInProgress, sStatus1, sStatus2, sStatus3)
UpdateStatus(frmMain_RestoreInProgress)
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 & Path.DirectorySeparatorChar & oGame.Path
End If
sStatus3 = String.Empty
WorkingGameInfo(frmMain_BackupInProgress, sStatus1, sStatus2, sStatus3)
UpdateStatus(frmMain_BackupInProgress)
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))
oBackup.DoBackup(oBackupList)
OperationEnded()
End Sub
Private Sub ExecuteRestore(ByVal oRestoreList As List(Of clsBackup))
oRestore.DoRestore(oRestoreList)
OperationEnded()
End Sub
Private Sub RunRestore(ByVal oRestoreList As Hashtable)
Dim oGame As clsGame
Dim oReadyList As New List(Of clsBackup)
Dim oRestoreInfo As clsBackup
Dim bTriggerReload As Boolean = False
Dim bPathVerified As Boolean
eCurrentOperation = eOperation.Restore
OperationStarted()
'Build Restore List
For Each de As DictionaryEntry In oRestoreList
bPathVerified = False
oGame = DirectCast(de.Key, clsGame)
oRestoreInfo = DirectCast(de.Value, clsBackup)
If mgrRestore.CheckPath(oRestoreInfo, oGame, bTriggerReload) Then
bPathVerified = True
Else
UpdateLog(mgrCommon.FormatString(frmMain_ErrorRestorePath, oRestoreInfo.Name), False, ToolTipIcon.Error, True)
End If
If bPathVerified Then
If oRestore.CheckRestorePrereq(oRestoreInfo, oGame.CleanFolder) Then
oReadyList.Add(oRestoreInfo)
End If
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 bPathVerified As Boolean
Dim oReadyList As New List(Of clsGame)
eCurrentOperation = eOperation.Backup
OperationStarted()
'Build Backup List
For Each oGame In oBackupList
bNoAuto = False
bPathVerified = False
gMonStripStatusButton.Enabled = False
UpdateLog(mgrCommon.FormatString(frmMain_ManualBackup, oGame.Name), 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.ProcessName, mgrCommon.FormatString(frmMain_ErrorRelativePath, oGame.Name), bNoAuto)
End If
If oGame.ProcessPath <> String.Empty Then
bPathVerified = True
Else
UpdateLog(mgrCommon.FormatString(frmMain_ErrorBackupUnknownPath, oGame.Name), False, ToolTipIcon.Error, True)
End If
Else
bPathVerified = True
End If
If bPathVerified Then
If oBackup.CheckBackupPrereq(oGame) Then
oReadyList.Add(oGame)
End If
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 Sub RunImportBackup(ByVal oImportBackupList As Hashtable)
PauseScan()
oBackup.ImportBackupFiles(oImportBackupList)
ResumeScan()
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
'Reload settings
LoadGameSettings()
oProcess.GameInfo = frm.Game
'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 oProcess.GameInfo.MonitorOnly = False Then
If SuppressSession() Then
bDoBackup = False
UpdateLog(mgrCommon.FormatString(frmMain_ErrorBackupSessionLength, oProcess.GameInfo.Name), False)
SetLastAction(mgrCommon.FormatString(frmMain_ErrorBackupSessionLength, oProcess.GameInfo.CroppedName))
OperationEnded()
Else
If oSettings.DisableConfirmation Then
bDoBackup = True
Else
If mgrCommon.ShowMessage(frmMain_ConfirmBackup, oProcess.GameInfo.Name, MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
bDoBackup = True
Else
bDoBackup = False
UpdateLog(mgrCommon.FormatString(frmMain_ErrorBackupCancel, oProcess.GameInfo.Name), False)
SetLastAction(mgrCommon.FormatString(frmMain_ErrorBackupCancel, oProcess.GameInfo.CroppedName))
OperationEnded()
End If
End If
End If
Else
bDoBackup = False
UpdateLog(mgrCommon.FormatString(frmMain_MonitorEnded, oProcess.GameInfo.Name), False)
SetLastAction(mgrCommon.FormatString(frmMain_MonitorEnded, oProcess.GameInfo.CroppedName))
OperationEnded()
End If
If bDoBackup Then
If Not oBackup.CheckBackupPrereq(oProcess.GameInfo) Then
SetLastAction(mgrCommon.FormatString(frmMain_ErrorBackupCancel, oProcess.GameInfo.CroppedName))
OperationEnded()
Else
'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 If
End Sub
Private Sub UpdateNotifier(ByVal iCount As Integer)
'Thread Safe
If Me.InvokeRequired = True Then
Dim d As New UpdateNotifierCallBack(AddressOf UpdateNotifier)
Me.Invoke(d, New Object() {iCount})
Else
Dim sNotification As String
If iCount > 1 Then
sNotification = mgrCommon.FormatString(frmMain_NewSaveNotificationMulti, iCount)
Else
sNotification = mgrCommon.FormatString(frmMain_NewSaveNotificationSingle, iCount)
End If
gMonNotification.Image = Icon_Inbox
gMonTrayNotification.Image = Icon_Inbox
gMonNotification.Text = sNotification
gMonTrayNotification.Text = sNotification
gMonNotification.Visible = True
gMonTrayNotification.Visible = True
End If
End Sub
Private Sub StartRestoreCheck()
iRestoreTimeOut = -1
tmRestoreCheck.Interval = 60000
tmRestoreCheck.AutoReset = True
tmRestoreCheck.Start()
AutoRestoreCheck()
End Sub
Private Sub AutoRestoreCheck()
Dim slRestoreData As SortedList = mgrRestore.CompareManifests()
Dim oNotReady As New List(Of clsBackup)
Dim oNotInstalled As New List(Of clsBackup)
Dim oNoCheckSum As New List(Of clsBackup)
Dim oBackup As clsBackup
Dim sFileName As String
Dim sExtractPath As String
Dim bFinished As Boolean = True
Dim hshRestore As Hashtable
Dim hshGames As Hashtable
Dim oGame As clsGame
Dim sGame As String
'Shut down the timer and bail out if there's nothing to do
If slRestoreData.Count = 0 Then
tmRestoreCheck.Stop()
Exit Sub
End If
If oSettings.AutoMark Or oSettings.AutoRestore Then
'Increment Timer
iRestoreTimeOut += 1
'Check backup files
For Each de As DictionaryEntry In slRestoreData
oBackup = DirectCast(de.Value, clsBackup)
'Check if backup file is ready to restore
If oBackup.CheckSum <> String.Empty Then
sFileName = oSettings.BackupFolder & Path.DirectorySeparatorChar & oBackup.FileName
If mgrHash.Generate_SHA256_Hash(sFileName) <> oBackup.CheckSum Then
oNotReady.Add(oBackup)
bFinished = False
End If
Else
oNoCheckSum.Add(oBackup)
End If
'Check if the restore location exists, if not we assume the game is not installed and should be auto-marked.
hshGames = mgrMonitorList.DoListGetbyMonitorID(de.Key)
If hshGames.Count = 1 Then
oGame = DirectCast(hshGames(0), clsGame)
If oGame.ProcessPath <> String.Empty Then
oBackup.RelativeRestorePath = oGame.ProcessPath & Path.DirectorySeparatorChar & oBackup.RestorePath
End If
End If
If oBackup.AbsolutePath Then
sExtractPath = oBackup.RestorePath
Else
sExtractPath = oBackup.RelativeRestorePath
End If
If Not Directory.Exists(sExtractPath) Then
If oSettings.AutoMark Then
If mgrManifest.DoManifestCheck(de.Key, mgrSQLite.Database.Local) Then
mgrManifest.DoManifestUpdateByMonitorID(de.Value, mgrSQLite.Database.Local)
Else
mgrManifest.DoManifestAdd(de.Value, mgrSQLite.Database.Local)
End If
End If
oNotInstalled.Add(oBackup)
End If
Next
'Remove any backup files that are not ready
For Each o As clsBackup In oNotReady
slRestoreData.Remove(o.MonitorID)
UpdateLog(mgrCommon.FormatString(frmMain_RestoreNotReady, o.Name), False, ToolTipIcon.Info, True)
Next
'Remove any backup files that should not be automatically restored
For Each o As clsBackup In oNotInstalled
slRestoreData.Remove(o.MonitorID)
If oSettings.AutoMark Then
UpdateLog(mgrCommon.FormatString(frmMain_AutoMark, o.Name), False, ToolTipIcon.Info, True)
Else
UpdateLog(mgrCommon.FormatString(frmMain_NoAutoMark, o.Name), False, ToolTipIcon.Info, True)
End If
Next
For Each o As clsBackup In oNoCheckSum
slRestoreData.Remove(o.MonitorID)
UpdateLog(mgrCommon.FormatString(frmMain_NoCheckSum, o.Name), False, ToolTipIcon.Info, True)
Next
'Automatically restore backup files
If oSettings.AutoRestore Then
If slRestoreData.Count > 0 Then
hshRestore = New Hashtable
sGame = String.Empty
For Each de As DictionaryEntry In slRestoreData
oBackup = DirectCast(de.Value, clsBackup)
hshGames = mgrMonitorList.DoListGetbyMonitorID(de.Key)
If hshGames.Count = 1 Then
oGame = DirectCast(hshGames(0), clsGame)
sGame = oGame.CroppedName
hshRestore.Add(oGame, de.Value)
Else
UpdateLog(mgrCommon.FormatString(frmMain_AutoRestoreFailure, oBackup.Name), False, ToolTipIcon.Info, True)
End If
Next
'Handle notifications
If oSettings.RestoreOnLaunch Then
If slRestoreData.Count > 1 Then
UpdateLog(mgrCommon.FormatString(frmMain_RestoreNotificationMulti, slRestoreData.Count), True, ToolTipIcon.Info, True)
Else
UpdateLog(mgrCommon.FormatString(frmMain_RestoreNotificationSingle, sGame), True, ToolTipIcon.Info, True)
End If
End If
RunRestore(hshRestore)
End If
End If
'Shutdown if we are finished
If bFinished Then
tmRestoreCheck.Stop()
End If
'Time out after 15 minutes
If iRestoreTimeOut = 15 Then
tmRestoreCheck.Stop()
End If
End If
'Update the menu notifier if we aren't using auto restore
If oSettings.RestoreOnLaunch And Not oSettings.AutoRestore Then
If slRestoreData.Count > 0 Then
UpdateNotifier(slRestoreData.Count)
End If
End If
End Sub
'Functions handling the display of game information
Private Sub SetIcon()
Dim sIcon As String
Dim fbBrowser As New OpenFileDialog
fbBrowser.Title = mgrCommon.FormatString(frmMain_ChooseIcon, oProcess.GameInfo.CroppedName)
'Unix Handler
If Not mgrCommon.IsUnix Then
fbBrowser.DefaultExt = "ico"
fbBrowser.Filter = frmMain_IconFilter
Else
fbBrowser.DefaultExt = "png"
fbBrowser.Filter = frmMain_PNGFilter
End If
Try
fbBrowser.InitialDirectory = 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 File.Exists(sIcon) Then
oProcess.GameInfo.Icon = sIcon
pbIcon.Image = mgrCommon.SafeIconFromFile(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 = mgrCommon.FormatString(frmMain_LastGame, oProcess.GameInfo.Name)
pbIcon.Image = oPriorImage
lblStatus1.Text = sPriorPath
lblStatus2.Text = sPriorCompany
lblStatus3.Text = sPriorVersion
If oSettings.TimeTracking Then
pbTime.Visible = True
lblTimeSpent.Visible = True
End If
Else
pbIcon.Image = Icon_Searching
lblGameTitle.Text = frmMain_NoGameDetected
lblStatus1.Text = String.Empty
lblStatus2.Text = String.Empty
lblStatus3.Text = String.Empty
pbTime.Visible = False
lblTimeSpent.Visible = False
End If
If eCurrentStatus = eStatus.Stopped Then
UpdateStatus(frmMain_NotScanning)
Else
UpdateStatus(frmMain_NoGameDetected)
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
pbTime.Visible = False
lblTimeSpent.Visible = False
pbIcon.Image = Icon_Working
lblGameTitle.Text = sTitle
lblStatus1.Text = sStatus1
lblStatus2.Text = sStatus2
lblStatus3.Text = sStatus3
End If
End Sub
Private Sub SetGameIcon()
Dim ic As Icon
Dim oBitmap As Bitmap
Try
'Grab icon from the executable
ic = System.Drawing.Icon.ExtractAssociatedIcon(oProcess.FoundProcess.MainModule.FileName)
oBitmap = New Bitmap(ic.ToBitmap)
ic.Dispose()
'Set the icon, we need to use an intermediary object to prevent file locking
pbIcon.Image = oBitmap
Catch ex As Exception
UpdateLog(mgrCommon.FormatString(frmMain_ErrorGameIcon), False, ToolTipIcon.Error)
UpdateLog(mgrCommon.FormatString(App_GenericError, ex.Message), False,, False)
End Try
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
pbIcon.Image = Icon_Unknown
'Set Game Icon
If Not mgrCommon.IsUnix Then SetGameIcon()
Try
'Set Game Details
sFileName = oProcess.FoundProcess.MainModule.FileName
sFileVersion = oProcess.FoundProcess.MainModule.FileVersionInfo.FileVersion
sCompanyName = oProcess.FoundProcess.MainModule.FileVersionInfo.CompanyName
Catch ex As Exception
UpdateLog(mgrCommon.FormatString(frmMain_ErrorGameDetails), False, ToolTipIcon.Error)
UpdateLog(mgrCommon.FormatString(App_GenericError, ex.Message), False,, False)
End Try
'Get Game Details
If bMulti Then
bAllowIcon = False
bAllowDetails = False
lblGameTitle.Text = frmMain_MultipleGames
pbTime.Visible = False
lblTimeSpent.Visible = False
pbIcon.Image = Icon_Unknown
If sFileName = String.Empty Then
lblStatus1.Text = frmMain_NoDetails
Else
lblStatus1.Text = sFileName
End If
Else
bAllowIcon = True
bAllowDetails = True
lblGameTitle.Text = oProcess.GameInfo.Name
'Check for a custom icon & details
If File.Exists(oProcess.GameInfo.Icon) Then
pbIcon.Image = mgrCommon.SafeIconFromFile(oProcess.GameInfo.Icon)
End If
If sFileName = String.Empty Then
If oProcess.GameInfo.ProcessPath <> String.Empty Then
sFileName = mgrCommon.FormatString(frmMain_ExePath, oProcess.GameInfo.ProcessPath)
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
pbTime.Visible = False
lblTimeSpent.Visible = False
End If
'Set Details
If sFileName = String.Empty Then
lblStatus1.Text = frmMain_NotAvailable
Else
lblStatus1.Text = sFileName
End If
If sCompanyName = String.Empty Then
lblStatus2.Text = frmMain_NotAvailable
Else
lblStatus2.Text = sCompanyName
End If
If sFileVersion = String.Empty Then
lblStatus3.Text = frmMain_NotAvailable
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 = mgrCommon.FormatString(frmMain_SessionMinutes, Math.Round((dTotalTime * 100) * 0.6).ToString)
Else
sTotalTime = mgrCommon.FormatString(frmMain_SessionHours, Math.Round(dTotalTime, 1).ToString)
End If
If dSessionTime < 1 Then
sSessionTime = mgrCommon.FormatString(frmMain_SessionMinutes, Math.Round((dSessionTime * 100) * 0.6).ToString)
Else
sSessionTime = mgrCommon.FormatString(frmMain_SessionHours, Math.Round(dSessionTime, 1).ToString)
End If
If dSessionTime > 0 Then
lblTimeSpent.Text = sSessionTime & " (" & sTotalTime & ")"
Else
lblTimeSpent.Text = sTotalTime
End If
pbTime.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)
mgrMonitorList.SyncMonitorLists(oSettings)
UpdateTimeSpent(dCurrentHours, oProcess.TimeSpent.TotalHours)
End Sub
Private Sub HandleSession()
Dim oSession As clsSession
If Not SuppressSession() Then
'Record Session
oSession = New clsSession
oSession.MonitorID = oProcess.GameInfo.ID
oSession.SessionStartFromDate = oProcess.StartTime
oSession.SessionEndFromDate = oProcess.EndTime
mgrSessions.AddSession(oSession)
End If
End Sub
Private Function SuppressSession() As Boolean
Dim iSession As Integer
If oSettings.SuppressBackup Then
iSession = Math.Ceiling(oProcess.TimeSpent.TotalMinutes)
If iSession > oSettings.SuppressBackupThreshold Then
Return False
Else
Return True
End If
Else
Return False
End If
End Function
'Functions handling the opening of other windows
Private Sub OpenDevConsole()
Dim sFullCommand As String
Dim sMainCommand As String
Dim sCommand As String()
Dim sDelimters As String = " :"
Dim cDelimters As Char() = sDelimters.ToCharArray
sFullCommand = InputBox(frmMain_EnterCommand, frmMain_DeveloperConsole)
If sFullCommand <> String.Empty Then
sMainCommand = sFullCommand.Split(cDelimters, 2)(0)
'Parse Command
Select Case sMainCommand.ToLower
Case "sql"
'Run a SQL command directly on any database
'Usage: SQL {Local or Remote} SQL Command
Dim oDatabase As mgrSQLite
Dim bSuccess As Boolean
sCommand = sFullCommand.Split(cDelimters, 3)
'Check Paramters
If sCommand.Length < 3 Then
mgrCommon.ShowMessage(frmMain_ErrorMissingParams, sCommand(0), MsgBoxStyle.Exclamation)
Exit Select
End If
If sCommand(1).ToLower = "local" Then
oDatabase = New mgrSQLite(mgrSQLite.Database.Local)
ElseIf sCommand(1).ToLower = "remote" Then
oDatabase = New mgrSQLite(mgrSQLite.Database.Remote)
Else
mgrCommon.ShowMessage(frmMain_ErrorCommandBadParam, New String() {sCommand(1), sCommand(0)}, MsgBoxStyle.Exclamation)
Exit Select
End If
bSuccess = oDatabase.RunParamQuery(sCommand(2), New Hashtable)
If bSuccess Then
mgrCommon.ShowMessage(frmMain_CommandSucess, MsgBoxStyle.Exclamation)
Else
mgrCommon.ShowMessage(frmMain_CommandFail, MsgBoxStyle.Exclamation)
End If
Case "debug"
'Enable or disable various debug modes
'Usage: DEBUG Mode {Enable or Disable}
sCommand = sFullCommand.Split(cDelimters, 3)
Dim bDebugEnable As Boolean = False
'Check Paramters
If sCommand.Length < 3 Then
mgrCommon.ShowMessage(frmMain_ErrorMissingParams, sCommand(0), MsgBoxStyle.Exclamation)
Exit Select
End If
If sCommand(2).ToLower = "enable" Then
bDebugEnable = True
ElseIf sCommand(2).ToLower = "disable" Then
bDebugEnable = False
Else
mgrCommon.ShowMessage(frmMain_ErrorCommandBadParam, New String() {sCommand(1), sCommand(0)}, MsgBoxStyle.Exclamation)
Exit Select
End If
Select Case sCommand(1).ToLower
Case "process"
bProcessDebugMode = bDebugEnable
mgrCommon.ShowMessage(frmMain_CommandSucess, MsgBoxStyle.Exclamation)
End Select
Case Else
mgrCommon.ShowMessage(frmMain_ErrorCommandInvalid, sMainCommand, MsgBoxStyle.Exclamation)
End Select
End If
End Sub
Private Sub OpenAbout()
Dim iProcessType As System.Reflection.ProcessorArchitecture = System.Reflection.AssemblyName.GetAssemblyName(Application.ExecutablePath()).ProcessorArchitecture
Dim sProcessType = [Enum].GetName(GetType(System.Reflection.ProcessorArchitecture), iProcessType)
Dim sRevision As String = My.Application.Info.Version.Revision
Dim oDatabase As New mgrSQLite(mgrSQLite.Database.Local)
Dim sSqliteVersion As String = oDatabase.ReportVersion
Dim sConstCopyright As String = Chr(169) & mgrCommon.FormatString(App_Copyright, Now.Year.ToString)
mgrCommon.ShowMessage(frmMain_About, New String() {mgrCommon.DisplayAppVersion, sProcessType, sRevision, sSqliteVersion, sConstCopyright}, MsgBoxStyle.Information)
End Sub
Private Sub OpenTags()
Dim frm As New frmTags
PauseScan()
frm.ShowDialog()
mgrMonitorList.SyncMonitorLists(oSettings)
ResumeScan()
End Sub
Private Sub OpenProcessManager()
Dim frm As New frmProcessManager
PauseScan()
frm.ShowDialog()
ResumeScan()
End Sub
Private Sub OpenGameManager(Optional ByVal bPendingRestores As Boolean = False)
Dim frm As New frmGameManager
PauseScan()
frm.Settings = oSettings
frm.PendingRestores = bPendingRestores
frm.ShowDialog()
LoadGameSettings()
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
'Handle import backup trigger
If frm.TriggerImportBackup Then
RunImportBackup(frm.ImportBackupList)
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
oBackup.Settings = oSettings
oRestore.Settings = oSettings
'Set Remote Database Location
mgrPath.RemoteDatabaseLocation = oSettings.BackupFolder
SetupSyncWatcher()
LoadGameSettings()
End If
ResumeScan()
End Sub
Private Sub OpenSessions()
Dim frm As New frmSessions
PauseScan()
If oSettings.SessionTracking = False Then
mgrCommon.ShowMessage(frmMain_WarningSessionsDisabled, MsgBoxStyle.Exclamation)
End If
If mgrSessions.CountRows > 0 Then
frm.ShowDialog()
Else
mgrCommon.ShowMessage(frmMain_ErrorNoSessions, MsgBoxStyle.Information)
End If
ResumeScan()
End Sub
Private Sub OpenGameWizard()
Dim frm As New frmAddWizard
PauseScan()
frm.GameData = mgrMonitorList.ReadList(mgrMonitorList.eListTypes.FullList)
frm.ShowDialog()
LoadGameSettings()
mgrMonitorList.SyncMonitorLists(oSettings)
ResumeScan()
End Sub
Private Sub OpenCustomVariables()
Dim frm As New frmVariableManager
PauseScan()
frm.ShowDialog()
mgrPath.LoadCustomVariables()
mgrMonitorList.SyncMonitorLists(oSettings)
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(App_URLWebsite)
End Sub
Private Sub OpenOnlineManual()
Process.Start(App_URLManual)
End Sub
Private Sub OpenCheckforUpdates()
Process.Start(App_URLUpdates)
End Sub
Private Sub CheckForNewBackups()
If oSettings.RestoreOnLaunch Or oSettings.AutoRestore Or oSettings.AutoMark Then
StartRestoreCheck()
End If
End Sub
'Functions handling the loading/sync of settings
Private Sub LoadGameSettings()
'Load Monitor List
hshScanList = mgrMonitorList.ReadList(mgrMonitorList.eListTypes.ScanList)
UpdateLog(mgrCommon.FormatString(frmMain_GameListLoaded, hshScanList.Keys.Count), False)
End Sub
Private Sub StartSyncWatcher()
oFileWatcher.EnableRaisingEvents = True
End Sub
Private Sub StopSyncWatcher()
oFileWatcher.EnableRaisingEvents = False
End Sub
Private Sub SetupSyncWatcher()
oFileWatcher.Path = oSettings.BackupFolder
oFileWatcher.Filter = "gbm.s3db"
oFileWatcher.NotifyFilter = NotifyFilters.LastWrite
End Sub
Private Sub QueueSyncWatcher() Handles oFileWatcher.Changed
tmFileWatcherQueue.Stop()
tmFileWatcherQueue.AutoReset = False
tmFileWatcherQueue.Interval = 30000
tmFileWatcherQueue.Start()
End Sub
Private Sub HandleSyncWatcher() Handles tmFileWatcherQueue.Elapsed
tmFileWatcherQueue.Stop()
StopSyncWatcher()
UpdateLog(frmMain_MasterListChanged, False, ToolTipIcon.Info, True)
SyncGameSettings()
LoadGameSettings()
CheckForNewBackups()
StartSyncWatcher()
End Sub
Private Sub SyncGameSettings()
'Sync Monitor List
mgrMonitorList.SyncMonitorLists(oSettings, False)
End Sub
Private Sub SyncGameIDs(ByVal bOfficial As Boolean)
Dim sLocation As String
PauseScan()
If mgrCommon.IsUnix Then
sLocation = App_URLImportLinux
Else
sLocation = App_URLImport
End If
If bOfficial Then
mgrMonitorList.SyncGameIDs(sLocation, oSettings, True)
Else
sLocation = mgrCommon.OpenFileBrowser("XML_Import", frmGameManager_ChooseImportXML, "xml", frmGameManager_XML, Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), False)
If sLocation <> String.Empty Then
mgrMonitorList.SyncGameIDs(sLocation, oSettings, False)
End If
End If
ResumeScan()
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 BackupDatabases()
Dim oLocalDatabase As New mgrSQLite(mgrSQLite.Database.Local)
Dim oRemoteDatabase As New mgrSQLite(mgrSQLite.Database.Remote)
oLocalDatabase.BackupDB(App_BackupOnLaunchFileDescription, True)
oRemoteDatabase.BackupDB(App_BackupOnLaunchFileDescription, True)
End Sub
Private Sub LoadAndVerify()
'If the default utility is missing we cannot continue
If Not oBackup.CheckForUtilities(mgrPath.Default7zLocation) Then
mgrCommon.ShowMessage(frmMain_Error7zip, MsgBoxStyle.Critical)
bInitFail = True
Exit Sub
End If
'Check Special Paths
If Not mgrPath.CheckSpecialPaths Then
bInitFail = True
Exit Sub
End If
'Local Database Check
VerifyDBVersion(mgrSQLite.Database.Local)
LocalDatabaseCheck()
'Load Settings
oSettings.LoadSettings()
oBackup.Settings = oSettings
oRestore.Settings = oSettings
If Not bFirstRun Then
'The application cannot continue if this fails
If Not VerifyBackupLocation() Then
bInitFail = True
Exit Sub
End If
'Remote Database Check
VerifyDBVersion(mgrSQLite.Database.Remote)
RemoteDatabaseCheck()
'Backup GBM data
If oSettings.BackupOnLaunch Then
BackupDatabases()
End If
'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(frmMain_ErrorAppLocationChanged, False, ToolTipIcon.Info)
End If
End If
'Check for any custom 7z utility and display a warning if it's missing
If oSettings.Custom7zLocation <> String.Empty Then
If Not oBackup.CheckForUtilities(oSettings.Custom7zLocation) Then
mgrCommon.ShowMessage(frmMain_Error7zCustom, oSettings.Custom7zLocation, MsgBoxStyle.Exclamation)
End If
End If
End Sub
'Functions that handle buttons, menus and other GUI features on this form
Private Sub ToggleState()
'Toggle State with Tray Clicks
If Not bShowToggle Then
bShowToggle = True
Me.Visible = True
Me.WindowState = wState
Me.ShowInTaskbar = True
Me.Focus()
Else
If Me.CanFocus Then
bShowToggle = False
wState = Me.WindowState
Me.WindowState = FormWindowState.Minimized
Me.ShowInTaskbar = False
Me.Visible = False
Else
gMonTray.ShowBalloonTip(5000, App_NameLong, App_ErrorFocus, ToolTipIcon.Info)
End If
End If
End Sub
Private Sub ScanToggle()
Select Case eCurrentStatus
Case eStatus.Running
HandleScan()
Case eStatus.Paused
Dim sGame As String = oProcess.GameInfo.CroppedName
If bProcessIsAdmin Then
mgrCommon.ShowMessage(frmMain_ErrorAdminDetect, sGame, MsgBoxStyle.Exclamation)
RestartAsAdmin()
Exit Sub
End If
If oProcess.Duplicate Then
sGame = frmMain_UnknownGame
End If
If mgrCommon.ShowMessage(frmMain_ConfirmMonitorCancel, sGame, MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
UpdateLog(mgrCommon.FormatString(frmMain_MonitorCancel, sGame), False)
SetLastAction(mgrCommon.FormatString(frmMain_MonitorCancel, sGame))
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 mgrCommon.ShowMessage(frmMain_Exit, MsgBoxStyle.YesNo) = 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(Optional ByVal bGameDetected As Boolean = False)
If bMenuEnabled Then
ToggleMenuItems(False, gMonFile)
ToggleMenuItems(False, gMonSetup)
ToggleMenuItems(False, gMonSetupAddWizard)
ToggleMenuItems(False, gMonHelp)
ToggleMenuItems(False, gMonTools)
ToggleMenuItems(False, gMonTraySetup)
ToggleMenuItems(False, gMonTrayTools)
gMonNotification.Enabled = False
gMonTrayNotification.Enabled = False
gMonTraySettings.Enabled = False
If Not bGameDetected Then
gMonTrayMon.Enabled = False
gMonTrayShow.Enabled = False
gMonTrayExit.Enabled = False
End If
bMenuEnabled = False
Else
ToggleMenuItems(True, gMonFile)
ToggleMenuItems(True, gMonSetup)
ToggleMenuItems(True, gMonSetupAddWizard)
ToggleMenuItems(True, gMonHelp)
ToggleMenuItems(True, gMonTools)
ToggleMenuItems(True, gMonTraySetup)
ToggleMenuItems(True, gMonTrayTools)
gMonNotification.Enabled = True
gMonTrayNotification.Enabled = True
gMonTraySettings.Enabled = True
gMonTrayMon.Enabled = True
gMonTrayShow.Enabled = True
gMonTrayExit.Enabled = True
bMenuEnabled = True
End If
End Sub
Private Sub ToggleMenuText()
Select Case eCurrentStatus
Case eStatus.Running
gMonFileMonitor.Text = frmMain_gMonFileMonitor_Stop
gMonTrayMon.Text = frmMain_gMonFileMonitor_Stop
Case eStatus.Stopped
gMonFileMonitor.Text = frmMain_gMonFileMonitor_Start
gMonTrayMon.Text = frmMain_gMonFileMonitor_Start
Case eStatus.Paused
gMonFileMonitor.Text = frmMain_gMonFileMonitor_Cancel
gMonTrayMon.Text = frmMain_gMonFileMonitor_Cancel
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
Private Function NotifySendUnix(ByVal sLogUpdate As String, ByVal objIcon As System.Windows.Forms.ToolTipIcon) As Boolean
Dim prsNotify As Process
Dim sUrgency As String
Dim sNotifyArgs As String
Dim bNotifyFailed As Boolean
'Build args for notify-send
Select Case objIcon
Case ToolTipIcon.Error
sUrgency = "critical"
Case ToolTipIcon.Warning
sUrgency = "normal"
Case ToolTipIcon.Info
sUrgency = "low"
Case Else
sUrgency = "low"
End Select
sNotifyArgs = "-i gbm " & "-u " & sUrgency & " """ & App_NameLong & """ ""<i>" & sLogUpdate.Replace("""", "\""") & "</i>"""
Try
'Execute notify-send
prsNotify = New Process
prsNotify.StartInfo.FileName = "/usr/bin/notify-send"
prsNotify.StartInfo.Arguments = sNotifyArgs
prsNotify.StartInfo.UseShellExecute = False
prsNotify.StartInfo.RedirectStandardOutput = True
prsNotify.StartInfo.CreateNoWindow = True
prsNotify.Start()
prsNotify.WaitForExit()
Select Case prsNotify.ExitCode
Case 0
bNotifyFailed = False
Case Else
bNotifyFailed = True
End Select
Catch
bNotifyFailed = True
End Try
Return bNotifyFailed
End Function
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
Dim bNotifyFailed As Boolean
'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
'Auto save and/or clear the log if we are approaching the limit
If txtLog.TextLength > 262144 Then
If oSettings.AutoSaveLog Then
Dim sLogFile As String = mgrPath.LogFileLocation
mgrCommon.SaveText(txtLog.Text, sLogFile)
txtLog.Clear()
txtLog.AppendText("[" & Date.Now & "] " & mgrCommon.FormatString(frmMain_LogAutoSave, sLogFile))
Else
txtLog.Clear()
txtLog.AppendText("[" & Date.Now & "] " & frmMain_LogAutoClear)
End If
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()
If bTrayUpdate Then
If mgrCommon.IsUnix Then
bNotifyFailed = NotifySendUnix(sLogUpdate, objIcon)
End If
If Not mgrCommon.IsUnix Or bNotifyFailed Then
gMonTray.BalloonTipText = sLogUpdate
gMonTray.BalloonTipIcon = objIcon
gMonTray.ShowBalloonTip(10000)
End If
End If
End If
Application.DoEvents()
End Sub
Private Sub ClearLog()
If mgrCommon.ShowMessage(frmMain_ConfirmLogClear, MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
txtLog.Clear()
End If
End Sub
Private Sub SaveLog()
Dim sLocation As String
sLocation = mgrCommon.SaveFileBrowser("Log_File", frmMain_ChooseLogFile, "txt", frmMain_Text, Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), frmMain_DefaultLogFileName & " " & Date.Now.ToString("dd-MMM-yyyy"))
If sLocation <> String.Empty Then
mgrCommon.SaveText(txtLog.Text, sLocation)
End If
End Sub
Private Sub SetForm()
'Set Minimum Size
Me.MinimumSize = New Size(Me.Size.Width, Me.Size.Height - txtLog.Size.Height)
'Set Form Name
Me.Name = App_NameLong
'Set Menu Text
gMonFile.Text = frmMain_gMonFile
gMonFileMonitor.Text = frmMain_gMonFileMonitor_Start
gMonFileSettings.Text = frmMain_gMonFileSettings
gMonFileExit.Text = frmMain_gMonFileExit
gMonSetup.Text = frmMain_gMonSetup
gMonSetupGameManager.Text = frmMain_gMonSetupGameManager
gMonSetupAddWizard.Text = frmMain_gMonSetupAddWizard
gMonSetupCustomVariables.Text = frmMain_gMonSetupCustomVariables
gMonSetupTags.Text = frmMain_gMonSetupTags
gMonSetupProcessManager.Text = frmMain_gMonSetupProcessManager
gMonTools.Text = frmMain_gMonTools
gMonToolsCompact.Text = frmMain_gMonToolsCompact
gMonToolsLog.Text = frmMain_gMonToolsLog
gMonToolsSessions.Text = frmMain_gMonToolsSessions
gMonToolsSyncGameID.Text = frmMain_gMonToolsSyncGameID
gMonToolsSyncGameIDOfficial.Text = frmMain_gMonToolsSyncGameIDOfficial
gMonToolsSyncGameIDFile.Text = frmMain_gMonToolsSyncGameIDFile
gMonLogClear.Text = frmMain_gMonLogClear
gMonLogSave.Text = frmMain_gMonLogSave
gMonHelp.Text = frmMain_gMonHelp
gMonHelpWebSite.Text = frmMain_gMonHelpWebSite
gMonHelpManual.Text = frmMain_gMonHelpManual
gMonHelpCheckforUpdates.Text = frmMain_gMonHelpCheckForUpdates
gMonHelpAbout.Text = frmMain_gMonHelpAbout
'Set Tray Menu Text
gMonTrayShow.Text = frmMain_gMonTrayShow
gMonTrayMon.Text = frmMain_gMonFileMonitor_Start
gMonTraySettings.Text = frmMain_gMonFileSettings
gMonTraySetup.Text = frmMain_gMonSetup
gMonTraySetupGameManager.Text = frmMain_gMonSetupGameManager
gMonTraySetupAddWizard.Text = frmMain_gMonSetupAddWizard
gMonTraySetupCustomVariables.Text = frmMain_gMonSetupCustomVariables
gMonTraySetupTags.Text = frmMain_gMonSetupTags
gMonTraySetupProcessManager.Text = frmMain_gMonSetupProcessManager
gMonTrayTools.Text = frmMain_gMonTools
gMonTrayToolsCompact.Text = frmMain_gMonToolsCompact
gMonTrayToolsLog.Text = frmMain_gMonToolsLog
gMonTrayToolsSessions.Text = frmMain_gMonToolsSessions
gMonTrayToolsSyncGameID.Text = frmMain_gMonToolsSyncGameID
gMonTrayToolsSyncGameIDOfficial.Text = frmMain_gMonToolsSyncGameIDOfficial
gMonTrayToolsSyncGameIDFile.Text = frmMain_gMonToolsSyncGameIDFile
gMonTrayLogClear.Text = frmMain_gMonLogClear
gMonTrayLogSave.Text = frmMain_gMonLogSave
gMonTrayExit.Text = frmMain_gMonFileExit
'Set Form Text
lblLastActionTitle.Text = frmMain_lblLastActionTitle
btnCancelOperation.Text = frmMain_btnCancelOperation
gMonStripStatusButton.Text = frmMain_gMonStripStatusButton
gMonStripStatusButton.ToolTipText = frmMain_gMonStripStatusButtonToolTip
If mgrCommon.IsElevated Then
gMonStripAdminButton.Image = Icon_Admin
gMonStripAdminButton.ToolTipText = frmMain_RunningAsAdmin
Else
gMonStripAdminButton.Image = Icon_User
gMonStripAdminButton.ToolTipText = frmMain_RunningAsNormal
End If
btnCancelOperation.Visible = False
lblLastActionTitle.Visible = False
lblLastAction.Text = String.Empty
pbTime.SizeMode = PictureBoxSizeMode.AutoSize
pbTime.Image = Icon_Clock
AddHandler mgrMonitorList.UpdateLog, AddressOf UpdateLog
ResetGameInfo()
End Sub
Private Function BuildChildProcesses() As Integer
Dim oCurrentProcess As clsProcess
Dim oProcessList As Hashtable
Dim prsChild As Process
oChildProcesses.Clear()
oProcessList = mgrGameProcesses.GetProcessesByGame(oProcess.GameInfo.ID)
If oProcessList.Count > 0 Then
For Each oCurrentProcess In oProcessList.Values
prsChild = New Process
prsChild.StartInfo.Arguments = oCurrentProcess.Args
prsChild.StartInfo.FileName = oCurrentProcess.Path
prsChild.StartInfo.UseShellExecute = False
prsChild.StartInfo.RedirectStandardOutput = True
prsChild.StartInfo.CreateNoWindow = True
oChildProcesses.Add(oCurrentProcess, prsChild)
Next
End If
Return oChildProcesses.Count
End Function
Private Sub StartChildProcesses()
Dim oCurrentProcess As clsProcess
Dim prsChild As Process
Try
For Each de As DictionaryEntry In oChildProcesses
oCurrentProcess = DirectCast(de.Key, clsProcess)
prsChild = DirectCast(de.Value, Process)
prsChild.Start()
UpdateLog(mgrCommon.FormatString(frmMain_ProcessStarted, oCurrentProcess.Name), False)
Next
Catch ex As Exception
UpdateLog(mgrCommon.FormatString(frmMain_ErrorStartChildProcess, oProcess.GameInfo.CroppedName), True, ToolTipIcon.Error)
UpdateLog(mgrCommon.FormatString(App_GenericError, ex.Message), False,, False)
End Try
End Sub
Private Sub EndChildProcesses()
Dim oCurrentProcess As clsProcess
Dim prsChild As Process
Try
For Each de As DictionaryEntry In oChildProcesses
oCurrentProcess = DirectCast(de.Key, clsProcess)
prsChild = DirectCast(de.Value, Process)
If oCurrentProcess.Kill Then
prsChild.Kill()
UpdateLog(mgrCommon.FormatString(frmMain_ProcessKilled, oCurrentProcess.Name), False)
End If
Next
Catch ex As Exception
UpdateLog(mgrCommon.FormatString(frmMain_ErrorEndChildProcess, oProcess.GameInfo.CroppedName), True, ToolTipIcon.Error)
UpdateLog(mgrCommon.FormatString(App_GenericError, ex.Message), False,, False)
End Try
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(frmMain_NotScanning)
gMonStripStatusButton.Image = Icon_Stopped
gMonTray.Icon = GBM_Tray_Stopped
Else
StartScan()
StartSyncWatcher()
eCurrentStatus = eStatus.Running
UpdateStatus(frmMain_NoGameDetected)
gMonStripStatusButton.Image = Icon_Ready
gMonTray.Icon = GBM_Tray_Ready
End If
ToggleMenuText()
End Sub
Private Sub PauseScan(Optional ByVal bGameDetected As Boolean = False)
If eCurrentStatus = eStatus.Running Then
StopSyncWatcher()
tmScanTimer.Stop()
eCurrentStatus = eStatus.Paused
UpdateStatus(frmMain_NotScanning)
gMonStripStatusButton.Image = Icon_Detected
gMonTray.Icon = GBM_Tray_Detected
End If
ToggleMenuText()
ToggleMenuEnable(bGameDetected)
End Sub
Private Sub ResumeScan()
If eCurrentStatus = eStatus.Running Or eCurrentStatus = eStatus.Paused Then
StartScan()
StartSyncWatcher()
eCurrentStatus = eStatus.Running
gMonStripStatusButton.Image = Icon_Ready
gMonTray.Icon = GBM_Tray_Ready
UpdateStatus(frmMain_NoGameDetected)
End If
ToggleMenuText()
ToggleMenuEnable()
End Sub
Private Sub StopScan()
StopSyncWatcher()
tmScanTimer.Stop()
eCurrentStatus = eStatus.Stopped
UpdateStatus(frmMain_NotScanning)
gMonStripStatusButton.Image = Icon_Stopped
gMonTray.Icon = 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
mgrCommon.ShowMessage(frmMain_ErrorCustomVariable, sGames, MsgBoxStyle.Exclamation)
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()
mgrMonitorList.HandleBackupLocationChange(oSettings)
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 Directory.Exists(sSettingsRoot) Then
Try
Directory.CreateDirectory(sSettingsRoot)
Catch ex As Exception
mgrCommon.ShowMessage(frmMain_ErrorSettingsFolder, ex.Message, MsgBoxStyle.Critical)
bShutdown = True
Me.Close()
End Try
End If
If Not 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
mgrCommon.ShowMessage(frmMain_ErrorDBVerLocal, New String() {iDBVer, mgrCommon.AppVersion}, MsgBoxStyle.Critical)
Case mgrSQLite.Database.Remote
mgrCommon.ShowMessage(frmMain_ErrorDBVerRemote, New String() {iDBVer, mgrCommon.AppVersion}, MsgBoxStyle.Critical)
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 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()
'Unix Hanlder
If Not mgrCommon.IsUnix Then
If mgrCommon.IsElevated Then
mgrCommon.ShowMessage(frmMain_ErrorAlreadyAdmin, MsgBoxStyle.Information)
Else
If mgrCommon.ShowMessage(frmMain_ConfirmRunAsAdmin, MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
mgrCommon.RestartAsAdmin()
bShutdown = True
ShutdownApp(False)
End If
End If
Else
mgrCommon.ShowMessage(App_ErrorUnixNotAvailable, MsgBoxStyle.Exclamation)
End If
End Sub
Private Sub CompactDatabases()
Dim oLocalDatabase As mgrSQLite
Dim oRemoteDatabase As mgrSQLite
PauseScan()
If mgrCommon.ShowMessage(frmMain_ConfirmRebuild, MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
oLocalDatabase = New mgrSQLite(mgrSQLite.Database.Local)
oRemoteDatabase = New mgrSQLite(mgrSQLite.Database.Remote)
UpdateLog(mgrCommon.FormatString(frmMain_LocalCompactInit, oLocalDatabase.GetDBSize), False)
oLocalDatabase.CompactDatabase()
UpdateLog(mgrCommon.FormatString(frmMain_LocalCompactComplete, oLocalDatabase.GetDBSize), False)
UpdateLog(mgrCommon.FormatString(frmMain_RemoteCompactInit, oRemoteDatabase.GetDBSize), False)
oRemoteDatabase.CompactDatabase()
UpdateLog(mgrCommon.FormatString(frmMain_RemoteCompactComplete, oRemoteDatabase.GetDBSize), 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 gMonToolsCompact_Click(sender As Object, e As EventArgs) Handles gMonToolsCompact.Click, gMonTrayToolsCompact.Click
CompactDatabases()
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 gMonSetupProcessManager_Click(sender As Object, e As EventArgs) Handles gMonSetupProcessManager.Click, gMonTraySetupProcessManager.Click
OpenProcessManager()
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 gMonLogClear_Click(sender As Object, e As EventArgs) Handles gMonLogClear.Click, gMonTrayLogClear.Click
ClearLog()
End Sub
Private Sub gMonLogSave_Click(sender As Object, e As EventArgs) Handles gMonLogSave.Click, gMonTrayLogSave.Click
SaveLog()
End Sub
Private Sub gMonToolsSessions_Click(sender As Object, e As EventArgs) Handles gMonToolsSessions.Click, gMonTrayToolsSessions.Click
OpenSessions()
End Sub
Private Sub gMonToolsSyncGameIDOfficial_Click(sender As Object, e As EventArgs) Handles gMonToolsSyncGameIDOfficial.Click, gMonTrayToolsSyncGameIDOfficial.Click
SyncGameIDs(True)
End Sub
Private Sub gMonToolsSyncGameIDFile_Click(sender As Object, e As EventArgs) Handles gMonToolsSyncGameIDFile.Click, gMonTrayToolsSyncGameIDFile.Click
SyncGameIDs(False)
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 gMonStripSplitStatusButton_ButtonClick(sender As Object, e As EventArgs) Handles gMonStripStatusButton.Click
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 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.Click
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
'Unix Handler
If mgrCommon.IsUnix And Not bShutdown Then
ShutdownApp()
End If
Select Case e.CloseReason
Case CloseReason.UserClosing
If bShutdown = False Then
e.Cancel = True
If Not mgrCommon.IsUnix Then
bShowToggle = False
wState = Me.WindowState
Me.WindowState = FormWindowState.Minimized
Me.ShowInTaskbar = False
Me.Visible = False
End If
End If
Case CloseReason.TaskManagerClosing, CloseReason.WindowsShutDown
'Do nothing and let the app close without warning
End Select
End Sub
Private Sub AutoRestoreEventProcessor(myObject As Object, ByVal myEventArgs As EventArgs) Handles tmRestoreCheck.Elapsed
If eCurrentStatus <> eStatus.Paused Then
AutoRestoreCheck()
End If
End Sub
Private Sub ScanTimerEventProcessor(myObject As Object, ByVal myEventArgs As EventArgs) Handles tmScanTimer.Tick
Dim bNeedsPath As Boolean = False
Dim bWineProcess As Boolean = False
Dim bContinue As Boolean = True
Dim iErrorCode As Integer = 0
Dim sErrorMessage As String = String.Empty
If oProcess.SearchRunningProcesses(hshScanList, bNeedsPath, bWineProcess, iErrorCode, bProcessDebugMode) Then
PauseScan(True)
If bNeedsPath Then
bContinue = False
If iErrorCode = 5 Then
If oProcess.Duplicate Then
sErrorMessage = mgrCommon.FormatString(frmMain_ErrorMultiAdmin)
UpdateLog(sErrorMessage, True, ToolTipIcon.Warning, True)
Else
If Not CheckForSavedPath() Then
bPathDetectionFailure = True
sPathDetectionError = mgrCommon.FormatString(frmMain_ErrorAdminBackup, oProcess.GameInfo.Name)
End If
bContinue = True
End If
ElseIf iErrorCode = 299 Then
If oProcess.Duplicate Then
sErrorMessage = mgrCommon.FormatString(frmMain_ErrorMulti64)
UpdateLog(sErrorMessage, True, ToolTipIcon.Warning, True)
Else
If Not CheckForSavedPath() Then
bPathDetectionFailure = True
sPathDetectionError = mgrCommon.FormatString(frmMain_Error64Backup, oProcess.GameInfo.Name)
End If
bContinue = True
End If
End If
End If
If bWineProcess Then
'Attempt a path conversion if the game configuration is using an absolute windows path that we can convert
If mgrVariables.CheckForReservedVariables(oProcess.GameInfo.TruePath) Then
Dim sWinePrefix As String = mgrPath.GetWinePrefix(oProcess.FoundProcess)
Dim sWineSavePath As String
If Not sWinePrefix = String.Empty Then
UpdateLog(mgrCommon.FormatString(frmMain_WinePrefix, New String() {oProcess.GameInfo.Name, sWinePrefix}), False)
sWineSavePath = mgrPath.GetWineSavePath(sWinePrefix, oProcess.GameInfo.TruePath)
If Not sWineSavePath = oProcess.GameInfo.TruePath Then
oProcess.GameInfo.TruePath = sWineSavePath
oProcess.GameInfo.AbsolutePath = True
UpdateLog(mgrCommon.FormatString(frmMain_WineSavePath, New String() {oProcess.GameInfo.Name, sWineSavePath}), False)
End If
End If
End If
End If
If bContinue = True Then
If oProcess.Duplicate Then
UpdateLog(frmMain_MultipleGamesDetected, oSettings.ShowDetectionToolTips)
UpdateStatus(frmMain_MultipleGamesDetected)
SetGameInfo(True)
Else
UpdateLog(mgrCommon.FormatString(frmMain_GameDetected, oProcess.GameInfo.Name), oSettings.ShowDetectionToolTips)
UpdateStatus(mgrCommon.FormatString(frmMain_GameDetected, oProcess.GameInfo.CroppedName))
SetGameInfo()
End If
If BuildChildProcesses() > 0 And Not oProcess.Duplicate Then
StartChildProcesses()
End If
oProcess.StartTime = Now
bwMonitor.RunWorkerAsync()
Else
StopScan()
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
Dim bContinue As Boolean = True
If oChildProcesses.Count > 0 And Not oProcess.Duplicate Then
EndChildProcesses()
End If
oProcess.EndTime = Now
If Not bCancelledByUser Then
'Check if we failed to detect the game path
If bPathDetectionFailure Then
oProcess.GameInfo.ProcessPath = mgrPath.ProcessPathSearch(oProcess.GameInfo.Name, oProcess.GameInfo.ProcessName, sPathDetectionError)
If oProcess.GameInfo.ProcessPath <> String.Empty Then
'Update and reload
mgrMonitorList.DoListUpdate(oProcess.GameInfo)
LoadGameSettings()
Else
bContinue = False
If oSettings.TimeTracking Then HandleTimeSpent()
If oSettings.SessionTracking Then HandleSession()
UpdateLog(mgrCommon.FormatString(frmMain_ErrorBackupUnknownPath, oProcess.GameInfo.Name), False)
oProcess.GameInfo = Nothing
ResetGameInfo()
ResumeScan()
End If
End If
If bContinue Then
If DoMultiGameCheck() Then
UpdateLog(mgrCommon.FormatString(frmMain_GameEnded, oProcess.GameInfo.Name), False)
If oSettings.TimeTracking Then HandleTimeSpent()
If oSettings.SessionTracking Then HandleSession()
RunBackup()
Else
UpdateLog(frmMain_UnknownGameEnded, False)
oProcess.GameInfo = Nothing
ResetGameInfo()
ResumeScan()
End If
End If
End If
'Reset globals
bPathDetectionFailure = False
sPathDetectionError = String.Empty
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
'Init
Try
SetForm()
VerifyGameDataPath()
LoadAndVerify()
If Not bInitFail Then
VerifyCustomPathVariables()
If oSettings.StartToTray And Not mgrCommon.IsUnix Then
bShowToggle = False
Me.Visible = False
Me.ShowInTaskbar = False
End If
If oSettings.MonitorOnStartup Then
eCurrentStatus = eStatus.Stopped
Else
eCurrentStatus = eStatus.Running
End If
HandleScan()
CheckForNewBackups()
'Unix Handler
If mgrCommon.IsUnix Then
Me.MinimizeBox = True
Else
Me.gMonTray.Visible = True
End If
End If
Catch ex As Exception
If mgrCommon.ShowMessage(frmMain_ErrorInitFailure, ex.Message, MsgBoxStyle.YesNo) = MsgBoxResult.No Then
bInitFail = True
End If
End Try
End Sub
Private Sub frmMain_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
If bInitFail Then
bShutdown = True
Me.Close()
End If
If bFirstRun And Not bShutdown Then
OpenStartupWizard()
End If
End Sub
Private Sub frmMain_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
If e.KeyCode = Keys.Oemtilde AndAlso e.Modifiers = Keys.Control Then
OpenDevConsole()
End If
End Sub
'This event handler lets the user clear focus from the log by clicking anywhere on the form.
'Due to txtLog being the only focusable control in most cases, it's impossible for it to lose focus unless a change is forced.
Private Sub ClearLogFocus(sender As Object, e As EventArgs) Handles MyBase.Click, lblGameTitle.Click, lblStatus1.Click, lblStatus2.Click,
lblStatus3.Click, pbTime.Click, lblTimeSpent.Click, lblLastActionTitle.Click, lblLastAction.Click, gMonMainMenu.Click, gMonStatusStrip.Click
'Move focus to first label
lblGameTitle.Focus()
End Sub
End Class