From 4c76eb7a8294c978b6a3f626a2ee2d2e5416ae3b Mon Sep 17 00:00:00 2001 From: David <8304331+kadrim@users.noreply.github.com> Date: Sun, 10 Feb 2019 00:41:37 +0100 Subject: [PATCH] initial version --- PrimoCacheBackupDetect.au3 | 209 +++++++++++++++++++++++++++++++++++++++++++++ PrimoCacheBackupDetect.ini | 6 ++ _ProcessListProperties.au3 | 128 +++++++++++++++++++++++++++ 3 files changed, 343 insertions(+) create mode 100644 PrimoCacheBackupDetect.au3 create mode 100644 PrimoCacheBackupDetect.ini create mode 100644 _ProcessListProperties.au3 diff --git a/PrimoCacheBackupDetect.au3 b/PrimoCacheBackupDetect.au3 new file mode 100644 index 0000000..aec3e42 --- /dev/null +++ b/PrimoCacheBackupDetect.au3 @@ -0,0 +1,209 @@ +#NoTrayIcon +#RequireAdmin +#AutoIt3Wrapper_Res_Fileversion=0.0.1.0 + +#include +#include ; +#include +#include "_ProcessListProperties.au3" + +Opt("TrayMenuMode", 3); + +Global Const $iconFile = "shell32.dll"; +Global Const $idIconError = -110 +Global Const $idIconRunning = -138 +Global Const $idIconPaused = -245 + +Global $sTaskDir = '' +Global $sTaskName = 'PrimoCacheBackupDetect' +Global $sTaskFullName = $sTaskDir & '\' & $sTaskName + +ReadConfig() +PrimoCacheBackupDetect() + +Func ReadConfig() + Global Const $configFile = @ScriptDir & "\PrimoCacheBackupDetect.ini" + Global $configInterval = Int(IniRead($configFile, "Config", "Interval", "10000")) + Global $configProcess = IniRead($configFile, "Config", "Process", "backupService-ab.exe") + Global $configThreshold = Int(IniRead($configFile, "Config", "Threshold", "50000000")) + Global $configPauseCmd = IniRead($configFile, "Config", "PauseCmd", '"C:\Program Files\PrimoCache\rxpcc.exe" pause -s -a') + Global $configResumeCmd = IniRead($configFile, "Config", "ResumeCmd", '"C:\Program Files\PrimoCache\rxpcc.exe" resume -s -a') +EndFunc + +Func PrimoCacheBackupDetect() + Local $idCheckProcess = TrayCreateItem("Check Process") + Global $idTask = TrayCreateItem("-") + RenameTrayTask() + Local $idExit = TrayCreateItem("Exit") + + TraySetIcon($iconFile, $idIconRunning) + TraySetToolTip("PrimoCache running, no Backup-Process detected.") + TraySetState($TRAY_ICONSTATE_SHOW) + + Local $hTimer = TimerInit() ; Begin the timer and store the handle in a variable. + Local $fDiff = 0 + Local $isRunning = 0, $wasRunning = 0 + + Local $processList + + While 1 + $fDiff = TimerDiff($hTimer) ; Find the difference in time from the previous call of TimerInit + If $fDiff > $configInterval Then ; If the difference is greater than interval then check if the named process is running + 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 + EndIf + EndIf + If $isRunning == 1 Then + If $wasRunning == 0 Then + PauseCache() + EndIf + $wasRunning = 1 + Else + If $wasRunning == 1 Then + ResumeCache() + EndIf + $wasRunning = 0 + EndIf + $hTimer = TimerInit() ; Reset the timer. + EndIf + + Switch TrayGetMsg() + Case $idExit ; Exit the loop. + ExitLoop + Case $idCheckProcess + CheckProcess() + Case $idTask + If IsTaskInstalled() Then + If Not UninstallTask() Then + MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONERROR), "Error!", "Could not remove Autostart!") + EndIf + Else + If MsgBox($MB_ICONQUESTION + $MB_YESNO, 'Proceed with Installation?', 'This will install a new scheduled Task to run this Program on boot.' & @CRLF & 'The Program has to remain at the current location which is: ' & @ScriptFullPath & @CRLF & @CRLF & 'Do you want to proceed?') = $IDYES Then + If Not InstallTask() Then + MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONERROR), "Error!", "Could not create Autostart!") + EndIf + EndIf + EndIf + RenameTrayTask() + EndSwitch + WEnd +EndFunc + +Func PauseCache() + Local $iPID = Run(@ComSpec & ' /C ' & $configPauseCmd, @SystemDir, @SW_HIDE, BitOR($STDERR_CHILD, $STDOUT_CHILD)) + ProcessWaitClose($iPID) + Local $sOutput = StdoutRead($iPID) + Local $sError = StderrRead($iPID) + If $sError <> "" Then + TraySetToolTip("Could not switch PrimoCache! An Error occured!") + TraySetIcon($iconFile, $idIconError) + MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONERROR), "Could not pause the PrimoCache!", $sError) + Else + TraySetToolTip("PrimoCache paused, Process " & $configProcess & " is running.") + TraySetIcon($iconFile, $idIconPaused) + EndIf +EndFunc + +Func ResumeCache() + Local $iPID = Run(@ComSpec & ' /C ' & $configResumeCmd, @SystemDir, @SW_HIDE, BitOR($STDERR_CHILD, $STDOUT_CHILD)) + ProcessWaitClose($iPID) + Local $sOutput = StdoutRead($iPID) + Local $sError = StderrRead($iPID) + If $sError <> "" Then + TraySetToolTip("Could not switch PrimoCache! An Error occured!") + TraySetIcon($iconFile, $idIconError) + MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONERROR), "Could not resume the PrimoCache!", $sError) + Else + TraySetToolTip("PrimoCache running, no Backup-Process detected.") + TraySetIcon($iconFile, $idIconRunning) + EndIf +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 + 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.") + EndIf + Else + MsgBox($MB_SYSTEMMODAL, "Process not running", "The configured process " & $configProcess & " is not running.") + EndIf +EndFunc + +Func InstallTask() + Local $sXML = _ + '' & @CRLF & _ + '' & @CRLF & _ + ' ' & @CRLF & _ + ' ' & @CRLF & _ + ' true' & @CRLF & _ + ' ' & @CRLF & _ + ' ' & @CRLF & _ + ' ' & @CRLF & _ + ' ' & @CRLF & _ + ' S-1-1-0' & @CRLF & _ + ' HighestAvailable' & @CRLF & _ + ' ' & @CRLF & _ + ' ' & @CRLF & _ + ' ' & @CRLF & _ + ' IgnoreNew' & @CRLF & _ + ' false' & @CRLF & _ + ' false' & @CRLF & _ + ' true' & @CRLF & _ + ' false' & @CRLF & _ + ' false' & @CRLF & _ + ' ' & @CRLF & _ + ' false' & @CRLF & _ + ' false' & @CRLF & _ + ' ' & @CRLF & _ + ' true' & @CRLF & _ + ' true' & @CRLF & _ + ' false' & @CRLF & _ + ' false' & @CRLF & _ + ' false' & @CRLF & _ + ' true' & @CRLF & _ + ' false' & @CRLF & _ + ' PT0S' & @CRLF & _ + ' 7' & @CRLF & _ + ' ' & @CRLF & _ + ' ' & @CRLF & _ + ' ' & @CRLF & _ + ' ###FILE###' & @CRLF & _ + ' ' & @CRLF & _ + ' ' & @CRLF & _ + '' + $sXML = StringReplace($sXML, '###FILE###', @ScriptFullPath) + Local $sFileXML = @TempDir & '\' & $sTaskName & '.xml' + FileDelete($sFileXML) + FileWrite($sFileXML, $sXML) + If FileRead($sFileXML) <> $sXML Then Return False + If RunWait('schtasks.exe /Create /XML "' & $sFileXML & '" /TN ' & $sTaskFullName, '', @SW_HIDE) <> 0 Then Return False + FileDelete($sFileXML) + Return True +EndFunc + +Func UninstallTask() + ;RunWait('schtasks.exe /End /TN ' & $sTaskFullName, '', @SW_HIDE) + If RunWait('schtasks.exe /Delete /F /TN ' & $sTaskFullName, '', @SW_HIDE) <> 0 Then Return False + Return True +EndFunc + +Func IsTaskInstalled() + If RunWait('schtasks.exe /Query /TN ' & $sTaskFullName, '', @SW_HIDE) <> 0 Then Return False + Return True +EndFunc + +Func RenameTrayTask() + If IsTaskInstalled() Then + TrayItemSetText($idTask, "Remove Autostart") + Else + TrayItemSetText($idTask, "Set Autostart on Boot") + EndIf +EndFunc \ No newline at end of file diff --git a/PrimoCacheBackupDetect.ini b/PrimoCacheBackupDetect.ini new file mode 100644 index 0000000..d65014f --- /dev/null +++ b/PrimoCacheBackupDetect.ini @@ -0,0 +1,6 @@ +[Config] +Interval=10000 +Process=backupService-ab.exe +Threshold=50000000 +PauseCmd="C:\Program Files\PrimoCache\rxpcc.exe" pause -s -a +ResumeCmd="C:\Program Files\PrimoCache\rxpcc.exe" resume -s -a diff --git a/_ProcessListProperties.au3 b/_ProcessListProperties.au3 new file mode 100644 index 0000000..9bfb0a6 --- /dev/null +++ b/_ProcessListProperties.au3 @@ -0,0 +1,128 @@ +;=============================================================================== +; 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