#include <Date.au3>
; *************************************************************************************************************;; Script to start the Matlab and Maple update install and keep them alive until the their setup.exe program finishes. This script is used by the Matlab ; and Maple WPKG program.; It's not as simple as making sure the process setup.exe is still running as there may already be a process running called ; setup.exe. We need; to look for the one that has the string matlab in the processes execute command line. To make things harder, the matlab setup.exe seems to; seems to start with one pid for the exe, this then seems to spawn a new setup.exe with another pid so we can't simple launch the original setup.exe, note
; its pid and then keep an eye on it, we need to keep looking for the pid for the process setup.exe with the string matlab in the execute command.
; This is where the function _ProcessListProperties (http://www.autoitscript.com/forum/topic/70538-processlistproperties/) is used.
;; A log file is made in the %TEMP% of the user running this script. It's called [arg1's process.exe].log;; C. Mortimer @damtp.cam.ca.uk - April 2011;; *************************************************************************************************************
Opt("TrayMenuMode", 1) ; Default tray menu items (Script Paused/Exit) will not be shown.
Else
Exit ; not really going to be run without compiling it
; UNCOMMENT LINES BELOW FOR TESTING
;~ $install_prog = "c:\Program Files\Windows NT\Accessories\wordpad.exe"
;~ $call_argument_wth = "foo"
;~ $config_file = "wibble"
;~ $wait_time = 2 * 1000
; UNCOMMENT LINES ABOVE FOR TESTING
EndIf
Dim $oWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2"), $commandline, $arg_found, $pid
$q = 1
$process_name = StringTrimLeft($install_prog, StringInStr($install_prog, "\", 0, -1))
$log = EnvGet("temp") & "\" & $process_name & "_install.log" ; delete the old log file
If FileGetSize ($log) > 5000000 Then FileCopy ($log, EnvGet("temp") & "\" & $process_name & "_install.old.log", 1)
_log("")
_log("")
_log("")
$run_install = Run($install_prog & " " & $call_argument_wth & " " & $config_file) ; Run the installer...
$log = FileOpen(EnvGet_log("tempNow starting.") & "\" & $process_name @CRLF & "_install.log", 2) ; Open the log file deleting all existing dataFileWriteLine($log, "Now starting. * Program to run = '" & $install_prog & "', argument " & @CRLF & "* Argument required to call in config file ='" & _ $call_argument_wth & "'," & @CRLF & "config * Config file = '" & $config_file & "', search " & @CRLF & "* Search string = '" & $install_prog & "', wait " & @CRLF & _ "* Wait before monitoring = '" & $wait_time / 1000 & "s'. [PID = '" & $run_install & "'] [" & @MDAY & "/" & @MON & "/" & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & "]")FileClose($log)
Sleep($wait_time)
While $q = 1
$log arg_found = FileOpen(EnvGet0 $o_ColListOfProcesses = $oWMIService.ExecQuery("temp") & "\SELECT * FROM Win32_Process WHERE Name = '" & $process_name & "_install.log'", 1) ; append to the log file For $o_ObjProcess In $o_ColListOfProcesses $avRET commandline = _ProcessListProperties($process_name)o_ObjProcess.CommandLine $array_search stringinstring = _ArraySearchStringInStr($avRETcommandline, $call_argument_wth, "", "", 0, 1config_file) If $stringinstring > 0 Then $arg_found = $o_ObjProcess.Handle ; set $arg_found to the PID EndIf Next If $array_search arg_found >= 0 Then FileWriteLine_log($log, $process_name & " still running... [PID = '" & $avRET[$array_search][1] arg_found & "'] [" & @MDAY ) ConsoleWrite($process_name & "/is running with a PID of " & @MON & "/" $arg_found & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & "]") FileClose($logCRLF)
Else
FileWriteLine_log($log, "Now exiting, " & $process_name & " no long isn't running. [" & @MDAY ) ConsoleWrite($process_name & "/isn't running, ending" & @MON & "/" & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & "]") FileClose($logCRLF)
$q = 2
EndIf
Sleep(5000)
WEnd
;===============================================================================; Function Name: _ProcessListPropertiesFunc _log(); Description: Get various properties of a process, or all processes; Call With: _ProcessListProperties( [$Process [, $sComputer]] text); Parameter FileOpen(s): EnvGet(optional) $Process - PID or name of a process, default is "temp" (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 = process_name & "_install.log") 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 append to WMI and get process objectsthe log file FileWriteLine($oWMI = ObjGet("winmgmts:{impersonationLevel=impersonatelog,authenticationLevel=pktPrivacy, (Debug)}!\\" & $sComputer text & "\root\cimv2[") If IsObj($oWMI) Then ; Get collection processes from Win32_Process If $Process == & @MDAY & "" 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(@MON & "select * from win32_process where Name = '/" & $Process @YEAR & "'") 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 & @HOUR & "\:" & $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 <> @MIN & "" 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, & @SEC & "$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 FileClose($oWMI, "Win32_PerfFormattedData_PerfProc_Process" log).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 $avProcsEndFunc ;==>_ProcessListProperties_log
</pre>