portablecio Posted October 2, 2009 Share Posted October 2, 2009 Hello everyone, I work for a small desktop support company. We do a lot of new system configuration, and the majority of the tasks are the same for every system. I'm trying to develop a script that will automatically configure a Windows XP workstation and install a selection of software. The script needs to be fault tolerant (i.e. If one part of the process hangs, the script can continue). I'd also like it to notify the user as to which parts of the process weren't completed. Here's how I decided to do it. I created a master script whose purpose is to run subscripts (modules also written in autoit). I've timed each task, and the master script will pause for a predetermined length of time while each module runs. If a module exceeds the expected time limit, the master script should end any active autoit scripts excepting itself. I wrote a function which is designed to first identify the master script's process ID (PID), and then end all other active instances of autoit3.exe ;finds master script pid and assigns it to variable $m. This should be the first thing the script does so there's only one process running. $m = ProcessExists("autoit3.exe") ;defines kill function which preserves the master script and kills all other autoit3.exe processes func kill($i) $array = processlist("autoit3.exe") While $i <= ($array[0][0]) if $m = ($array[$i][1]) then $i=$i+1 Else processclose($array[$i][1]) $i=$i+1 endif WEnd EndFunc When I tested this function initially, it seemed to work like a charm. However, when I intergrated it into my master script it doesn't kill processes that have timed out. To go you an idea of how it all works, here's the first part of the master script: ;look and feel run("1 look and feel.exe") sleep(12000) fileopen("checklist.txt", 0) if FileReadLine("checklist.txt", 1) <> "Success - Look and Feel" then fileclose("checklist.txt") fileopen("checklist.txt", 1) FileWriteline("checklist.txt", "Failure - Look and Feel") fileclose("checklist.txt") kill(1) Else fileclose("checklist.txt") EndIf "1 look and feel.exe" is a module that does basic look and feel modifications to the Windows XP GUI. "Checklist.txt" starts as a blank document, and it serves as a record of which modules completed successfully and which modules timed-out. It's also a way for the master script and modules to communicate with each-other. I've included this section of code at the end of each module: ;write success to checklist fileopen("checklist.txt", 1) FileWriteline("checklist.txt", "Success - Look and Feel") fileclose("checklist.txt") Here's how it all works: The master script runs the module ("look and feel" in the example). It waits for a pre-defined amount of time. During that time, the module either runs to completion, at which point it writes a line to the checklist document saying that it succeeded, or it hangs. After the master script finishes waiting, it looks at the checklist. If it sees that the last line of text is NOT a success message, it writes that the module failed and then kills all instances of autoit3.exe other than itself. If it sees that the last line of text IS a success message, it moves to the next module. So, my question is this: Why doesn't the master script kill processes that have hung? Additionally, the checklist usually ends up with "success" and "failure" entries for each and every module (which is worse than useless for the technician running the script)! Is there something wrong with the kill function? Also, is there a better, more stable way to do what I'm trying to do? As you can probably tell from my code, I'm new to scripting and have very little programming experience. Hopefully your experienced eyes will catch the obvious flaw in my logic. Thanks for any help you can provide! Link to comment Share on other sites More sharing options...
PsaltyDS Posted October 5, 2009 Share Posted October 5, 2009 (edited) So, my question is this: Why doesn't the master script kill processes that have hung?Where did you get this kill() function, and why isn't it included here? Psychic debugging is hard to come by. Gotta learn to read more carefully... Edited October 5, 2009 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
Seagul Posted October 5, 2009 Share Posted October 5, 2009 just give me your job and ill do it~~!! or can you just use http://www.nliteos.com/ and make a slipstreamed cd with all the proper software? then deploy it that way? Link to comment Share on other sites More sharing options...
herewasplato Posted October 5, 2009 Share Posted October 5, 2009 Hello everyone, I work for a small desktop support company. We do a lot of new system configuration, and the majority of the tasks are the same for every system. I'm trying to develop a script that will automatically configure a Windows XP workstation and install a selection of software. The script needs to be fault tolerant (i.e. If one part of the process hangs, the script can continue). I'd also like it to notify the user as to which parts of the process weren't completed. Here's how I decided to do it. I created a master script whose purpose is to run subscripts (modules also written in autoit). I've timed each task, and the master script will pause for a predetermined length of time while each module runs. If a module exceeds the expected time limit, the master script should end any active autoit scripts excepting itself. I wrote a function which is designed to first identify the master script's process ID (PID), and then end all other active instances of autoit3.exe ;finds master script pid and assigns it to variable $m. This should be the first thing the script does so there's only one process running. $m = ProcessExists("autoit3.exe") ;defines kill function which preserves the master script and kills all other autoit3.exe processes func kill($i) $array = processlist("autoit3.exe") While $i <= ($array[0][0]) if $m = ($array[$i][1]) then $i=$i+1 Else processclose($array[$i][1]) $i=$i+1 endif WEnd EndFunc When I tested this function initially, it seemed to work like a charm. However, when I intergrated it into my master script it doesn't kill processes that have timed out. To go you an idea of how it all works, here's the first part of the master script: ;look and feel run("1 look and feel.exe") sleep(12000) fileopen("checklist.txt", 0) if FileReadLine("checklist.txt", 1) <> "Success - Look and Feel" then fileclose("checklist.txt") fileopen("checklist.txt", 1) FileWriteline("checklist.txt", "Failure - Look and Feel") fileclose("checklist.txt") kill(1) Else fileclose("checklist.txt") EndIf "1 look and feel.exe" is a module that does basic look and feel modifications to the Windows XP GUI. "Checklist.txt" starts as a blank document, and it serves as a record of which modules completed successfully and which modules timed-out. It's also a way for the master script and modules to communicate with each-other. I've included this section of code at the end of each module: ;write success to checklist fileopen("checklist.txt", 1) FileWriteline("checklist.txt", "Success - Look and Feel") fileclose("checklist.txt") Here's how it all works: The master script runs the module ("look and feel" in the example). It waits for a pre-defined amount of time. During that time, the module either runs to completion, at which point it writes a line to the checklist document saying that it succeeded, or it hangs. After the master script finishes waiting, it looks at the checklist. If it sees that the last line of text is NOT a success message, it writes that the module failed and then kills all instances of autoit3.exe other than itself. If it sees that the last line of text IS a success message, it moves to the next module. So, my question is this: Why doesn't the master script kill processes that have hung? Additionally, the checklist usually ends up with "success" and "failure" entries for each and every module (which is worse than useless for the technician running the script)! Is there something wrong with the kill function? Also, is there a better, more stable way to do what I'm trying to do? As you can probably tell from my code, I'm new to scripting and have very little programming experience. Hopefully your experienced eyes will catch the obvious flaw in my logic. Thanks for any help you can provide!Welcome to the forums. You call your kill function with this line: kill(1) That would send the string 1 to the kill function So this line func kill($i) becomes this line func kill(1) This line $array = processlist("autoit3.exe") builds a list of the process IDs for programs that are named "autoit3.exe". This line While $i <= ($array[0][0]) becomes this line While 1 <= ??? where ??? equals the number of processes that are named "autoit3.exe". So you are never going kill a process named "1 look and feel.exe" if all you have to work with is an array listing the PIDs of the processes named "autoit3.exe". Just for your info, you could remove the kill func and replace this line: run("1 look and feel.exe") with this line $PID = run("1 look and feel.exe") And replace this line: kill(1) with this line ProcessClose($PID) But the overall method may be too flawed to be worth saving. Additionally, the checklist usually ends up with "success" and "failure" entries for each and every module... I would have to see more of your code to be find that cause. It would be best if those that deploy software for a living address the "how to do this better" question. [size="1"][font="Arial"].[u].[/u][/font][/size] Link to comment Share on other sites More sharing options...
portablecio Posted October 5, 2009 Author Share Posted October 5, 2009 Plato, Thanks for the tip on using "run" to capture a module's PID, that's much cleaner than using the kill function, especially since I'll only need to end one module at a time (the counter part of the Kill function was included to deal with a situation where more than two instances of Autoit3.exe exist). I'll try that out and see if it improves overall functionality (although theoretically it should achieve the same result) and let you all know how it turns out. Seagul, We thought about using Nlite to do deployments, but our shop usually gets systems which have just shipped from Dell or another OEM. Since we don't have the option to do a fresh install on these systems, we need a tool that will configure a generic XP installation; hence this scripting project which is slowly driving me insane. Good thought though. Thanks everyone, keep those ideas coming! Link to comment Share on other sites More sharing options...
herewasplato Posted October 5, 2009 Share Posted October 5, 2009 ... (the counter part of the Kill function was included to deal with a situation where more than two instances of Autoit3.exe exist). ... There should be two instances of Autoit3.exe when you run a script from within SciTE. If you are running/debugging a script as a text file (no from within SciTE) then you should only have one instances of Autoit3.exe per script. If one AU3 file (text file) has hung and you start another one - you should have code in the script that looks for and warns about the other copy running. $S_running = "???????" ;name the script If WinExists($S_running) Then MsgBox(0, "AutoIt", "This script is already running.") Exit EndIf AutoItWinSetTitle($S_running) _Singleton is another way to prevent multiple copies of the same script from running. [size="1"][font="Arial"].[u].[/u][/font][/size] Link to comment Share on other sites More sharing options...
Megadime Posted October 6, 2009 Share Posted October 6, 2009 Thanks a lot for your contributions. That last one seems to be a good way to get this thing to work. Thanks again. Link to comment Share on other sites More sharing options...
portablecio Posted October 6, 2009 Author Share Posted October 6, 2009 Great Success! I replaced the kill function with the code that Plato suggested and viola!, everything works. I still don't understand why the kill function didn't do what I wanted it to, but that's ok because the project is back on track. Thanks Plato! 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