Detection rewrite for issue #153 - Pass 1
This commit is contained in:
@@ -21,7 +21,6 @@ Public Class clsGame
|
||||
Private bMonitorOnly As Boolean = False
|
||||
Private sComments As String = String.Empty
|
||||
Private bIsRegEx As Boolean = False
|
||||
Private bDuplicate As Boolean = False
|
||||
Private oImportTags As New List(Of Tag)
|
||||
Private bImportUpdate As Boolean = False
|
||||
|
||||
@@ -46,12 +45,6 @@ Public Class clsGame
|
||||
End Get
|
||||
End Property
|
||||
|
||||
ReadOnly Property CompoundKey As String
|
||||
Get
|
||||
Return ProcessName & ":" & ID
|
||||
End Get
|
||||
End Property
|
||||
|
||||
ReadOnly Property CroppedName As String
|
||||
Get
|
||||
If Name.Length > 40 Then
|
||||
@@ -248,15 +241,6 @@ Public Class clsGame
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Property Duplicate As Boolean
|
||||
Get
|
||||
Return bDuplicate
|
||||
End Get
|
||||
Set(value As Boolean)
|
||||
bDuplicate = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Property TruePath As String
|
||||
Set(value As String)
|
||||
sPath = value
|
||||
@@ -266,12 +250,6 @@ Public Class clsGame
|
||||
End Get
|
||||
End Property
|
||||
|
||||
ReadOnly Property TrueProcess As String
|
||||
Get
|
||||
Return HandleProcessDuplicates()
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Property ImportTags As List(Of Tag)
|
||||
Get
|
||||
Return oImportTags
|
||||
@@ -460,18 +438,6 @@ Public Class clsGame
|
||||
Return DirectCast(Me.MemberwiseClone(), clsGame)
|
||||
End Function
|
||||
|
||||
Private Function HandleProcessDuplicates() As String
|
||||
Dim sProcessName As String
|
||||
|
||||
'Handle Duplicates
|
||||
sProcessName = Me.ProcessName
|
||||
If Me.Duplicate Then
|
||||
sProcessName = Me.ProcessName.Split(":")(0)
|
||||
End If
|
||||
|
||||
Return sProcessName
|
||||
End Function
|
||||
|
||||
Public Shared Function SetSyncField(ByVal eSyncFields As eOptionalSyncFields, ByVal eSyncField As eOptionalSyncFields) As eOptionalSyncFields
|
||||
Return eSyncFields Or eSyncField
|
||||
End Function
|
||||
|
||||
@@ -82,7 +82,7 @@ Public Class frmAdvancedImport
|
||||
Next
|
||||
sTags = sTags.TrimEnd(New Char() {",", " "})
|
||||
|
||||
oListViewItem = New ListViewItem(New String() {oApp.Name, oApp.TrueProcess, sTags})
|
||||
oListViewItem = New ListViewItem(New String() {oApp.Name, oApp.ProcessName, sTags})
|
||||
oListViewItem.Tag = oApp.ID
|
||||
|
||||
If FinalData.ContainsKey(oApp.ID) Then
|
||||
@@ -114,7 +114,7 @@ Public Class frmAdvancedImport
|
||||
If sFilter = String.Empty Then
|
||||
bAddItem = True
|
||||
Else
|
||||
If oApp.Name.ToLower.Contains(sFilter.ToLower) Or oApp.TrueProcess.ToLower.Contains(sFilter.ToLower) Or sTags.ToLower.Contains(sFilter.ToLower) Then
|
||||
If oApp.Name.ToLower.Contains(sFilter.ToLower) Or oApp.ProcessName.ToLower.Contains(sFilter.ToLower) Or sTags.ToLower.Contains(sFilter.ToLower) Then
|
||||
bAddItem = True
|
||||
End If
|
||||
End If
|
||||
|
||||
@@ -574,7 +574,7 @@ Public Class frmGameManager
|
||||
If CurrentGame.ProcessPath <> String.Empty Then
|
||||
CurrentBackupItem.RelativeRestorePath = CurrentGame.ProcessPath & Path.DirectorySeparatorChar & CurrentBackupItem.RestorePath
|
||||
Else
|
||||
sProcess = CurrentGame.TrueProcess
|
||||
sProcess = CurrentGame.ProcessName
|
||||
If mgrCommon.IsProcessNotSearchable(CurrentGame) Then bNoAuto = True
|
||||
sRestorePath = mgrPath.ProcessPathSearch(CurrentBackupItem.Name, sProcess, mgrCommon.FormatString(frmGameManager_ErrorPathNotSet, CurrentBackupItem.Name), bNoAuto)
|
||||
|
||||
@@ -864,7 +864,7 @@ Public Class frmGameManager
|
||||
'Core
|
||||
txtID.Text = oApp.ID
|
||||
txtName.Text = oApp.Name
|
||||
txtProcess.Text = oApp.TrueProcess
|
||||
txtProcess.Text = oApp.ProcessName
|
||||
chkRegEx.Checked = oApp.IsRegEx
|
||||
txtParameter.Text = oApp.Parameter
|
||||
txtSavePath.Text = oApp.Path
|
||||
|
||||
+1
-11
@@ -228,7 +228,7 @@ Public Class frmMain
|
||||
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, mgrCommon.FormatString(frmMain_ErrorRelativePath, oGame.Name), bNoAuto)
|
||||
oGame.ProcessPath = mgrPath.ProcessPathSearch(oGame.Name, oGame.ProcessName, mgrCommon.FormatString(frmMain_ErrorRelativePath, oGame.Name), bNoAuto)
|
||||
End If
|
||||
|
||||
If oGame.ProcessPath <> String.Empty Then
|
||||
@@ -1689,15 +1689,6 @@ Public Class frmMain
|
||||
|
||||
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
|
||||
@@ -1946,7 +1937,6 @@ Public Class frmMain
|
||||
End If
|
||||
|
||||
If bContinue = True Then
|
||||
CheckForSavedDuplicate()
|
||||
If oProcess.Duplicate Then
|
||||
UpdateLog(frmMain_MultipleGamesDetected, oSettings.ShowDetectionToolTips)
|
||||
UpdateStatus(frmMain_MultipleGamesDetected)
|
||||
|
||||
@@ -225,7 +225,7 @@ Public Class mgrCommon
|
||||
If oGame.ProcessName.ToLower.Contains(s) Then bFound = True
|
||||
Next
|
||||
|
||||
If bFound Or oGame.Duplicate = True Then
|
||||
If bFound Then
|
||||
Return True
|
||||
Else
|
||||
Return False
|
||||
|
||||
@@ -45,7 +45,7 @@ Public Class mgrMonitorList
|
||||
|
||||
hshParams.Add("ID", oGame.ID)
|
||||
hshParams.Add("Name", oGame.Name)
|
||||
hshParams.Add("Process", oGame.TrueProcess)
|
||||
hshParams.Add("Process", oGame.ProcessName)
|
||||
hshParams.Add("Path", oGame.TruePath)
|
||||
hshParams.Add("AbsolutePath", oGame.AbsolutePath)
|
||||
hshParams.Add("FolderSave", oGame.FolderSave)
|
||||
@@ -75,10 +75,8 @@ Public Class mgrMonitorList
|
||||
Dim hshList As New Hashtable
|
||||
Dim hshDupeList As New Hashtable
|
||||
Dim oGame As clsGame
|
||||
Dim oCompareGame As clsGame
|
||||
Dim bIsDupe As Boolean
|
||||
|
||||
sSQL = "SELECT * FROM monitorlist ORDER BY IsRegEx DESC"
|
||||
sSQL = "SELECT * FROM monitorlist ORDER BY Name ASC"
|
||||
oData = oDatabase.ReadParamData(sSQL, New Hashtable)
|
||||
|
||||
For Each dr As DataRow In oData.Tables(0).Rows
|
||||
@@ -87,39 +85,7 @@ Public Class mgrMonitorList
|
||||
Case eListTypes.FullList
|
||||
hshList.Add(oGame.ID, oGame)
|
||||
Case eListTypes.ScanList
|
||||
For Each de As DictionaryEntry In hshList
|
||||
bIsDupe = False
|
||||
oCompareGame = DirectCast(de.Value, clsGame)
|
||||
|
||||
If oCompareGame.IsRegEx Then
|
||||
If oGame.IsRegEx Then
|
||||
If oCompareGame.ProcessName = oGame.ProcessName Then
|
||||
bIsDupe = True
|
||||
End If
|
||||
Else
|
||||
If Regex.IsMatch(oGame.ProcessName, oCompareGame.ProcessName) Then
|
||||
bIsDupe = True
|
||||
End If
|
||||
End If
|
||||
Else
|
||||
If oGame.IsRegEx Then
|
||||
If Regex.IsMatch(oCompareGame.ProcessName, oGame.ProcessName) Then
|
||||
bIsDupe = True
|
||||
End If
|
||||
Else
|
||||
If oGame.ProcessName = oCompareGame.ProcessName Then
|
||||
bIsDupe = True
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
|
||||
If bIsDupe Then
|
||||
DirectCast(hshList.Item(oCompareGame.ProcessName), clsGame).Duplicate = True
|
||||
oGame.ProcessName = oGame.CompoundKey
|
||||
oGame.Duplicate = True
|
||||
End If
|
||||
Next
|
||||
If oGame.Enabled Then hshList.Add(oGame.ProcessName, oGame)
|
||||
If oGame.Enabled Then hshList.Add(oGame.ID, oGame)
|
||||
End Select
|
||||
Next
|
||||
|
||||
@@ -413,7 +379,7 @@ Public Class mgrMonitorList
|
||||
'Core Parameters
|
||||
hshParams.Add("ID", oGame.ID)
|
||||
hshParams.Add("Name", oGame.Name)
|
||||
hshParams.Add("Process", oGame.TrueProcess)
|
||||
hshParams.Add("Process", oGame.ProcessName)
|
||||
hshParams.Add("Path", oGame.TruePath)
|
||||
hshParams.Add("AbsolutePath", oGame.AbsolutePath)
|
||||
hshParams.Add("FolderSave", oGame.FolderSave)
|
||||
|
||||
@@ -10,8 +10,6 @@ Public Class mgrProcessDetection
|
||||
Private oGame As clsGame
|
||||
Private oDuplicateGames As New ArrayList
|
||||
Private bDuplicates As Boolean
|
||||
Private bVerified As Boolean = False
|
||||
Private sFullCommand As String = String.Empty
|
||||
|
||||
Property FoundProcess As Process
|
||||
Get
|
||||
@@ -73,91 +71,32 @@ Public Class mgrProcessDetection
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Property FullCommand As String
|
||||
Get
|
||||
Return sFullCommand
|
||||
End Get
|
||||
Set(value As String)
|
||||
sFullCommand = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private Function HandleDuplicates(hshScanList As Hashtable) As Boolean
|
||||
Dim sProcess As String
|
||||
Dim sParameter As String = String.Empty
|
||||
Dim bParameter As Boolean = False
|
||||
Dim oInitialDupes As New ArrayList
|
||||
|
||||
bDuplicates = True
|
||||
oDuplicateGames.Clear()
|
||||
|
||||
|
||||
For Each o As clsGame In hshScanList.Values
|
||||
sProcess = o.ProcessName.Split(":")(0)
|
||||
If o.Duplicate And o.IsRegEx Then
|
||||
If Regex.IsMatch(prsFoundProcess.ProcessName, sProcess) Then
|
||||
oInitialDupes.Add(o.ShallowCopy)
|
||||
End If
|
||||
ElseIf o.Duplicate And Not o.IsRegEx Then
|
||||
If sProcess = prsFoundProcess.ProcessName Then
|
||||
oInitialDupes.Add(o.ShallowCopy)
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
|
||||
For Each o As clsGame In oInitialDupes
|
||||
If (o.Parameter <> String.Empty And FullCommand.Contains(o.Parameter)) Then
|
||||
sParameter = o.Parameter
|
||||
bParameter = True
|
||||
Exit For
|
||||
End If
|
||||
Next
|
||||
|
||||
If bParameter Then
|
||||
For Each o As clsGame In oInitialDupes
|
||||
If (o.Parameter = sParameter) Then
|
||||
oDuplicateGames.Add(o.ShallowCopy)
|
||||
End If
|
||||
Next
|
||||
Else
|
||||
For Each o As clsGame In oInitialDupes
|
||||
If (o.Parameter = String.Empty) Then
|
||||
oDuplicateGames.Add(o.ShallowCopy)
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
|
||||
If oDuplicateGames.Count = 1 Then
|
||||
oGame = DirectCast(oDuplicateGames(0), clsGame).ShallowCopy
|
||||
Return True
|
||||
End If
|
||||
|
||||
Return False
|
||||
End Function
|
||||
|
||||
'This function will only work correctly on Windows
|
||||
Private Sub GetWindowsCommand(ByVal prs As Process)
|
||||
FullCommand = String.Empty
|
||||
Private Function GetWindowsCommand(ByVal prs As Process) As String
|
||||
Dim sFullCommand As String = String.Empty
|
||||
Try
|
||||
Using searcher As New ManagementObjectSearcher("SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + prs.Id.ToString)
|
||||
For Each o As ManagementObject In searcher.Get()
|
||||
FullCommand &= o("CommandLine") & " "
|
||||
sFullCommand &= o("CommandLine") & " "
|
||||
Next
|
||||
End Using
|
||||
Catch ex As Exception
|
||||
Catch
|
||||
'Do Nothing
|
||||
End Try
|
||||
End Sub
|
||||
Return sFullCommand
|
||||
End Function
|
||||
|
||||
'This function will only work correctly on Unix
|
||||
Private Sub GetUnixCommand(ByVal prs As Process)
|
||||
FullCommand = String.Empty
|
||||
Private Function GetUnixCommand(ByVal prs As Process) As String
|
||||
Dim sFullCommand As String = String.Empty
|
||||
Try
|
||||
FullCommand = File.ReadAllText("/proc/" & prs.Id.ToString() & "/cmdline").Replace(vbNullChar, " ")
|
||||
sFullCommand = File.ReadAllText("/proc/" & prs.Id.ToString() & "/cmdline").Replace(vbNullChar, " ")
|
||||
Catch ex As Exception
|
||||
'Do Nothing
|
||||
End Try
|
||||
End Sub
|
||||
|
||||
Return sFullCommand
|
||||
End Function
|
||||
|
||||
'This function will only work correctly on Unix
|
||||
Private Function GetUnixProcessArguments(ByVal prs As Process) As String()
|
||||
@@ -208,14 +147,89 @@ Public Class mgrProcessDetection
|
||||
Return False
|
||||
End Function
|
||||
|
||||
Private Function GetProcessPath(ByVal bWineProcess As Boolean) As String
|
||||
Try
|
||||
If Not bWineProcess Then
|
||||
Return Path.GetDirectoryName(FoundProcess.MainModule.FileName)
|
||||
Else
|
||||
Return GetUnixSymLinkDirectory(FoundProcess)
|
||||
End If
|
||||
Catch
|
||||
Return String.Empty
|
||||
End Try
|
||||
End Function
|
||||
|
||||
Private Sub FilterDetected(ByVal oDetectedGames As ArrayList, ByVal bWineProcess As Boolean)
|
||||
Dim bMatch As Boolean = False
|
||||
Dim sProcessPath As String
|
||||
Dim sFullCommand As String
|
||||
Dim oNotDetectedWithParameters As New ArrayList
|
||||
Dim oDetectedWithParameters As New ArrayList
|
||||
Dim oDetectedWithProcessPath As New ArrayList
|
||||
|
||||
'Get parameters of the found process
|
||||
If mgrCommon.IsUnix Then
|
||||
sFullCommand = GetUnixCommand(FoundProcess)
|
||||
Else
|
||||
sFullCommand = GetWindowsCommand(FoundProcess)
|
||||
End If
|
||||
|
||||
'Look for any games using parameters and any matches
|
||||
For Each oDetectedGame As clsGame In oDetectedGames
|
||||
If oDetectedGame.Parameter <> String.Empty Then
|
||||
If sFullCommand.Contains(oDetectedGame.Parameter) Then
|
||||
oDetectedWithParameters.Add(oDetectedGame)
|
||||
Else
|
||||
oNotDetectedWithParameters.Add(oDetectedGame)
|
||||
End If
|
||||
|
||||
End If
|
||||
Next
|
||||
|
||||
'If we detected at least one parameter match, replace full detected list with the detected with parameter list
|
||||
If oDetectedWithParameters.Count > 0 Then
|
||||
oDetectedGames = oDetectedWithParameters
|
||||
Else
|
||||
'If there is no parameter match, remove any games using parameters from the detected list
|
||||
For Each oGameNotDetected As clsGame In oNotDetectedWithParameters
|
||||
oDetectedGames.Remove(oGameNotDetected)
|
||||
Next
|
||||
End If
|
||||
|
||||
'If there's only one match after parameter detection, set it as current game and we're done.
|
||||
If oDetectedGames.Count = 1 Then
|
||||
GameInfo = oDetectedGames(0)
|
||||
Duplicate = False
|
||||
Else
|
||||
'Get Process Path
|
||||
sProcessPath = GetProcessPath(bWineProcess)
|
||||
|
||||
'Check if we have any exact matches based on process path
|
||||
For Each oDetectedGame As clsGame In oDetectedGames
|
||||
If oDetectedGame.ProcessPath = sProcessPath Then
|
||||
oDetectedWithProcessPath.Add(oDetectedGame)
|
||||
End If
|
||||
Next
|
||||
|
||||
'If there's only one match after process detection, set it as current game and we're done
|
||||
If oDetectedWithProcessPath.Count = 1 Then
|
||||
GameInfo = oDetectedWithProcessPath(0)
|
||||
Duplicate = False
|
||||
Else
|
||||
'We've done all we can, the user must selected which game they were playing when the process ends
|
||||
Duplicate = True
|
||||
oDuplicateGames = oDetectedGames
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Public Function SearchRunningProcesses(ByVal hshScanList As Hashtable, ByRef bNeedsPath As Boolean, ByRef bWineProcess As Boolean, ByRef iErrorCode As Integer, ByVal bDebugMode As Boolean) As Boolean
|
||||
Dim prsList() As Process = Process.GetProcesses
|
||||
Dim sProcessCheck As String = String.Empty
|
||||
Dim sProcessList As String = String.Empty
|
||||
Dim bPass As Boolean
|
||||
Dim oDetectedGames As New ArrayList
|
||||
|
||||
For Each prsCurrent As Process In prsList
|
||||
bPass = False
|
||||
|
||||
'This needs to be wrapped due to issues with Mono.
|
||||
Try
|
||||
@@ -245,39 +259,20 @@ Public Class mgrProcessDetection
|
||||
'Do Nothing
|
||||
End Try
|
||||
|
||||
'Detection Pass 1
|
||||
For Each oCurrentGame As clsGame In hshScanList.Values
|
||||
If IsMatch(oCurrentGame, sProcessCheck) Then
|
||||
prsFoundProcess = prsCurrent
|
||||
oGame = oCurrentGame.ShallowCopy
|
||||
bPass = True
|
||||
|
||||
If mgrCommon.IsUnix Then
|
||||
GetUnixCommand(prsCurrent)
|
||||
Else
|
||||
GetWindowsCommand(prsCurrent)
|
||||
End If
|
||||
|
||||
If oGame.Duplicate = True Then
|
||||
If HandleDuplicates(hshScanList) Then
|
||||
bDuplicates = False
|
||||
oDuplicateGames.Clear()
|
||||
End If
|
||||
Else
|
||||
bDuplicates = False
|
||||
oDuplicateGames.Clear()
|
||||
End If
|
||||
|
||||
If Duplicate And DuplicateList.Count = 0 Then bPass = False
|
||||
|
||||
If oGame.Parameter <> String.Empty And Not Duplicate And Not FullCommand.Contains(oGame.Parameter) Then bPass = False
|
||||
oDetectedGames.Add(oGame.ShallowCopy)
|
||||
End If
|
||||
Next
|
||||
|
||||
'Detection Pass 2
|
||||
If bPass Then
|
||||
'Determine the process path if we need it
|
||||
If Not oGame.AbsolutePath Or oGame.Duplicate Then
|
||||
If oDetectedGames.Count > 0 Then
|
||||
FilterDetected(oDetectedGames, bWineProcess)
|
||||
End If
|
||||
|
||||
If oDetectedGames.Count > 0 Then
|
||||
If Not oGame.AbsolutePath And Not oGame.MonitorOnly Then
|
||||
Try
|
||||
If Not bWineProcess Then
|
||||
oGame.ProcessPath = Path.GetDirectoryName(prsCurrent.MainModule.FileName)
|
||||
@@ -296,24 +291,14 @@ Public Class mgrProcessDetection
|
||||
iErrorCode = 299
|
||||
Else
|
||||
If bDebugMode Then mgrCommon.ShowMessage(exWin32.NativeErrorCode & " " & exWin32.Message & vbCrLf & vbCrLf & exWin32.StackTrace, MsgBoxStyle.Critical)
|
||||
'A different failure occured, drop out and continue to scan.
|
||||
bPass = False
|
||||
Return False
|
||||
End If
|
||||
Catch exAll As Exception
|
||||
If bDebugMode Then mgrCommon.ShowMessage(exAll.Message & vbCrLf & vbCrLf & exAll.StackTrace, MsgBoxStyle.Critical)
|
||||
'A different failure occured, drop out and continue to scan.
|
||||
bPass = False
|
||||
Return False
|
||||
End Try
|
||||
End If
|
||||
|
||||
'This will force two cycles for detection to try and prevent issues with UAC prompt
|
||||
If Not bVerified Then
|
||||
bVerified = True
|
||||
Return False
|
||||
Else
|
||||
bVerified = False
|
||||
Return True
|
||||
End If
|
||||
Return True
|
||||
End If
|
||||
Next
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ Public Class mgrRestore
|
||||
If oGame.ProcessPath <> String.Empty Then
|
||||
oRestoreInfo.RelativeRestorePath = oGame.ProcessPath & Path.DirectorySeparatorChar & oRestoreInfo.RestorePath
|
||||
Else
|
||||
sProcess = oGame.TrueProcess
|
||||
sProcess = oGame.ProcessName
|
||||
If mgrCommon.IsProcessNotSearchable(oGame) Then bNoAuto = True
|
||||
sRestorePath = mgrPath.ProcessPathSearch(oRestoreInfo.Name, sProcess, mgrCommon.FormatString(mgrRestore_RelativeNeedPath, oRestoreInfo.Name), bNoAuto)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user