Sign in to follow this  
Followers 0
juk

Exiting multiple scripts with one hotkey

11 posts in this topic

I have a script that uses RunWait -command to run other autoit-scripts. In the main script I have a HotKeySet("{ESC}","Terminate") that asks for confirmation and then exits the script. Now that exits only the main script and the one it started could be left running. How can I exit all running autoit-scripts with that one hotkey?

; Teh Main Script
HotKeySet("{ESC}","Terminate")

...some code here...

RunWait('"C:\Program Files\AutoIt3\AutoIt3.exe" <subsrcipt>')

..more code here...

Func Terminate()
  If MsgBox(4,"Terminate?","Really terminate script execution?") == 6 Then
    Exit
  EndIf
EndFunc

-juk

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Might try something like:

This will work with run not runwait, for runwait might try something like pskill from sysinternals.

HotKeySet("{ESC}","Terminate")
Dim $PID[1]
$PID[0] = 0

...some code here...

$PID[0] = $PID[0] + 1
ReDim $PID[$PID[0] + 1]
$PID[$PID[0]] = Run('"C:\Program Files\AutoIt3\AutoIt3.exe" <subsrcipt>')

..more code here...

Func Terminate()
  If MsgBox(4,"Terminate?","Really terminate script execution?") == 6 Then
     For $x = 1 To $PID[0]
        if ProcessExists($PID[$x]) then
           ProcessClose($PID[$x])
        endif
     Next
    Exit
  EndIf
EndFunc

Another option might be

While ProcessExists("AutoIt3.exe")

ProcessClose("AutoIt3.exe")

Sleep ( 1000 )

Wend

Edited by gafrost

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites

This will work with run not runwait, for runwait might try something like pskill from sysinternals.

<{POST_SNAPBACK}>

And that would require the use of DllCall? The problem is that the subscripts need to be run back to back so that the previous is completed before the next one starts. Is there a way of knowing what's the processID of the current script (the main script) so that I could kill the other AutoIt3.exe -processes before I exit the main script?

-juk

Share this post


Link to post
Share on other sites

I'd prefer to get this working without any external software.

How about putting everything in a subscript.au3 in a function declaration and then calling the function instead of running the file in the main script? Subscript files would have to be included in the main script, naturally. Sounds like a valid idea, I'll try it.

-juk

Share this post


Link to post
Share on other sites

I have a script that uses RunWait -command to run other autoit-scripts. In the main script I have a HotKeySet("{ESC}","Terminate") that asks for confirmation and then exits the script. Now that exits only the main script and the one it started could be left running. How can I exit all running autoit-scripts with that one hotkey?

Create a seperate script and put this in it.

$list = ProcessList("autoit3.exe")
for $i = 1 to $list[0][0]  
  ProcessClose($list[$i][1])
next

Processlist will return all pids of all scripts. The last called script (this one) will be listed last in the array. It will therefore close all scripts and then exit. I use this but don't have it set as a hotkey. This only works if the above code is in a seperate script that you call. If you put it in your main script it may not list itself last in the array and may not therefor close all scripts.

If you just want to run a second script and be able to close it from the fist one without closing all your stuff just start the script with something similar to this line.

$start2pid = Run(@AutoItExe & ' "' & @ScriptDir & '/start2.au3')

Then use

ProcessClose($start2pid)

when you want to kill it.

Hmm... Why did I do that different in this script at work then what I did at home. I'll have to look at that.

If you want to spawn other scripts that can then close the first script depending on certain conditions. Well that stuff is at home so I'll post that later tonight if you want it.

Share this post


Link to post
Share on other sites

Here is a way to close a parent script from the child script because I did not see a way to find the pid of the parent script. The parent script opens nero and calls the child. It then waits for a successfull burning and plays a song becasue I'm most likely within earshot of the computer but not looking at it.

The child closes the parent if I close nero without burning anything so that nothing is running after exiting nero.

Parent

Opt("MouseCoordMode", 0)       ;1=absolute, 0=relative

; ensure this copy is the running one.
$g_szVersion = "Nero Script"
If WinExists($g_szVersion) Then WinClose($g_szVersion)
AutoItWinSetTitle($g_szVersion)

run("C:\Program Files\nero\Nero StartSmart\NeroStartSmart.exe","")

; start nero2.au3 to monitor and close this script if needed.
$pidnero2 = run("c:\program files\autoit3\autoit3.exe D:\tools\scripts\nero2.au3")

WinWaitActive("Nero Burning ROM", "Burn process completed successfully")
RunWait(@ComSpec & " /c " & 'D:\tools\dvd.autoit\done.mp3', "", @SW_HIDE)

Child

; purpose.  To stop "Nero Script" if Nero gets closed.

Opt("MouseCoordMode", 0)       ;1=absolute, 0=relative

; ensure this copy is the running one.
$g_szVersion = "Nero2 Script"
If WinExists($g_szVersion) Then WinClose($g_szVersion)
AutoItWinSetTitle($g_szVersion)


$pidnero = ProcessExists('NeroStartSmart.exe')
if $pidnero <> 0 then ProcessWaitClose($pidnero)
WinClose("Nero Script")

Of course now that I've given every script a name of the form "xxxx Script" I now realize that I can do a windows search for "Script" and create an array with all the running pids and the scripts that called them without having to compile them as exes and build the array from the processlist command. Thats what I was trying to figure out before I did it this way.

Now why did I start writing this....

Your original question... yes, to find the pid number of the current running script so you can close the others before closeing the current one. If your script is given a name you can use the WinGetProcess command to get the pid of the current script.

For example in my child script I could have added

$pid = WinGetProcess("Nero2 Script")
MsgBox(0, "PID is", $pid)

To get the pid of the current script. Then use ProcessList to get a list of the other pids. Then close them all skipping what I know to be my own.

No external programs needed. No beta needed.

I know I rambled on a bit but I hope that helps.

Share this post


Link to post
Share on other sites

If you just want to run a second script and be able to close it from the fist one without closing all your stuff just start the script with something similar to  this line.

$start2pid = Run(@AutoItExe & ' "' & @ScriptDir & '/start2.au3')

Then use

ProcessClose($start2pid)

<{POST_SNAPBACK}>

That's the thing. See, I wasn't using Run, but RunWait which doesn't return the pid. :) But then I thought of going around the problem by making functions of all the child scripts, cause Call works similar to RunWait by pausing until the function/child script has run. I'm not yet sure if that is the best solution concidering the whole scheme I'm working on tho, so it's good to know if there's a solution to the actual problem aswell!

-juk

Share this post


Link to post
Share on other sites

If your script is given a name you can use the WinGetProcess command to get the pid of the current script.

For example in my child script I could have added

$pid = WinGetProcess("Nero2 Script")
MsgBox(0, "PID is", $pid)

<{POST_SNAPBACK}>

How can a name my script? My scripts don't create any windows, if that's what you're after with WinGetProcess. Mine just operate other ones, so I can't tell from the process list what processes relate to what scripts. All there are is AutoIt3.exes. But if I did compile the script, it would work that way and show it in the process list as MyScript.exe? Or would it? Haven't tried it yet.

-juk

Share this post


Link to post
Share on other sites

How can a name my script? My scripts don't create any windows, if that's what you're after with WinGetProcess. Mine just operate other ones, so I can't tell from the process list what processes relate to what scripts. All there are is AutoIt3.exes. But if I did compile the script, it would work that way and show it in the process list as MyScript.exe? Or would it? Haven't tried it yet.

-juk

<{POST_SNAPBACK}>

Ya thats whats I thought too a couple weeks ago when I was playing around with this stuff. All scripts create windows. But they are hidden ones. If you don't name them within the script the default name is "AutoIt 3".

The lines that name them.

$g_szVersion = "Juks Script"
AutoItWinSetTitle($g_szVersion)

That will name the script its called from "Juks Script". Now you can access it like any other window. Before the AutoItWinSetTitle command the name of the hidden script window will be the default "AutoIt 3"

If you want the pid then use the the following line after you have named the script.

$pid = WinGetProcess("Juks Script")

All my scripts are now named of the format "xxxxx Script" so that I can search for "Script" and get a list of all running scripts. If you do this, don't forget to add the line

Opt("WinTitleMatchMode", 2) ;1=start, 2=subStr, 3=exact, 4=advanced

so that your searching the windows properly. Its a 1 by default if you dont include that line.

Yes, you can compile them and then the name will show in the processlist but I wanted to avoid that as I modify them often and did not want to have to recompile them every time I changed something when testing. So I came up with this method instead. There may very well be a better way of doing this, I only came up with this last week. I was unaware of the AutoItWinSetTitle command before that.

Funny thing is that this command is in the FAQ in the Help file but I had never realized what it did.

Share this post


Link to post
Share on other sites

Oooh! Good to know!

I never get around to reading the FAQ again after I start really using something, like AutoIt. And in the function reference there is a remark about it, but how could you think to look there if you didn't think there was such an option. :)

Thanks a lot!

-juk

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0