From 2d4c150768fcf5c106c8782e46a854839b0cd55f Mon Sep 17 00:00:00 2001 From: David <8304331+kadrim@users.noreply.github.com> Date: Tue, 12 Feb 2019 21:52:16 +0100 Subject: [PATCH 1/3] not needed anymore --- _ProcessListProperties.au3 | 128 --------------------------------------------- 1 file changed, 128 deletions(-) delete mode 100644 _ProcessListProperties.au3 diff --git a/_ProcessListProperties.au3 b/_ProcessListProperties.au3 deleted file mode 100644 index 9bfb0a6..0000000 --- a/_ProcessListProperties.au3 +++ /dev/null @@ -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 \ No newline at end of file From e1c86838ec44d94f69f812ef4e5648e87a5f7bb3 Mon Sep 17 00:00:00 2001 From: David <8304331+kadrim@users.noreply.github.com> Date: Tue, 12 Feb 2019 21:53:04 +0100 Subject: [PATCH 2/3] removed UDF from PsaltyDS because it would lead to memory leaks on Windows XP --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 380da2e..a1ad421 100644 --- a/README.md +++ b/README.md @@ -51,9 +51,6 @@ This will remove the previously created scheduled task. ## Compiling 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 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. From 257b8f0ef76823cdde26cdd4ad9f498ab929630e Mon Sep 17 00:00:00 2001 From: David <8304331+kadrim@users.noreply.github.com> Date: Tue, 12 Feb 2019 21:53:55 +0100 Subject: [PATCH 3/3] added own implementation to get the memory-footprint of a process --- PrimoCacheBackupDetect.au3 | 74 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 9 deletions(-) diff --git a/PrimoCacheBackupDetect.au3 b/PrimoCacheBackupDetect.au3 index 497e680..3bcd771 100644 --- a/PrimoCacheBackupDetect.au3 +++ b/PrimoCacheBackupDetect.au3 @@ -1,11 +1,15 @@ #NoTrayIcon #RequireAdmin -#AutoIt3Wrapper_Res_Fileversion=0.0.3.0 +#AutoIt3Wrapper_Res_Fileversion=0.0.4.0 #include #include #include -#include "_ProcessListProperties.au3" +#include +#include +#include +#include +#include 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 $isRunning = 0 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 - If $processList[1][7] > $configThreshold Then - $isRunning = 1 + Local $pData = GetProcessDetails($configProcess) + If $pData <> False Then + If $pData[2] > $configThreshold Then + $isRunning = 1 + EndIf EndIf EndIf If $isRunning == 1 Then @@ -124,10 +130,12 @@ Func ResumeCache() EndFunc Func CheckProcess() - 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 - 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 $processList[1][7] > $configThreshold Then + If ProcessExists($configProcess) Then + Local $pData = GetProcessDetails($configProcess) + If $pData == False Then Return False + + 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.") Else 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 TrayItemSetText($idTask, "Set Autostart on Boot") 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 \ No newline at end of file