Sign in to follow this  
Followers 0
neogia

How to pause a script externally?

16 posts in this topic

Ok, so you know how you right click on an AutoIt script's tray icon and it pauses? Well, I'm trying to create a server script that can do the same thing with many child scripts. I know you can use HotKeySet(), but is there any other way to simulate what happens when you right click the icon? Any help is appreciated.


[u]My UDFs[/u]Coroutine Multithreading UDF LibraryStringRegExp GuideRandom EncryptorArrayToDisplayString"The Brain, expecting disaster, fails to find the obvious solution." -- neogia

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Ok, so you know how you right click on an AutoIt script's tray icon and it pauses? Well, I'm trying to create a server script that can do the same thing with many child scripts. I know you can use HotKeySet(), but is there any other way to simulate what happens when you right click the icon? Any help is appreciated.

Is this an autoit script your talking about? If so, I think Cameronsdad made something in scripts and scrapts to do this.

Edit:

Is this what your talking about?: http://www.autoitscript.com/forum/index.ph...topic=20379&hl=

Edited by SmOke_N

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

If the master script starts all the child scripts, you could use StdInWrite and StdOutRead to communicate between scripts. When you run the child, just set the standard_i/o_flag to 3 or 7.

Run ( "filename" [, "workingdir" [, flag[, standard_i/o_flag]]] )

standard_i/o_flag - [optional] Provide a meaningful handle to one or more STD I/O streams of the child process.

1 ($STDIN_CHILD) = Provide a handle to the child's STDIN stream

2 ($STDOUT_CHILD) = Provide a handle to the child's STDOUT stream

4 ($STDERR_CHILD) = Provide a handle to the child's STDERR stream

From there, I would suggest having an adlib function in the child scripts to check for written data every 500 to 1000 ms.

This is (obviously) not the best method, as it isn't instant, takes communication between scripts in order for something to work, and isn't direct. However, if done correctly it would work.

Share this post


Link to post
Share on other sites

That is mostly about TCP communication though.. and he double-posted that topic, so there are different responses in the other one (including mine about STD in and out). I have to go find the other one to see if a better stdin and stdout script was written....

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

That is mostly about TCP communication though...

I was not talking about the thread, just the one post from Chris.

I ran that code - it is a good example - here is part of the code:

; AutoIt Version: 3.1.103 beta

; Author: Chris Lambert

Func Adlib ()
    For $i = 1 to Ubound ($Foo) - 1 
        If @error then exitloop
    $line = StdoutRead($foo[$i],"",true)
    If $Line <> 0 then 
        $line = StdoutRead($foo[$i])
    MsgBox(0, "STDOUT read:", $line)
EndIf
Next
EndFunc
there is no TCP in that script - that was the point of Chris's post to that thread :-) Edited by herewasplato

[size="1"][font="Arial"].[u].[/u][/font][/size]

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Whoa.. that one is actually different than the one he posted in the other thread. The other one had TCP in it, and they looked so similar.. I guess I assumed they were the same.

My bad. Time to go try that script and watch it work.

Edit - Wow too bad I missed that a while ago. That was fun.

Edited by greenmachine

Share this post


Link to post
Share on other sites

My bad.

Not really - I knew that I should have taken the time to point out that post code's vs. the thread's topic. I read that other thread too - easy to get lost in all of the code.

What struck me about that TCP thread was the AutoIt community at work:

Valik states, "You don't need to use TCP connections, you can use the STD handles to communicate...."

SmOke_N states, "Any chance of getting a working example script..."

and ChrisL responds with that sample within hours.

Thanks for all of your help in the forums.


[size="1"][font="Arial"].[u].[/u][/font][/size]

Share this post


Link to post
Share on other sites

Not really - I knew that I should have taken the time to point out that post code's vs. the thread's topic. I read that other thread too - easy to get lost in all of the code.

What struck me about that TCP thread was the AutoIt community at work:

Valik states, "You don't need to use TCP connections, you can use the STD handles to communicate...."

SmOke_N states, "Any chance of getting a working example script..."

and ChrisL responds with that sample within hours.

Thanks for all of your help in the forums.

I agree, these forums are amazing. We've got a large number of dedicated scripters at work here, and they can really get a job done.

Share this post


Link to post
Share on other sites

Wow, I go to a concert for a few hours and I miss all the awesome responses..

@SmOke_N: Yes, it is an AutoIt script, and thanks for posting the link to cameronsdad's script, but I don't want to edit the context menu, I just want to be able to simulate what right-clicking on a script's tray icon does. You know, when it starts blinking the red "X" icon?

@greenmachine, herewasplato: Yeah, I looked into Std***() functions, but didn't like the delay that would be required by AdLib().

So what I'm working on is an extension of ChrisL's idea for simulated multithreading. Pausing isn't absolutely necessary, but sometimes useful in running coroutines. I'm shooting for a lua-like interface to this, but if I do end up implementing it to a UDF, I wouldn't want Hotkeys being set and called in the background, cause that could cause major headaches for the unaware. However, that seems to be the only way to call an instantaneous pause.

I guess my real question is this: When you right click on a script's tray icon, does something internal to AutoIt happen to pause the script, or is it a function that's exposed through AutoIt's interface that can be "activated" in some other manner than right-clicking on the systray icon? Wordy question, I know, but I like to be thorough. Thanks again, for the great responses. I love these forums.


[u]My UDFs[/u]Coroutine Multithreading UDF LibraryStringRegExp GuideRandom EncryptorArrayToDisplayString"The Brain, expecting disaster, fails to find the obvious solution." -- neogia

Share this post


Link to post
Share on other sites

I've been looking through the AutoIt source code (version 3.1.0, but it's still good), and it's fascinating. I'm going to assume that since the source is openly available to download that it's ok to post here, and so I'm going to show some pieces that have to do with the tray icon and pausing.

Check out a piece of this function (hidden to us as far as I can tell):

int AutoIt_Script::ProcessMessages()
{
[...]
if (m_nCurrentOperation == AUT_QUIT)
        return AUT_QUIT;
    else if (g_bScriptPaused)
        return AUT_PAUSED;
    else
        return AUT_RUN;
}

The var g_bScriptPaused is false be default (because the script needs to run). As for the AUT_xxx vars, look at this:

// Possible states of the script
enum
{
    AUT_RUN, AUT_QUIT,
    AUT_SLEEP,
    AUT_WINWAIT, AUT_WINWAITCLOSE,
    AUT_WINWAITACTIVE, AUT_WINWAITNOTACTIVE,
    AUT_RUNWAIT,
    AUT_PROCESSWAIT, AUT_PROCESSWAITCLOSE,
    AUT_INETGET,
    AUT_PAUSED                                  // Not actually used except for a ProcessMessages() return value
};

So basically, the g_bScriptPaused is an important boolean var, and AUT_PAUSED isn't (and I thought it would be...).

AUT_RESULT AutoIt_Script::Execute(int nScriptLine)
{
[...]
// Run our Execute() loop
    while(m_bWinQuitProcessed == false && m_bUserFuncReturned == false)
    {
        // Run the windows message loop and handle quit conditions
        ProcessMessages();

        // If script is in a quit state then don't execute any more code
        if (m_nCurrentOperation == AUT_QUIT)
            break;                              // Exit while loop

        // If we are waiting for something (winwait, sleep, paused, etc) then loop again
        if (HandleDelayedFunctions() == true)
            continue;
[...]
}

Execute is really handy!

bool AutoIt_Script::HandleDelayedFunctions(void)
{
    // Handle hotkeys first (even if paused - eventually we will and an unpause function to make this useful)
    if (HandleHotKey() == true)
        return true;

    // If the script is paused, sleep then loop again
    if (g_bScriptPaused == true)
    {
        Sleep(AUT_IDLE);                    // Quick sleep to reduce CPU load
        return true;
    }
[...]
}

That'll do for now. I guess the whole point of this post was that yes, it's an internal msg being sent, and I've found which one. The next task would be to figure out how to send that msg to other scripts (likely to be a tough task for me)...

Interesting find: the order of execution goes hotkey, sleep, adlib, guievent, .... That's why you can press a hotkey and it will interrupt a sleep. NICE.

P.S. - Mods: if for any reason I shouldn't have posted all this code out in the open, and you need to remove it, feel free, but please PM me to let me know.

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

@neogia: My solution:

If the "server" script started the other scripts, it can close the other scripts ;like this:

$pid = Run(whatever)

;;;;;;when finish,
ProcessClose($pid)

@greenmachine: People can find out by themselves anyway, if you can, others can.

#)

Edited by nfwu

Share this post


Link to post
Share on other sites

Wow, what a wealth of information, thank you so much, greenmachine! So that settles it, it's an internal variable which determines if it is asleep or not. So this gives me an idea. I don't know much about memory writing, but I do know there's some others who excel in editing memory values! *wink wink*, and if "g_bScriptPaused" is allocated for every script which I assume it is, then it should be at the same memory offset right? And therefore, can be changed, given the process, or even the PID, which is returned from Run(). Anyone that knows their way around this department, am I on the right track? Is this possible?

Thanks again, greenmachine.


[u]My UDFs[/u]Coroutine Multithreading UDF LibraryStringRegExp GuideRandom EncryptorArrayToDisplayString"The Brain, expecting disaster, fails to find the obvious solution." -- neogia

Share this post


Link to post
Share on other sites

@neogia: My solution:

If the "server" script started the other scripts, it can close the other scripts ;like this:

$pid = Run(whatever)

;;;;;;when finish,
ProcessClose($pid)

@greenmachine: People can find out by themselves anyway, if you can, others can.

#)

About your solution - neogia wanted to know if you could pause a script externally, not just open and close them.

About the code - I'm not exactly sure where you comment comes into play... I posted the code because I've found it (and I enjoyed reading the code to see how it works), and I added the PS because I noticed something about redistributing the code and I wasn't sure if this would qualify under that restriction or not.

Share this post


Link to post
Share on other sites

That is mostly about TCP communication though.. and he double-posted that topic, so there are different responses in the other one (including mine about STD in and out). I have to go find the other one to see if a better stdin and stdout script was written....

On my faking multithreading, I should have put it in scripts and scraps but stupidly put it in Support which it wasn't, I put it later into scripts and scraps incase anyone was looking for an idea. My first post should have been moved really to avoid confusion. Sorry

Share this post


Link to post
Share on other sites

Hey don't worry about it Chris. I figured it out in the end. Oh, and nice script too.

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