ElfCabbage Posted March 19, 2014 Share Posted March 19, 2014 Here is code for a file listener. It takes an .ini file for specifics (directory, file name) and it will execute multiple actions once it finds the files. expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_outfile=Listener.exe #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #Include <File.au3> #Include <Array.au3> #Include <Constants.au3> Opt("TrayOnEventMode",1) Opt("TrayMenuMode",0) Opt("TrayAutoPause",0) ;Set log file location $g_logFile = @ScriptDir & "\listener.log" ;***********************DON'T CHANGE BELOW THIS AREA**************************** ;sets build reference $g_iniFile = getIniFile() $g_ArrayBaseSize = IniReadSection ( $g_iniFile, "Products" ) dim $g_manLaunch[UBound($g_ArrayBaseSize)] dim $g_ExecuteArray[24][60][7] dim $g_pid[20] dim $g_WaitTime[3] func main() dim $ExamineBuild $TimeOut = 2000 ;$g_iniFile = $CmdLine[1] $i = 1 ;$ProductName = IniRead($g_iniFile,"Products",$i,"1") ;This product name will be displayed just before executing. This helps when executing with multiple products. $Array_LaunchOrder = IniReadSection ( $g_iniFile, "Products" ) ;declaring public variable $n = UBound($Array_LaunchOrder) dim $Build[$n] ; creates tray menu items to launch specific launchOrder items For $q =1 to $n-1 Step 1 ; loop to set array of Tray Menu Items $g_manLaunch[$q] = TrayCreateItem(IniRead($g_iniFile,"Products",$q,"1")) TrayItemSetOnEvent(-1,"singleExecute") ;MsgBox(0,"id",TrayItemGetText($g_manLaunch[$q])) Next TraySetState() ;Credentials to build directory ;$Networkshare = ;$UserName = ;$NetworkPassword = ;MountBuild($Networkshare, $UserName, $NetworkPassword);Ensures credentials to build directory Do For $i = 1 To $n-1 Step 1 ;this for loop is to cycle through install dirs checking for new builds of multiple products $CurrentSection = $Array_LaunchOrder[$i][1] $BuildDir = IniRead($g_iniFile,$CurrentSection,"BuildDir","1") $BuildSuffix = IniRead($g_iniFile,$CurrentSection,"BuildSuffix","1") $StripPrefix = IniRead($g_iniFile,$CurrentSection,"BuildPrefix","LotR") $BuildFinish = IniRead($g_iniFile,$CurrentSection,"BuildFinish","cabbage") $PassDir = IniRead($g_iniFile,$CurrentSection,"PassDir","elf") $ExecuteWait = IniRead($g_iniFile,$CurrentSection,"ExecuteWait","90") ;Individual credentials for each section $Networkshare = IniRead($g_iniFile,$CurrentSection,"NetworkShare","") $UserName = IniRead($g_iniFile,$CurrentSection,"UserName","") $NetworkPassword = IniRead($g_iniFile,$CurrentSection,"NetworkPassword","") if $Networkshare <> "" then MountBuild($Networkshare, $UserName, $NetworkPassword);Ensures credentials to build directory if Not $Build[$i] Then $Build[$i]=LocateBuildNumber($BuildDir,$StripPrefix);Sets the initual build number if $Build[$i] <> 0 Then $answer = MsgBox(260, "Listener - " & $CurrentSection, "Start execution for " & $CurrentSection & " build " & $Build[$i] & "? Will default to ""No"" after 20 seconds.", 20) If $answer = 6 Then _FileWriteLog($g_logFile, "User chose to start execution for " & $CurrentSection & ", build " & $Build[$i] ) $Preempted = Preempt($CurrentSection) If $Preempted = 0 Then ExecuteScript(1,$Build[$i],$g_iniFile,$CurrentSection,$PassDir) EndIf EndIf $ExamineBuild = $Build[$i] $TimeOut = 1000 EndIf Else $TimeOut = IniRead($g_iniFile,"Timeout","wait","300000") EndIf $ExamineBuild = LocateBuildNumber($BuildDir,$StripPrefix) _FileWriteLog($g_logFile,"For product: " & $CurrentSection & " the current build #'s are: " & $ExamineBuild & ", " & $Build[$i] & " (new, existing).") If ($ExamineBuild <> $Build[$i] And $ExamineBuild <> 0 And $Build[$i] <> 0) Then $TimedOutWaiting = BuildNumSuffixWait($BuildFinish) if $TimedOutWaiting = 0 Then $DoneAlready = CheckExecution($CurrentSection) $Preempted = Preempt($CurrentSection) ;MsgBox(0,"there?",$DoneAlready) if $DoneAlready = 50 Then _FileWriteLog($g_logFile, "Execution for " & $CurrentSection & ", build " & $Build[$i] & " has run in the last " & $ExecuteWait & " minutes. Skipping execution.") ElseIf $Preempted = 0 Then ExecuteScript (0,$ExamineBuild,$g_iniFile,$CurrentSection,$PassDir) $Build[$i] = $ExamineBuild EndIf ElseIf $TimedOutWaiting = 18 Then _FileWriteLog($g_logFile, "Continuing to listen. Skipped execution from " & $CurrentSection & ".") EndIf EndIf ClearExecution($CurrentSection) Next sleep ($TimeOut) ; Sleep 5 minutes Until 0 EndFunc ;This function is for the execution of a single process via the Tray menu. Func singleExecute() $Array_LaunchOrder = IniReadSection ( $g_iniFile, "Products" ) $b = UBound($g_ArrayBaseSize) For $y = 1 to $b-1 Step 1 $msg = TrayItemGetState($g_manLaunch[$y]) Select Case $msg = 68 ContinueLoop Case $msg = 65 $CurrentSection = TrayItemGetText($g_manLaunch[$y]) $buildDir = IniRead($g_iniFile,$CurrentSection,"BuildDir","1") $StripPrefix = IniRead($g_iniFile,$CurrentSection,"BuildPrefix","cabbage" ) $buildNum = LocateBuildNumber($buildDir,$StripPrefix) _FileWriteLog($g_logFile,"starting " & $CurrentSection & " from system tray selection.") ExecuteScript(0,$buildNum,$g_iniFile,$CurrentSection,1) TrayItemSetState($g_manLaunch[$y],$TRAY_UNCHECKED) ExitLoop EndSelect Next EndFunc ; This function calculates the time wait period based on the time wait value in the ini file and the current time. func CalcExecutionTime($CurrentSection) $ExecuteWait = IniRead($g_iniFile,$CurrentSection,"ExecuteWait","90") $theHour = @HOUR $theMin = @MIN $Hours = Floor($ExecuteWait/60) $Mins = Mod ($ExecuteWait,60) $Mins = $theMin - $Mins If $Mins < 0 Then $theHour = $theHour - 1 $Mins = 59 + $Mins EndIf $Hours = $theHour - $Hours If $Hours < 0 Then $Hours = 23 + $Hours EndIf $g_WaitTime[1] = $Hours $g_WaitTime[2] = $Mins EndFunc ; This function checks to see whether the current product has been executed within it's time wait period. func CheckExecution($CurrentSection) _FileWriteLog($g_logFile,"Checking for recent execution of " & $CurrentSection) For $k = 0 To 23 For $n = 0 To 59 For $i = 1 To 6 Step 1 $file = $g_ExecuteArray[$k][$n][$i] If $file = $CurrentSection Then return 50 EndIf Next Next Next return 0 EndFunc ; This function clears the execution time array from "current time - time wait value" to at least 2 hours before then. func ClearExecution($CurrentSection) CalcExecutionTime($CurrentSection) $KillWait = IniRead($g_iniFile,$CurrentSection,"KillWait","2") $n = $g_WaitTime[1] $b = $g_WaitTime[1] - $KillWait $g = $g_WaitTime[2] ;This first if handles the case where we need to clear the beginning and then the end of the array. If $b < 0 Then For $k = $n To 0 Step -1 For $j = $g-1 To 0 Step -1 For $i = 1 To 6 Step 1 If $g_ExecuteArray[$k][$j][$i] = $CurrentSection Then $g_ExecuteArray[$k][$j][$i] = "" if $CurrentSection <> "" Then For $w = 0 To UBound($g_pid)-1 $Match = StringInStr($g_pid[$w],$CurrentSection) If $Match <> 0 Then $ParseMe = StringSplit($g_pid[$w],",") if ProcessExists($ParseMe[2]) Then _FileWriteLog($g_logFile,"Process ID " & $ParseMe[2] & " for " & $CurrentSection & " is being shutdown.") ProcessClose($ParseMe[2]) EndIf $g_pid[$w] = "" EndIf Next EndIf EndIf Next Next $g = 60 Next For $k = 23 To 23+$b Step -1 $g = 59 For $j = $g To 0 Step -1 For $i = 1 To 6 Step 1 If $g_ExecuteArray[$k][$j][$i] = $CurrentSection Then $g_ExecuteArray[$k][$j][$i] = "" if $CurrentSection <> "" Then For $w = 0 To UBound($g_pid)-1 $Match = StringInStr($g_pid[$w],$CurrentSection) If $Match <> 0 Then $ParseMe = StringSplit($g_pid[$w],",") if ProcessExists($ParseMe[2]) Then _FileWriteLog($g_logFile,"Process ID " & $ParseMe[2] & " for " & $CurrentSection & " is being shutdown.") ProcessClose($ParseMe[2]) EndIf $g_pid[$w] = "" EndIf Next EndIf EndIf Next Next Next Else For $k = $n To $b Step -1 For $j = $g-1 To 0 Step -1 For $i = 1 To 6 Step 1 If $g_ExecuteArray[$k][$j][$i] = $CurrentSection Then $g_ExecuteArray[$k][$j][$i] = "" if $CurrentSection <> "" Then For $w = 0 To UBound($g_pid)-1 $Match = StringInStr($g_pid[$w],$CurrentSection) If $Match <> 0 Then $ParseMe = StringSplit($g_pid[$w],",") if ProcessExists($ParseMe[2]) Then _FileWriteLog($g_logFile,"Process ID " & $ParseMe[2] & " for " & $CurrentSection & " is being shutdown.") ProcessClose($ParseMe[2]) EndIf $g_pid[$w] = "" EndIf Next EndIf EndIf Next Next $g = 60 Next EndIf EndFunc Func Preempt($CurrentSection) $CheckFor = IniRead($g_iniFile,$CurrentSection,"Preempt","") if $CheckFor <> "" Then For $j = 0 To UBound($g_pid)-1 $Match = StringInStr($g_pid[$j],$CheckFor) If $Match <> 0 Then $ParseMe = StringSplit($g_pid[$j],",") if ProcessExists($ParseMe[2]) Then _FileWriteLog($g_logFile,"Process " & $ParseMe[2] & " for " & $CheckFor & " exists and preempts this launch of " & $CurrentSection & ".") Return 5 Else Return 0 EndIf EndIf Next EndIf EndFunc Func BuildNumSuffixWait($BuildFinish) $checkForFinish = FileExists ($BuildFinish) $tick = 0 While ($checkForFinish == 0) if $tick = 15 Then _FileWriteLog($g_logFile,"Timed out looking for: " & $BuildFinish) return 18 EndIf sleep (60000); Sleep 1 Minute $checkForFinish = FileExists ($BuildFinish) $tick = $tick +1 WEnd _FileWriteLog($g_logFile,"Discovered: " & $BuildFinish) return 0 EndFunc Func ExecuteScript ($flag,$Build,$g_iniFile,$CurrentSection,$PassDir);$flag set 0 will prompt before execution, else, it'll not prompt. $k = 1 dim $answer ;This code is to check for Process ID's associated with the product being executed and close them. For $j = 0 To UBound($g_pid)-1 If StringInStr($g_pid[$j],$CurrentSection) <> 0 Then $ParseMe = StringSplit($g_pid[$j],",") if ProcessExists($ParseMe[2]) Then _FileWriteLog($g_logFile,"Process ID " & $ParseMe[2] & " for " & $CurrentSection & " is being shutdown.") ProcessClose($ParseMe[2]) EndIf EndIf Next ; This loop is to add the product name to the execution time array in the first available slot for that minute in time. For $w =1 To 6 $b = @HOUR $q = @MIN if $g_ExecuteArray[$b][$q][$w] = "" Then $g_ExecuteArray[$b][$q][$w] = $CurrentSection ExitLoop EndIf Next $NumToEx = IniRead($g_iniFile,$CurrentSection,"NumToEx","1") $ExeWait = IniRead($g_iniFile,$CurrentSection,"RunWait","0") if $flag = 0 Then $answer = MsgBox(4, "Listener - " & $CurrentSection, "Start execution for " & $CurrentSection & " build " & $Build & "? Will default to ""Yes"" after 20 seconds.", 20) EndIf If $answer = 7 Then _FileWriteLog($g_logFile, "Not starting " & $CurrentSection & " since end user clicked no. Continuing to listen") Else For $k = 1 To $NumToEx $exeCom = "Execute" & $k $Execute = IniRead($g_iniFile,$CurrentSection,$exeCom,"") _FileWriteLog($g_logFile, "Executing: " & $Execute) if $ExeWait = 0 Then $pid = Run($Execute) ElseIf $ExeWait = 1 Then $pid = RunWait($Execute) EndIf $ProdPid = $CurrentSection & "," & $pid _ArrayAdd($g_pid,$ProdPid) _FileWriteLog($g_logFile, "Process ID(PID) returned: " & $pid );if PID = 0, then there was an error running. Next EndIf EndFunc func LocateBuildNumber($BuildDir,$StripPrefix) ;This function searches for the latest build, including alpha builds. Prereq is the build directory must start as a number. dim $search = FileFindFirstFile($BuildDir & "\*") if $search = -1 then MsgBox(0, "Error", "No build folders found.") Return 0 endif ; find the most recent build SetError(0) dim $file = FileFindNextFile($search) dim $number = 0 dim $build dim $buildNum _FileWriteLog($g_logFile,StringReplace($file,$StripPrefix,"") & " -- " & $StripPrefix) while @error <> 1 if ($file <> ".") and ($file <> "..") then _FileWriteLog($g_logFile,StringReplace($file,$StripPrefix,"") & " -- " & $StripPrefix) if (Number(StringReplace($file,$StripPrefix,"")) > $number) then $number = Number(StringReplace($file,$StripPrefix,"")) $build = $number endif endif $file = FileFindNextFile($search) wend FileClose($search) if ($build = "") then Return 0 endif Return $build EndFunc Func MountBuild($NetworkShare, $UserName, $NetworkPassword);This ensures permissions to network shares. If Not($UserName = "") Then RunWait(@ComSpec & " /c net use " & $NetworkShare & " /u:" & $UserName & " """ & $NetworkPassword & """ /persistent:no", _ "", @SW_HIDE) ;I'm including a set of quotes arround the password in case special characters are included. EndIf endfunc func getIniFile();Defaults to listener.ini if one isn't specified. dim $ini if ($CmdLine[0] = 0) then $ini = @ScriptDir & "\listener.ini" Else $ini = $CmdLine[1] EndIf if not FileExists($ini) Then _FileWriteLog($g_logFile, "Ini file could not be found: " & $ini) MsgBox(48, "Listener", "Ini file could not be found: " & $ini) exit 5 EndIf _FileWriteLog($g_logFile, "Ini file: " & $ini) return $ini EndFunc main() Link to comment Share on other sites More sharing options...
ElfCabbage Posted March 19, 2014 Author Share Posted March 19, 2014 Forgot to put the ini file info in: [Products] 1=Sample 2=Example [Timeout] wait=300000 [sample] BuildFinish=<any file that will appear once a build has finished publishing> BuildDir = <root directory down to where build directories vary> BuildSuffix = <text that might come after build number in directory name> BuildPrefix = <text that might come before build number in directory name> PassDir = 1 NumToEx = 2 Execute1=<path to file to execute if finish file is found> Execute2 =<path to file to execute if finish file is found> ExecuteWait = 30 KillWait = 10 [Example] NetworkShare=<network path to build directory> UserName=<credentials for permission to build directory> NetworkPassword=<credentials for permission to build directory> BuildDir = <root directory down to where build directories vary> BuildSuffix = NumToEx = 1 Execute1=<path to file to execute if finish file is found> ExecuteWait = 45 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now