Jump to content

On consolidating scripts


qwert
 Share

Recommended Posts

Although I've only been using AutoIt for a few weeks, I've built a library of a dozen utilities that perform useful functions, most called from a database application. Compiled and compressed, the scripts now exceed 3 megabytes on my base directory -- plus, there's the overhead of uncompressing when one of them is called. So I was thinking ...

Is it possible to combine such scripts into what would amount to a single companion task that would be initialized once -- as the database application starts -- and then remain running to service individual requests? Script calls would then be of the form:

CompositeScript <functionID> <parameters>

The advantages would seem to be:

> a 90% reduction in the net size of the compiled set of utilities

> near-instant response to script calls (the equivalent of TSR programs)

> a reduction in the "perceived complexity" of the runtime result

Conceptually, this approach sounds good, but I'm very uncertain on how to proceed -- or if it's even practical. If it is, I'd sure like to know of an example that I can learn from -- or maybe get a suggestion of a couple of functions to begin working with. My searches haven't turn up anything of use -- but I can't say I know what terms to search for. This is an entirely new area for me.

Any advice will be greatly appreciated. Thanks in advance.

Link to comment
Share on other sites

Let me see if I understand. Something like this?:

While 1   
    Select  
       Case CmdLine[1] = "Function A"
         :
       Case CmdLine[1] = "Function B"
         :
       Case CmdLine[1] = "Function C"
        :
       Case CmdLine[1] = "Close"
       Exit
    EndSelect
Sleep(100)
Wend

If so, then I have these questions:

Will the script then be "re-enterable" such that if a previous request is still in progress (like moving 500 files) and a new request is received (like displaying a popup with current date/time) that the second request will be serviced immediately -- or will it be delayed? And does this mean there will be only one copy of the script in PC memory -- or one for each active call?

Is there any problem with receiving requests from different calling applications? I guess what I'm asking is does the OS maintain a "stack" for calling parameters so that parameters from one call can't get jumbled with parameters from another.

And, finally, your comment "you need to be diligent on your design ..." suggests there may be pitfalls. At this point, all of my scripts are fairly straightforward. I don't have scripts calling scripts, for example. But can you think of out any specific things I should watch out for?

Thanks for helping me understand this.

Link to comment
Share on other sites

I'll be interested in hearing your "lessons learned" breakdown after implementation.

If you utilize a separate message stack for error handling, you can invoke compiled apps willy-nilly without compromising your main loop. I.E., use Run() instead of RunWait()

The message stack could be a windows message, the registry,or a file (xml,ini,txt) . Then one application handles the invoking of the apps, and one handles the error messages.

I've handled this issue by by generating individual files containing the pertinent data, and as they are handled, delete them. Also eases debugging - turn off the error processor, and I can see the exact error messages as they are created. Somewhat messy, (one folder can get a bunch of messages) , but I'm not going to miss a message, and I don't have to worry about whether or not I've handled a message or whether or not something has got the file opened / locked when I'm trying to write to it.

edited for relative brevity/clarity

Edited by flyingboz

Reading the help file before you post... Not only will it make you look smarter, it will make you smarter.

Link to comment
Share on other sites

flyingboz, was your post a response to my topic or a different one? It's just that I don't understand what most of it means or how it applies. I'm still trying to get a foothold on this subject. So my questions remain:

Will the script then be "re-enterable" such that if a previous request is still in progress (like moving 500 files) and a new request is received (like displaying a popup with current date/time) that the second request will be serviced immediately -- or will it be delayed? And does this mean there will be only one copy of the script in PC memory -- or one for each active call?

Is there any problem with receiving requests from different calling applications? I guess what I'm asking is does the OS maintain a "stack" for calling parameters so that parameters from one call can't get jumbled with parameters from another.

And, finally, the comment "you need to be diligent on your design ..." suggests there may be pitfalls. At this point, all of my scripts are fairly straightforward. I don't have scripts calling scripts, for example. But can you think of out any specific things I should watch out for?

Anyone?
Link to comment
Share on other sites

Will the script then be "re-enterable" such that if a previous request is still in progress (like moving 500 files) and a new request is received (like displaying a popup with current date/time) that the second request will be serviced immediately -- or will it be delayed? And does this mean there will be only one copy of the script in PC memory -- or one for each active call?

That depends on how you code it. As flyingboz said if u use the run command the action will be executed and main script will continue to run as usual. So you could have 2 requests at once, it would be like fake multi threading.

Link to comment
Share on other sites

I guess I'm just missing your points entirely. When a script is called from my database application, there is no alternative for "RunWithWait" -- everything is simply a "Run AutoIt Script". In my example above, Function A is simply a sequence of steps within the CompositeScript -- and not a separate AutoIt script.

Can you please help me get to some common ground so that I can understand what you're suggesting. For example, if the script structure I posted above isn't appropriate, what should it be?

Thanks for your help.

Link to comment
Share on other sites

Well, I'm going to be the one to say that it cannot be done the way you have requested... at least the way that I understand what you have requested.

...most called from a database application...

That can mean many things - so I'm going to pick one interpretation and elaborate on it to see if I'm anywhere near close:

You start an MS Access database.

You click on a customized icon that launches one of your scripts.

The script does things and then exits.

You click on another customized icon that launches another one of your scripts.

The script does different things and then exits.

[if that interpretation is wrong, then the rest of my post may be useless.]

...Is it possible to combine such scripts into what would amount to a single companion task that would be initialized once -- as the database application starts -- and then remain running to service individual requests? Script calls would then be of the form:

CompositeScript <functionID> <parameters>...

You can pass info to the "CompositeScript" by having it constantly looking somewhere for that info (Registry, an INI file...) But you will need something to set/change that info each time you press one of those "customized icon" from within MS Access. Something like a second AutoIt script. But then you are back in the boat that you started in - you will need a "second script" for each function to be called.

...> near-instant response to script calls (the equivalent of TSR programs)...

Wow, I've not seen "TSR" used in a long time. I knew that I was old, but...

If the "CompositeScript" is TSR, then "CmdLine" is of little use here.

I do not think that you can feed a compiled script that is already running a new CmdLine.

[Even if I'm wrong about that, it still does not solve your problem.]

So, as I understand your request - you want one script to load when your database loads and stay loaded until your database exits. You want those "customized icons" from within MS Access to act like an AutoIt HotKey - causing a UDF to run inside your "CompositeScript".

I do not see how it can be done, but then again, I don't know all that much.

I await a solution from others that conforms to your spec request of a TSR.

At least "TSR" in the respect that your "CompositeScript" stays running. It is not started and stopped over and over with new a CmdLine or two each time.

TSR: http://en.wikipedia.org/wiki/Terminate_and_Stay_Resident

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

Link to comment
Share on other sites

herewasplato, you have summarized my situation exactly.

Each time I click one of the icons, I want a different set of parameters passed to the memory-resident, "idling" AutoIt CompositeScript -- which would then take the appropriate action, depending on the parameters.

So, is there any approach that would work?

Anyone have a suggestion?

(Thanks for adding the reference to the TSR definition! I didn't think about it being rather dated.)

Link to comment
Share on other sites

Although I've only been using AutoIt for a few weeks, I've built a library of a dozen utilities that perform useful functions, most called from a database application. Compiled and compressed, the scripts now exceed 3 megabytes on my base directory -- plus, there's the overhead of uncompressing when one of them is called. So I was thinking ...

Is it possible to combine such scripts into what would amount to a single companion task that would be initialized once -- as the database application starts -- and then remain running to service individual requests? Script calls would then be of the form:

CompositeScript <functionID> <parameters>

The advantages would seem to be:

> a 90% reduction in the net size of the compiled set of utilities

> near-instant response to script calls (the equivalent of TSR programs)

> a reduction in the "perceived complexity" of the runtime result

Conceptually, this approach sounds good, but I'm very uncertain on how to proceed -- or if it's even practical. If it is, I'd sure like to know of an example that I can learn from -- or maybe get a suggestion of a couple of functions to begin working with. My searches haven't turn up anything of use -- but I can't say I know what terms to search for. This is an entirely new area for me.

Any advice will be greatly appreciated. Thanks in advance.

only 3 mb?

my latest script is over 18 mb.

it will be much larger as i progress through it :)

Link to comment
Share on other sites

herewasplato, you have summarized my situation exactly. ...

Lucky guess :-)

...So, is there any approach that would work?...

The goal (as I see it) is to have those custom buttons write some info somewhere that AutoIt can read and act upon. If the button runs a batch file - the bat file could do any number of things that your "CompositeScript" could read. You might have to suffer thru seeing a cmd window flash by... but the bat file could write to a text file whatever info that you want. You would have one bat file for each of your custom buttons. Each bat file would have only one line:

----bat file-----

echo functionID parameters > c:\temp\test.txt

----bat file-----

When your database starts

your "CompositeScript" starts:

...reads the date/time of c:\temp\test.txt

...loops checking for a date/time change for c:\temp\test.txt

...if change - then read/use file contents

[i think that a simple FileGetTime returning YYYYMMDDHHMMSS would work.]

The bat file meets the criteria of:

...not taking up much space on the drive

...loads quickly

...runs quickly

However, having the cmd window flash by might be annoying and others may know of a better work around than what I'm about to suggest - Make one bat file with one word in it:

pause

Save and run that bat file.

right mouse click on the cmd window title bar

select properties

on the tab named Layout

uncheck "Let system position window"

enter coordinates that place all or most of the cmd window out of sight for your desktop settings

[My XP OS had limits on the coordinates that could be entered, but those limits put the window out of sight for me.]

When closing the dialog box for the window coordinates, select:

"Modify shortcut that started this window"

Hope this helps.

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

Link to comment
Share on other sites

Thanks for the analysis and suggestions. I'll give them consideration, of course -- but I'm now concerned by Volly's initial response:

Sure it can. You need to be diligent on your design, but I see no reason why not. I've done it many times with stuff I design.

Maybe I'm reading too much into that analysis, but something I read a month ago (and can't find now) led me to believe scripts could be called a second time while they're running. I certainly don't want to implement a "square wheel" if a round one is possible.

Hopefully, someone will notice the confusion around this topic and can help to illuminate (or extinguish) the possibilities.

Thanks again.

Link to comment
Share on other sites

BTW, you can compile without compression and get a file about twice as large. I'm not sure which loads faster. I opt not to compress for anti virus reasons and hard drive space is no issue.

...scripts could be called a second time while they're running...

Ain't English grand?

A "call", I'll assume in this case, is something that the operating system is going to do via the command/target line of the "custom button" within an MS Access database.

If by "called a second time" you mean "restarted"; then maybe it was something like the sample code at the very bottom of this page http://www.autoitscript.com/autoit3/docs/f...ns/RunAsSet.htm

That "restart" involves the same decompression time that you hoped to avoid and I cannot see how it could be used for this topic's task... so that probably is not what you saw.

So, restarting defeats the TSR value

...but solves the hard disk volume

[one script vs. many]

If by "called a second time" you mean "start a second instance/copy" [while the first copy is still running], then yes, you can do that. Each custom button can do that using unique CmdLine info. You would have two (or more) copies of your CompositeScript running and you did not avoid the decompression time or come close to a TSR.

So yes, let's see what Volly, sccrstvn93 & flyingboz had in mind.

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

Link to comment
Share on other sites

Rereading this thread, there is confusion about what I envision. To clarify:

> One copy of the CompositeScript running, started by a call from the database application.

> uncompressing takes place only one time

> All functions carried out by steps within the CompositeScript (i.e., doesn't call other scripts)

> After each "call", CompositeScript resumes its idle loop, waiting for another call

In the "old" days, this code would be deemed "re-enterable and re-executable" and the operating system would simply start it each time from the top using a different stack pointer. Things are obviously more complicated today, but the concept seems viable -- even if it involved waiting until the script goes idle before the next call can be handled. Why should it have to go through all the overhead of releasing memory and then reloading the script (and un-compressing) on every call? Worst case, it would need to exit, but stay resident for re-use (hence the TSR designation).

Anyway, I still have hope of a solution with comments like the following (but which I don't understand).

if u use the run command the action will be executed and main script will continue to run as usual. So you could have 2 requests at once, it would be like fake multi threading.

So I remain unsure about how to proceed -- but thanks for all your comments.
Link to comment
Share on other sites

I see now - I thought that you meant just the speed of a TSR because the AutoIt script was never supposed to exit/terminate. I did not know that you had more in mind with that comparison.

Yes, it would be interesting to see just how just a call would be made.

BTW, I'm not a programmer by trade or training...

...so terms like "pointers and stacks" bring to mind "dogs and hay" :-)

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

Link to comment
Share on other sites

Hi gwert,

Sorry I'm a bit late and I'm not sure to understand exactly what you need to do... but if you call a script which is already running you will create a new instance of it...

There is maybe a solution to the problem (if I correctly understand it)... Why would you not make an "exe" for each of your functions instead of grouping them in the same

exe file ?

The "watcher" program (the one running in memory) would only call the appropriate "exe" if a condition is true

The way to proceed could be something like :

- When you click on a button in your database, it only creates a empty text file in a determined directory and this file will have the same name as the "exe" file to run.

- The watcher detects the text file (extract the left side of the "myfile.exe.txt" using the StringTrimRight command).

- The watcher run the myfile.exe and continues to loop.

- The myfile.exe deletes the myfile.exe.txt file when it stops (use OnAutoExit function)

- If you ask your DB to perform and other action in the meantime, as a "myfile2.exe.txt" will be created, the watcher will also detect it and run the appropriate "myfile2.exe" file.

And so on...

This would drive you to maintain several exe files (put them in the same directory) but would allow you to have a "light" resident executable.

What do you think about that ?

Freerider

FreeRiderHonour & Fidelity

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...