Console App Updater

I have a main Console app that I run 24/7 on many computers (Windows, Linux and Mac). I need to update this main Console app to later versions. So I have another Console ‘Updater’ app that the main Console app downloads and runs via a Shell command.

With Windows I use a Windows Service for the main Console app, so it’s fine, but I have a problem with Linux and Mac launching shell applications asynchronously (Mode = 1) using the ‘nohup … &’ command. This is what happens on Mac/Linux:

  1. main Console app downloads it’s new version plus an Updater Console app
  2. main Console app launches Updater Console app via asynchronous Shell and keeps itself running (otherwise the Updater Console app will be killed)
  3. the Updater Console app moves the old Console app aside and moves the new version into place
  4. the Updater Console app should now kill the old (still running) main Console app, then launch the new main Console app, then the Updater Console app should quit itself.

This is working down to number 4 where the new version is being launched, but dies once it’s Parent i.e. the Updater Console app quits itself.

How can I launch another console application in a shell and have the launched app not be killed when the Parent application is quit?

I have checked out the forum posts below, but none describe my situation above.

https://forum.xojo.com/15981-shell-w-external-applications
https://forum.xojo.com/18064-making-a-shell-script-survive-quit

If you launch the app using a shell and follow the command with &, does that work?

/path/to/command &

No. Using both 'nohup /path/to/app &’ and ‘/path/to/app &’ cause the the second app to be quit on MacOS after the first calling app quits. The only exception is if Mode=0 i.e. synchronous, but then I have all three apps running (original console app, updater app and new app version)!

I think this works for MacOS X:

Shell.Execute("open -a " + f.ShellPath + "; exit")

It has gracefully quit it’s parent apps without taking down the Shell child app.

I use @David Cox’s tip for all of my long running helpers that need to run beyond the GUI’s life.

[quote=167947:@Greg O’Lone]If you launch the app using a shell and follow the command with &, does that work?

/path/to/command &

That would require that the shell would need to open without a TTY attachment (which would mean that you couldn’t monitor its I/O). Otherwise, when the Parent GUI app exits, the exec’d shell precess dies because the parent is gone - this is what happens in Xojo (and must without major reworking of the Shell).

David, I do exactly this in the Kaju project. Take a look to see how I did it.

http://github.com/ktekinay/Kaju

I think the key is, after starting the Shell command, you have to give it a little bit of time to actually start, but there may be another difference that will help you.

[quote]I think the key is, after starting the Shell command, you have to give it a little bit of time to actually start, but there may be another difference that will help you.
[/quote]
I have been working on this for literally days, including putting delays in before the Shell.Close and after. Thats how I was able to get the process working right up until the newly updated app was running, but like a Slinky™, when I quit the old app, that quit the updater, then that quit the new app!

It works well with MacOS X, but I have had to use the ‘nohup /path/to/app &’ command for Linux and I am testing the ‘start /path/to/app’ command with Windows.

Have you considered using cron to run your updater?

Shell.Execute("at now < " + f.ShellPath)

cron wont wake a mac up

I must have missed something. I didn’t see waking the computer up as a requirement for updating an app.

24/7 server you might but no the OP didn’t say that was required

On OS X you also have the NSUnixTask and NSTask objects for controlling ‘console’ applications, you can launch a console application via NSTask and quit the main task, while the console application continues to run.

That is great Sam. I was precisely wondering how to launch a console program without it being tied to the parent.

Thank you :slight_smile: