Computer Science Canada

How to start one program from another

Author:  Cezna [ Sat Jul 03, 2010 6:55 pm ]
Post subject:  How to start one program from another

I am currently making a Turing program that will allow you to start several other turing programs.
I have done something like this before, but it was only with two programs 9not counting the one that ran them), and I had to modify them to make them into units.

For this one, I want it to be generic to I can very easily add new programs for the central program to start, and I want to do as little modification to the programs that it will be starting as is possible.

I thought of using include, but this didn't work properly, since the way I am doing it is to have buttons for each programs, which means I have to use if statements, and hence any programs that have procedures, functions, classes, etc., won't work since none of these can be declared within an if statement.

I also intend to have it so that you get back to the main program by clicking on it's window, which I haven't gotten to yet, but if anyone has any better ideas, please let me know (again, I hope to modify the other programs as little as I possibly can, and thus I don't just want to have to press a certain key to go back to the main program).

Author:  DemonWasp [ Sun Jul 04, 2010 2:40 am ]
Post subject:  RE:How to start one program from another

Run the programs as separate processes (I'm assuming you have one "launcher" program and it never really needs to talk to the "client" programs at all). This is pretty simple -- I think it's Sys.Exec in Turing -- and doesn't require changing the client programs at all.

You may have to compile your client programs into executables (.exe) to execute with Sys.Exec; I don't know whether you can invoke Turing such that it will load and run a file from the command line.

Author:  Cezna [ Sun Jul 04, 2010 9:06 am ]
Post subject:  RE:How to start one program from another

How do I use Sys.Exec with files that have spaces in their names?

I have found that it will not work if the file has a space in it's name, and when I change the name of the file, taking out the space, and then use Sys.Exec with the new file name, it works fine.

Also, using Sys.Exec does not allow me to close the window using any controls in the program (such as clicking on the launcher window, or clicking a "end program" button in the launcher window).

I don't want the launcher to be able to open more than one program at a time, and the only way I could think of was to use a boolean to represent whether a program is being run.
It is simple enough to set this boolean to true when a program is launched, but there is no way I can find to set it to false when the program is closed.

Author:  Euphoracle [ Sun Jul 04, 2010 9:10 am ]
Post subject:  RE:How to start one program from another

Why don't you code each program as a 'Window' and use Window.Open to spawn each program from within the same process so you can terminate and control them as you desire.

Author:  Cezna [ Sun Jul 04, 2010 9:12 am ]
Post subject:  RE:How to start one program from another

That's what I originaly planned to do, and what I have done in the past, but this requires too much modification of the original code, and several of the programs that the launcher is dealing with use multiple windows themselves, so this would mean even more modification of the code.

Author:  Euphoracle [ Sun Jul 04, 2010 11:23 am ]
Post subject:  RE:How to start one program from another

Well there's no other way to do this... what programs are you launching anyway?

Author:  Insectoid [ Sun Jul 04, 2010 4:27 pm ]
Post subject:  RE:How to start one program from another

I think there's an escape character for spaces in filenames but I don't know what it is. I've used Sys.exec before with files with spaces but that was three years ago and I don't have the code anymore.

Author:  Tony [ Sun Jul 04, 2010 4:35 pm ]
Post subject:  RE:How to start one program from another

If you wrap the filename around in double quotes, that should work for lunching files with spaces in their name
code:

Sys.Exec("\"file name.exe\"")


The unescaped string that is passed to the command line is "file name.exe"; which is how spaces are typically handled. The second layer of quotes is to have this as a string object in Turing.

Author:  Cezna [ Tue Jul 06, 2010 10:38 am ]
Post subject:  Re: RE:How to start one program from another

Tony @ Sun Jul 04, 2010 4:35 pm wrote:
If you wrap the filename around in double quotes, that should work for lunching files with spaces in their name
code:

Sys.Exec("\"file name.exe\"")


The unescaped string that is passed to the command line is "file name.exe"; which is how spaces are typically handled. The second layer of quotes is to have this as a string object in Turing.


So do I need those back slashes, or are those just to show where the seperations would go between folders?

The files I am launching are mostly games I have made.

Author:  TheGuardian001 [ Tue Jul 06, 2010 11:35 am ]
Post subject:  Re: RE:How to start one program from another

Cezna @ Tue Jul 06, 2010 10:38 am wrote:
Tony @ Sun Jul 04, 2010 4:35 pm wrote:
If you wrap the filename around in double quotes, that should work for lunching files with spaces in their name
code:

Sys.Exec("\"file name.exe\"")


The unescaped string that is passed to the command line is "file name.exe"; which is how spaces are typically handled. The second layer of quotes is to have this as a string object in Turing.


So do I need those back slashes, or are those just to show where the seperations would go between folders?

The files I am launching are mostly games I have made.


The backslashes are what allow you to have quotes inside a string, so yes, you do need them. Without them, you would have two empty strings wrapped around a syntax error.

Author:  Cezna [ Tue Jul 06, 2010 9:30 pm ]
Post subject:  Re: RE:How to start one program from another

TheGuardian001 @ Tue Jul 06, 2010 11:35 am wrote:
Cezna @ Tue Jul 06, 2010 10:38 am wrote:
Tony @ Sun Jul 04, 2010 4:35 pm wrote:
If you wrap the filename around in double quotes, that should work for lunching files with spaces in their name
code:

Sys.Exec("\"file name.exe\"")


The unescaped string that is passed to the command line is "file name.exe"; which is how spaces are typically handled. The second layer of quotes is to have this as a string object in Turing.


So do I need those back slashes, or are those just to show where the seperations would go between folders?

The files I am launching are mostly games I have made.


The backslashes are what allow you to have quotes inside a string, so yes, you do need them. Without them, you would have two empty strings wrapped around a syntax error.


So say the file is called 'program', and it is in folder, 'PROGRAMS', which is in folder 'OTHER FOLDER'
I would put:
code:

Sys.Exec("OTHER FOLDER\PROGRAMS\\"program.exe\"")


Also, any ideas about my above mentioned issue with closing the programs or keeping track of how many are running (since closing the program by exiting out of the window could not be made to return any sort of value to indicate to the launcher that the program has been closed)

Author:  TheGuardian001 [ Tue Jul 06, 2010 10:03 pm ]
Post subject:  Re: How to start one program from another

Cezna wrote:

So say the file is called 'program', and it is in folder, 'PROGRAMS', which is in folder 'OTHER FOLDER'
I would put:
code:

Sys.Exec("OTHER FOLDER\PROGRAMS\\"program.exe\"")


Also, any ideas about my above mentioned issue with closing the programs or keeping track of how many are running (since closing the program by exiting out of the window could not be made to return any sort of value to indicate to the launcher that the program has been closed)


No, you would use
code:

Sys.Exec("\"OTHER FOLDER\\PROGRAMS\\program.exe\"")

Backslashes are escape characters. They are used to put characters that cannot normally be contained in a string into a string. This includes quotes (\"), newlines (\n, \r, or \r\n, depending on OS) and backslashes (\\, since \ is used as an escape character, a second one is needed)

For example,
code:

%If the numbers below don't line up with the quote marks, number the quotes
%1 to 4 in order of appearance.
..................1 2......................3 4
var s : string := " "this string has quotes" "
%the above is wrong. Below is the correct string:
var t : string := " \"this string has quotes\" "

The compiler sees the first quote (1) as a the start of the string. It then sees another quote (2), and thinks the string is over. Then it sees the words this string has quotes and crashes, because there are no variables or procedures by those names. The \ tells the compiler that the character after the \ should be considered part of the string, not a sign to end the string value.


If you were to launch this program from the command line, you would run "OTHER FOLDER\PROGRAMS\program.exe" (with quotes included). However since you are now going to store this as a string, it needs to be surrounded by quotes (which screw up the quotes stored in the string.) To get around this, you use the \ character to escape them (as well as to escape the backslashes)

breaking the call down bit by bit:
code:

Sys.Exec(  %CALL Sys.Exec
"   %START THE QUOTE
\"  %we want a quote inside our string, since it has spaces (\" is treated as " when compiled)
OTHER FOLDER\\PROGRAMS\\ %Double backslashes, so they can be stored in the string as well (\\ is treated as \)
program.exe\"  %End the quote that is inside of our string
") %end the string, and the call.


As for keeping track of the running programs, you can't unless you combine all of their respective source codes into one giant horrible mess of a program (Or use some elaborate "include" setup), or use a different programming language that allows you to access other running processes' information.

Author:  Cezna [ Wed Jul 07, 2010 7:47 pm ]
Post subject:  RE:How to start one program from another

@ Guardian001
Thank you, that cleared it up a lot, and I now understand how to work with programs with spaces in their names

Does anyone have any idea about only allowing one window open at a time (I stated the details more thoroughly above, but don't want to keep spaming it)

Author:  Tony [ Wed Jul 07, 2010 8:58 pm ]
Post subject:  RE:How to start one program from another

I think you were asking about knowing when a process exists -- you'd need some utility that will tell you about process statuses. There is ps on *nix Operating Systems. I don't know about Windows.

Author:  Cezna [ Thu Jul 08, 2010 2:08 pm ]
Post subject:  RE:How to start one program from another

I typed ps into Turing, but it didn't come up bold.

Author:  chrisbrown [ Thu Jul 08, 2010 2:19 pm ]
Post subject:  RE:How to start one program from another

ps is a command-line program, not a Turing keyword; it won't help you here.

While your launcher can't talk directly to a process that it spawns, you could modify those programs to be launched to write a new file on startup and delete on completion.

Then have your launcher continuously check for the existence of that file. If it exists, another program is running, so the launcher should become/stay hidden. Otherwise, a program has either finished or nothing has been launched, so the launcher should be visible.

Author:  Tony [ Thu Jul 08, 2010 2:21 pm ]
Post subject:  RE:How to start one program from another

Of course, should the program end unexpectedly via exceptions, it might not have a chance to write about its exit status. The only system that knows about the status of a process for a fact is the kernel.

Author:  chrisbrown [ Thu Jul 08, 2010 3:26 pm ]
Post subject:  RE:How to start one program from another

True. Windows' 'tasklist' program will display running processes, but even with a batch file and output redirection, I can't figure out a way to stop the command prompt from opening momentarily while it executes, so I don't think that's going to work for OP.

Without decent CLI integration, the heartbeat method is probably the best way to go. I think it was discussed somewhere recently.

Author:  mirhagk [ Fri Jul 09, 2010 9:25 am ]
Post subject:  RE:How to start one program from another

How about have both programs connect to each other on the loop back address, I forget the syntax to write this exactly (almost 2 years since I really worked with Turing other than simple operations).

If the host program calls the new program, and the new program connects to the host program on the loopback address, then you can have both programs communicate to each other, being able to not only tell about whether the file is open or not, but also be able to send commands back and forth, for instance closing the child program from within the main program.

I am going to fool around a bit with the network part of turing, I'll be back in 5-10 minutes with some code that should work.

Author:  mirhagk [ Fri Jul 09, 2010 10:00 am ]
Post subject:  Re: How to start one program from another

So I believe this code should work (my turing doesn't compile programs right, stupid 4.1.1)

Here's the main program
Turing:

put "starting program.exe" %obviosuly your code would go before here
var address : string %used to store the address of the connecting computer
if (Sys.Exec ("program.exe") = false) then %start the file
    put "program could not be found" %if it doesnt start tell the user
else
    put "waiting for program to connect to main"
    var client := Net.WaitForConnection (9000, address) %wait for a connection
    put "connected, checking to make sure that the program is connected still" %now the program is connected
    var timeSinceLast := 0 %the amount of time that's passed since last msg was recieved
    var msg : char %to store the recieved message
    loop
        if (Net.CharAvailable (client)) then %if there is anything to read
            get : client, msg %get it from the client
            timeSinceLast := 0 %reset timer
            put msg .. %display the one character
        else
            timeSinceLast += 1 %if nothing to read add to the timer
        end if
        exit when timeSinceLast > 1000 %if the timer is above 1000 (1 second)
        %the program has "timed out" so we know it has ended
        delay(1) %delay by a millesecond
    end loop
end if


and the program (you need to compile it first)
Turing:

put "started, connecting to host"
var host := Net.OpenConnection ("127.0.0.0", 9000) %connect to host and store the connection in an int
put "connected, transmitting welcome message" %now it's connected
loop
    put : host, "hi" %write to the host that it's still connected
    exit when hasch () %exit when you press any key
    delay (5) %delay by 5 milliseconds (just so the byte stream doesn't get to full
end loop


Author:  Cezna [ Fri Jul 09, 2010 10:28 am ]
Post subject:  RE:How to start one program from another

@ mirhagk
I'm not sure exactly what that will do, but it looks to me like you are just writing the client program into the launcher's run window.

Author:  mirhagk [ Fri Jul 09, 2010 11:32 am ]
Post subject:  RE:How to start one program from another

No it runs the client, and the client just says hi until it ends, then it times out on the hosts side, letting you know when it's done


: