Merge pull request #6 from kadrim/replace-memory-function

Replace memory function
This commit is contained in:
David
2019-02-12 21:58:56 +01:00
committed by GitHub
3 changed files with 65 additions and 140 deletions

View File

@@ -1,11 +1,15 @@
#NoTrayIcon #NoTrayIcon
#RequireAdmin #RequireAdmin
#AutoIt3Wrapper_Res_Fileversion=0.0.3.0 #AutoIt3Wrapper_Res_Fileversion=0.0.4.0
#include <AutoItConstants.au3> #include <AutoItConstants.au3>
#include <TrayConstants.au3> #include <TrayConstants.au3>
#include <MsgBoxConstants.au3> #include <MsgBoxConstants.au3>
#include "_ProcessListProperties.au3" #include <ProcessConstants.au3>
#include <SecurityConstants.au3>
#include <Security.au3>
#include <WinAPI.au3>
#include <WinAPIProc.au3>
Opt("TrayMenuMode", 3) Opt("TrayMenuMode", 3)
@@ -52,9 +56,11 @@ Func PrimoCacheBackupDetect()
TraySetState($TRAY_ICONSTATE_SHOW) ; try to show the trayicon if it has not been initialized correctly on startup, due to a premature boot via scheduled tasks TraySetState($TRAY_ICONSTATE_SHOW) ; try to show the trayicon if it has not been initialized correctly on startup, due to a premature boot via scheduled tasks
$isRunning = 0 $isRunning = 0
If ProcessExists($configProcess) Then ; Check if the process is running. If ProcessExists($configProcess) Then ; Check if the process is running.
$processList = _ProcessListProperties($configProcess) ; check if the process has a memory consumption higher than the configured threshold Local $pData = GetProcessDetails($configProcess)
If $processList[1][7] > $configThreshold Then If $pData <> False Then
$isRunning = 1 If $pData[2] > $configThreshold Then
$isRunning = 1
EndIf
EndIf EndIf
EndIf EndIf
If $isRunning == 1 Then If $isRunning == 1 Then
@@ -124,10 +130,12 @@ Func ResumeCache()
EndFunc EndFunc
Func CheckProcess() Func CheckProcess()
If ProcessExists($configProcess) Then ; Check if the process is running. If ProcessExists($configProcess) Then
$processList = _ProcessListProperties($configProcess) ; check if the process has a memory consumption higher than the configured threshold Local $pData = GetProcessDetails($configProcess)
MsgBox($MB_SYSTEMMODAL, "Process-Details", $processList[1][0] & @CRLF & "PID: " & $processList[1][1] & @CRLF & "PPID: " & $processList[1][2] & @CRLF & "OWNER: " & $processList[1][3] & @CRLF & "PRIORITY: " & $processList[1][4] & @CRLF & "PATH: " & $processList[1][5] & @CRLF &"CPU: " & $processList[1][6] & @CRLF &"MEMORY: " & $processList[1][7] & @CRLF &"CREATION: " & $processList[1][8] & @CRLF &"CLI: " & $processList[1][9]) If $pData == False Then Return False
If $processList[1][7] > $configThreshold Then
MsgBox($MB_SYSTEMMODAL, "Process-Details", $configProcess & @CRLF & "number of page faults: " & $pData[0] & @CRLF & "The peak working set size, in bytes: " & $pData[1] & @CRLF & "current working set size, in bytes: " & $pData[2] & @CRLF & "peak paged pool usage, in bytes: " & $pData[3] & @CRLF & "current paged pool usage, in bytes: " & $pData[4] & @CRLF & "peak nonpaged pool usage, in bytes: " & $pData[5] & @CRLF & "current nonpaged pool usage, in bytes: " & $pData[6] & @CRLF & "current space allocated for the pagefile, in bytes: " & $pData[7] & @CRLF & "peak space allocated for the pagefile, in bytes: " & $pData[8] & @CRLF & "current amount of memory that cannot be shared with other processes, in bytes: " & $pData[9])
If $pData[2] > $configThreshold Then
MsgBox($MB_SYSTEMMODAL, "Threshold reached", "The process " & $configProcess & " has reached the configured Threshold of " & $configThreshold & " Bytes.") MsgBox($MB_SYSTEMMODAL, "Threshold reached", "The process " & $configProcess & " has reached the configured Threshold of " & $configThreshold & " Bytes.")
Else Else
MsgBox($MB_SYSTEMMODAL, "Threshold not reached", "The process " & $configProcess & " has not reached the configured Threshold of " & $configThreshold & " Bytes.") MsgBox($MB_SYSTEMMODAL, "Threshold not reached", "The process " & $configProcess & " has not reached the configured Threshold of " & $configThreshold & " Bytes.")
@@ -206,4 +214,52 @@ Func RenameTrayTask()
Else Else
TrayItemSetText($idTask, "Set Autostart on Boot") TrayItemSetText($idTask, "Set Autostart on Boot")
EndIf EndIf
EndFunc
Func GetProcessDetails($sProcess = "")
If ProcessExists($sProcess) Then ; Check if the process is running.
; Open the current process in ALL ACCESS mode, with no inheritance for child processes.
Local $hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, @AutoItPID)
; If the function failed, return False.
If $hProcess = 0 Then Return False
; Open the access token associated with the current process (an access token contains
; the security information for a logon session.
; What matter to us is the privileges contained by this token.
Local $hToken = _Security__OpenProcessToken($hProcess, $TOKEN_ALL_ACCESS)
; If the function failed, return False.
If $hToken = 0 Then Return False
; Close the current process handle.
_WinAPI_CloseHandle($hProcess)
; Retrieves the LUID (locally unique identifier) which represents the SE_DEBUG privilege.
Local $iLUID = _Security__LookupPrivilegeValue("", $SE_DEBUG_NAME)
; If the function failed, return False.
If $iLUID = 0 Then Return False
; Create a struct containing the TOKEN_PRIVILEGES tag.
Local $tTOKENPRIV = DllStructCreate($tagTOKEN_PRIVILEGES)
; Fill the struct with the right infos.
DllStructSetData($tTOKENPRIV, "Count", 1)
DllStructSetData($tTOKENPRIV, "LUID", $iLUID, 1)
DllStructSetData($tTOKENPRIV, "Attributes", $SE_PRIVILEGE_ENABLED, 1)
; Now adjust the token privilege to enable the DEBUG privilege.
Local $fAdjust = _Security__AdjustTokenPrivileges($hToken, False, DllStructGetPtr($tTOKENPRIV), DllStructGetSize($tTOKENPRIV))
; If the function failed, return False.
If Not $fAdjust Then Return False
; Release the resources used by the structure.
$tTOKENPRIV = 0
Local $pData = _WinAPI_GetProcessMemoryInfo(ProcessExists($sProcess))
_WinAPI_CloseHandle($hToken)
Return $pData
Else
Return False
EndIf
EndFunc EndFunc

View File

@@ -51,9 +51,6 @@ This will remove the previously created scheduled task.
## Compiling ## Compiling
Clone this repository and compile the Program using [AutoIt v3](https://www.autoitscript.com/site/) Clone this repository and compile the Program using [AutoIt v3](https://www.autoitscript.com/site/)
## Thanks
Many Thanks to [PsaltyDS](http://www.autoitscript.com/forum) for his great UDF [_ProcessListProperties()](https://www.autoitscript.com/forum/topic/70538-_processlistproperties/)
## Disclaimer ## Disclaimer
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,128 +0,0 @@
;===============================================================================
; Function Name: _ProcessListProperties()
; Description: Get various properties of a process, or all processes
; Call With: _ProcessListProperties( [$Process [, $sComputer]] )
; Parameter(s): (optional) $Process - PID or name of a process, default is "" (all)
; (optional) $sComputer - remote computer to get list from, default is local
; Requirement(s): AutoIt v3.2.4.9+
; Return Value(s): On Success - Returns a 2D array of processes, as in ProcessList()
; with additional columns added:
; [0][0] - Number of processes listed (can be 0 if no matches found)
; [1][0] - 1st process name
; [1][1] - 1st process PID
; [1][2] - 1st process Parent PID
; [1][3] - 1st process owner
; [1][4] - 1st process priority (0 = low, 31 = high)
; [1][5] - 1st process executable path
; [1][6] - 1st process CPU usage
; [1][7] - 1st process memory usage
; [1][8] - 1st process creation date/time = "MM/DD/YYY hh:mm:ss" (hh = 00 to 23)
; [1][9] - 1st process command line string
; ...
; [n][0] thru [n][9] - last process properties
; On Failure: Returns array with [0][0] = 0 and sets @Error to non-zero (see code below)
; Author(s): PsaltyDS at http://www.autoitscript.com/forum
; Date/Version: 12/01/2009 -- v2.0.4
; Notes: If an integer PID or string process name is provided and no match is found,
; then [0][0] = 0 and @error = 0 (not treated as an error, same as ProcessList)
; This function requires admin permissions to the target computer.
; All properties come from the Win32_Process class in WMI.
; To get time-base properties (CPU and Memory usage), a 100ms SWbemRefresher is used.
;===============================================================================
Func _ProcessListProperties($Process = "", $sComputer = ".")
Local $sUserName, $sMsg, $sUserDomain, $avProcs, $dtmDate
Local $avProcs[1][2] = [[0, ""]], $n = 1
; Convert PID if passed as string
If StringIsInt($Process) Then $Process = Int($Process)
; Connect to WMI and get process objects
$oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy, (Debug)}!\\" & $sComputer & "\root\cimv2")
If IsObj($oWMI) Then
; Get collection processes from Win32_Process
If $Process == "" Then
; Get all
$colProcs = $oWMI.ExecQuery("select * from win32_process")
ElseIf IsInt($Process) Then
; Get by PID
$colProcs = $oWMI.ExecQuery("select * from win32_process where ProcessId = " & $Process)
Else
; Get by Name
$colProcs = $oWMI.ExecQuery("select * from win32_process where Name = '" & $Process & "'")
EndIf
If IsObj($colProcs) Then
; Return for no matches
If $colProcs.count = 0 Then Return $avProcs
; Size the array
ReDim $avProcs[$colProcs.count + 1][10]
$avProcs[0][0] = UBound($avProcs) - 1
; For each process...
For $oProc In $colProcs
; [n][0] = Process name
$avProcs[$n][0] = $oProc.name
; [n][1] = Process PID
$avProcs[$n][1] = $oProc.ProcessId
; [n][2] = Parent PID
$avProcs[$n][2] = $oProc.ParentProcessId
; [n][3] = Owner
If $oProc.GetOwner($sUserName, $sUserDomain) = 0 Then $avProcs[$n][3] = $sUserDomain & "\" & $sUserName
; [n][4] = Priority
$avProcs[$n][4] = $oProc.Priority
; [n][5] = Executable path
$avProcs[$n][5] = $oProc.ExecutablePath
; [n][8] = Creation date/time
$dtmDate = $oProc.CreationDate
If $dtmDate <> "" Then
; Back referencing RegExp pattern from weaponx
Local $sRegExpPatt = "\A(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(?:.*)"
$dtmDate = StringRegExpReplace($dtmDate, $sRegExpPatt, "$2/$3/$1 $4:$5:$6")
EndIf
$avProcs[$n][8] = $dtmDate
; [n][9] = Command line string
$avProcs[$n][9] = $oProc.CommandLine
; increment index
$n += 1
Next
Else
SetError(2); Error getting process collection from WMI
EndIf
; release the collection object
$colProcs = 0
; Get collection of all processes from Win32_PerfFormattedData_PerfProc_Process
; Have to use an SWbemRefresher to pull the collection, or all Perf data will be zeros
Local $oRefresher = ObjCreate("WbemScripting.SWbemRefresher")
$colProcs = $oRefresher.AddEnum($oWMI, "Win32_PerfFormattedData_PerfProc_Process" ).objectSet
$oRefresher.Refresh
; Time delay before calling refresher
Local $iTime = TimerInit()
Do
Sleep(20)
Until TimerDiff($iTime) >= 100
$oRefresher.Refresh
; Get PerfProc data
For $oProc In $colProcs
; Find it in the array
For $n = 1 To $avProcs[0][0]
If $avProcs[$n][1] = $oProc.IDProcess Then
; [n][6] = CPU usage
$avProcs[$n][6] = $oProc.PercentProcessorTime
; [n][7] = memory usage
$avProcs[$n][7] = $oProc.WorkingSet
ExitLoop
EndIf
Next
Next
Else
SetError(1); Error connecting to WMI
EndIf
; Return array
Return $avProcs
EndFunc ;==>_ProcessListProperties