Best way to manage an external process

Hi. I’m new to Xojo. I would like to create a GUI desktop app that launches an external process. The process will run a task and then close. I need to get output from the process, ideally in real-time. I might need to send input to the process but maybe I can put everything in the command line. I don’t want the GUI to freeze while the process is active.

What are my options with Xojo? Can anyone share their experience?

Hi Ken,
Welcome to the community. It sounds like you would use an asynchronous shell Shell — Xojo documentation to launch & interact with your UI.

1 Like

Thank you. I’ll have a look!

I added a property to keep the Shell in scope. Then I made a button to click and launch the process. How do I handle events (DataAvailable, Completed)? Can I add a method to process data as it comes in?

You can drag a shell onto your window and add event handlers to it in the normal fashion. (If Shell isn’t shown in the Library, drag out a Generic Object and change it’s Super to Shell.)

Alternately, you can instantiate the shell as a property and use AddHandler to connect its events to methods.

You may also want to look at the new Worker class. Worker - Xojo Documentation

1 Like

Thank you. I tried adding Shell to the window and it works but what do I do with the event? I looked up DataAvailable in the docs and it doesn’t tell me anything. Is the assumption that I get the data from the Shell object? Or is there something else?

I see the Shell object has “Result” and that is appended each time. But can I get the specific data that triggered the event?

EDIT:

I found ReadAll. Maybe that is the best way to get the data? It returns the output and clears the buffer.

1 Like

If you run the shell in synchronous mode (the default), your app pauses until the shell command finishes and you get the results of the command back in Shell.Result. Eg.,

dim s as String
myShell.Execute("some command")
s = myShell.Result

If you run the shell in asynchronous mode, then your app continues while the shell executes and you get your results in the DataAvailable event using ReadAll. Eg.,

myShell.Execute("some command")
// continue processing while the shell does its thing

Later, in DataAvailable

dim s as String
s = me.ReadAll
// process the results

Note that you could get multiple DataAvailable events while the shell is processing. You know the shell is finished when you get a Completed event.

So, synchronous = no events, use Result. Async = no Result, use the events.

1 Like

Okay, thanks again. :slight_smile: ReadAll seems to be working, so I will go with that.

Is this a one-way communication?

Yes. One way. My intent was to give the OP some fundamentals of shell processing. I avoided discussing shell in interactive mode and only mentioned workers. This rabbit hole could go much deeper.