PDA

View Full Version : OS_ShellExecute a sequence of programs (a daisy-chain)



JohnP
19-06-2011, 00:28
Hi all,

Can anyone help with this problem?

I would like to run an initial program (call it Prog1) which, when it has finished its purpose, runs another program (call it Prog2) and Prog1 stops, whilst Prog2 continues.

Then, when Prog2 has finished its purpose, it runs another program (call it Prog3) and Prog2 stops, whilst Prog3 continues, etc, etc.

I have written three simple test programs to see how this might work, but no matter what I do, I can only get one program to execute another. The next execution attempted (by the second program) fails, without any error.

e.g. Prog1 will run Prog2, but Prog2 won't run Prog3. Also Prog2 will run Prog3, so there appears to be nothing wrong with the code in Prog2.

It's a complete puzzle. Is there a limit of only one operation in the OS_ShellExecute function?

I am running Win7 64-bit.

My code for Prog1 is shown below and is virtually identical in Prog2, etc, except that the titles of the programs being executed are changed to the appropriate ones:



' Test OS_ShellExecute

' Prog 1

Uses "OS", "console"

Dim pID As Long

Cls
PrintL "PROGRAM 1."
PrintL
PrintL "Now about to run Program 2....."
pID = OS_ShellExecute("open","OS_Shell_prog2.tbasic","","",1)
PrintL "pID=",pID
PrintL

If pID>0 Then
PrintL "pID was greater than zero, so Prog 2 should run."
End If
WaitKey
regards
JohnP

John Spikowski
19-06-2011, 02:29
I you hit the wall, ScriptBasic supports a cascading preprocessor feature that sounds like what you need. The output (results) of the first preprocessor script is the input to the next.

Just an idea if the frustration level becomes overwhelming.

John

ErosOlmi
19-06-2011, 10:23
JohnP,

OS_ShellExecute command is not the right solution.
OS_ShellExecute is a wrapper of ShellExecute http://msdn.microsoft.com/en-us/library/bb762153(v=vs.85).aspx and its main purpose is running verbs ("open", "print", "find", "explore") over registered files extensions and/or operating system shell commands.
Also OS_ShellExecute does not return a process id but just a "not true process handle" HINSTANCE, it is just a number (I will improve documentation on this)


What I think you need is OS_Shell command (whose purpose it to create a new process) using %OS_SHELL_ASYNC option.

Attached two example scripts, the first executes the second and stops. The second execute the third and stop ... and so on.
Remember to remove WaitKey otherwise calling script will still wait for a key to be pressed.

Let me know if it is what you need.

First script


'-------------------------------------------------------
' OS_Shell_prog1.tbasic
'-------------------------------------------------------

Uses "OS"
Uses "console"

PrintL "START ", APP_ScriptName

'...
'...do all the jobs this script has to do...
'...

'---Now execute next script
Dim thinBasic As String = APP_Path & APP_Name
Dim NextScript_Name As String = APP_ScriptPath & "OS_Shell_prog2.tbasic"
Dim NextScript_pID As DWord

'---Executed in async mode. Execution of this script will immediately continue after this command
NextScript_pID = OS_Shell(thinBasic & " " & $DQ & NextScript_Name & $DQ, %OS_WNDSTYLE_NORMAL, %OS_SHELL_ASYNC)
PrintL "Executed process ", NextScript_pID

PrintL "STOP ", APP_ScriptName

WaitKey




Second script

'-------------------------------------------------------' OS_Shell_prog2.tbasic
'-------------------------------------------------------

Uses "OS"
Uses "console"

PrintL "START ", APP_ScriptName

'...
'...do all the jobs this script has to do...
'...

'---Now execute next script
Dim thinBasic As String = APP_Path & APP_Name
Dim NextScript_Name As String = APP_ScriptPath & "OS_Shell_prog3.tbasic"
Dim NextScript_pID As DWord

'---Executed in async mode. Execution of this script will immediately continue after this command
NextScript_pID = OS_Shell(thinBasic & " " & $DQ & NextScript_Name & $DQ, %OS_WNDSTYLE_NORMAL, %OS_SHELL_ASYNC)
PrintL "Executed process ", NextScript_pID

PrintL "STOP ", APP_ScriptName

WaitKey

JohnP
19-06-2011, 10:51
Hi John, Eros,

Thank you both for your very prompt and helpful replies.

@John:
I have had an eye on ScriptBasic for some time and will keep up my interest, thanks.

@Eros:
Your explanation has hit the nail on the head.
I have obviously misinterpreted the purpose of the OS_ShellExecute command and if the thinBasic Help file is extended to contain your clarification, it will help others from falling into the trap that I did.

I have run your suggested code and it does exactly what I wanted.
At a stroke, you have solved a problem I have had for months!

It allows me to split a long, complex program up into 'modules' (each of which deal with particular program operations and which I can use for other related programming tasks) which are each sequentially executed. That helps me to concentrate on programming specific functions within each 'module' and, then, when I encounter an error, it helps me to locate and deal with that specific error more quickly.

Thank again,

regards
John

ErosOlmi
19-06-2011, 11:02
I have run your suggested code and it does exactly what I wanted.
At a stroke, you have solved a problem I have had for months!


Next time, do not wait and ask ;)

We are here to help. Maybe we cannot reply in one second, maybe we have a solution for the next day or so but we will try our best to explain and find a way.
Also requests like yours let us know that something is not correct in thinBasic and/or thinBasic documentation letting us improve the material we produce.

Ciao and thanks
Eros

JohnP
20-06-2011, 00:24
Next time, do not wait and ask ;)

We are here to help. Maybe we cannot reply in one second, maybe we have a solution for the next day or so but we will try our best to explain and find a way.
Also requests like yours let us know that something is not correct in thinBasic and/or thinBasic documentation letting us improve the material we produce.

Ciao and thanks
Eros

Eros,

I try not to waste your valuable time. So I try to solve a problem first, before asking.
But OK, I'll still do that, but will ask for help sooner in future.

Right! Here is the next question then! :D

If the programs being called sequentially have been 'bundled' (NextScript_Name = 'OS_Shell_Prog2.exe' rather than 'OS_Shell_Prog2.tbasic'), how do you then refer to them in the code below?

NextScript_pID = OS_Shell(thinBasic & " " & $DQ & NextScript_Name & $DQ, %OS_WNDSTYLE_NORMAL, %OS_SHELL_ASYNC)

I guessed that one omits the 'thinbasic & ""' part, but that didn't work.

regards
JohnP

ErosOlmi
20-06-2011, 08:03
Ok, here thinBasic has a problem and at the moment I do not know how to solve.

A bundled exe is a sort of .ZIP file containing all the files (original script in obfuscated way plus thinBasic.exe plus all needed modules) needed to execute the original script without the need to have thinBasic installed on the target machine.
When you call first bundled exe: all files are exploded on disk (as system hidden files) in the same directory of the exe
When the first script try to OS_Shell the second bundled exe, it try to explode mainly the same files of the first, but they are already there so an internal error would occur and second exe will not be executed.


Maybe an option could be to create bundled exe setting the flag "Activate Isolation"
This flag instruct the bundled exe that when it is executed, explosion of all the files must take place into a random named directory created under current bundled exe directory. In such a way there will be no conflict between different bundled exe execution.
So if you execute your script from something like C:\thinBasic\SampleScripts\OS\Test\
in reality it will be executed from something like C:\thinBasic\SampleScripts\OS\Test\z8216tmp\
In this case your script 1 should calculate the directory from which execute script 2 (is quite easy using somthing like Dim NextScript_Path As String = LEFT$(LEFT$(APP_ScriptPath, -1), InStr(-1, LEFT$(APP_ScriptPath, -1), "\")))

But I have tested this option and script 2 seems executed not from C:\thinBasic\SampleScripts\OS\Test\xxxxtmp\ but from C:\thinBasic\SampleScripts\OS\Test\xxxxtmp\z8216tmp\
So it seems bundled exe takes its current directory from the caller bundled exe and not from its exe path

So, I'm sorry but I do not a solution right now using bundled exe.

Last chance is to use obfuscated scripts, their execution is like executing a normal script (so previous examples should work) and change script extension to .tBasicx
The problem here is that you must have thinBasic installed in your target machine.

JohnP
20-06-2011, 11:34
Ok, here thinBasic has a problem and at the moment I do not know how to solve.....


.... So, I'm sorry but I do not a solution right now using bundled exe.

Last chance is to use obfuscated scripts, their execution is like executing a normal script (so previous examples should work) and change script extension to .tBasicx.

The problem here is that you must have thinBasic installed in your target machine.


Eros,

I am most grateful for your comprehensive reply.
It really helps to know when one has reached the current limits, and so I won't try to do the impossible!

I will stick to using plain normal script, for simplicity, with thinBasic installed on the target machine. That's fine, thanks.

regards
JohnP