I'm trying to build a script that opens all of the web dev programs I use. I want the print("Opened all apps")
to only run once all 3 programs have opened and fully loaded (rather than currently printing after just opening the programs and not waiting for them to load) because I want to do something after they've loaded.
I have the following:
import subprocess
chrome = "Google Chrome"
mongo = "MongoDB Compass"
vsc = "Visual Studio Code"
apps = [chrome, vsc, mongo]
for app in apps:
p = subprocess.Popen(["open", "-a", app])
print("Opening " app)
p.wait()
print("Opened?")
print("Opened all apps")
However, the problem is that p.wait()
seems to not wait for each app to load. Does anyone know why this happens and how to make it wait properly for all apps to fully load?
I tried the suggestions from this post: Python: waiting for external launched process finish
Thank you for any advice
CodePudding user response:
The wait
method waits for the process to exit. There's no standard way to tell when a program has "finished" starting up.
CodePudding user response:
That depends on your definition of "load".
subprocess
spawns simple processes in a subshell, once the process completes it returns an exitcode. wait
does just that, it waits for the exitcode. That does not guarantee that your app will be fully loaded, since the processes spawned by the subprocess module get the exit code of the open
command, and not your apps themselves. think of this as a "fire and forget" type of mechanism, though not as limited as os.system()
.
if you truly want to wait for these apps to load, then you must determine what constitutes that each of those apps is fully loaded.
- The simplest way (but most of the time incomplete) would be to check a list of processes spawned by that app and see that they're all running.
- From the user perspective, an app would be fully loaded once the GUI is up and running.
- Screenshots and image recognition. This would be the least reliable.
If you want the latter, I'd advise you look into software automation libs. This is one of my favorites: atomacos This allows your python script to attach to a process and check out the UI elements. From there you can simply keep querying to see if a certain Native UI element is displayed and visible, which would mean that your app has loaded.
I recommended this native lib because of 2 reasons:
- I noticed you used
open -a
which made me assume you're on MacOS - Even though some of these applications might be webapps, they need to be started with certain flags for the web automation frameworks to have control over the application. Attaching to an already running process would be much simpler.
atomacos
has its drawbacks, however. It needs some exceptions added to the Security settings of your OS, so there's that to take into account.