How to interact with programs when names read from a list I have a script which checks for loads of applications if they are open, and closes them if yes, and opens them if not.

Until now I had a simple:

tell application "System Events"
if exists (process "Caffeine") then
    tell application "Caffeine" to quit
else
    tell application "Caffeine" to activate
end if
...
end tell


To go through the programs. Today I had to edit some programs and I figured "this could be so much simpler with an array and a for-loop"

So I tried this:

set theList to {"Caffeine", ...}
tell application "System Events"
repeat with prog in theList
    if exists (process prog) then
        tell application prog to quit
    else
        tell application prog to activate
    end if
end repeat
end tell


But now for some reason I get an error, each time I run the script: 


  error "System Events got an error: Connection is invalid." number -609  


The error pops-up always from a different point in the script.
I'm really confused why this doesn't work.

Can anybody assist me in getting this to work?
"Connection is invalid" means that the script cannot communicate with the application. Perhaps it has been quit during execution… perhaps there is a duplication in your list? My best guess is that there is more than one process spawned by an application.

Anyway, I think your methodology could be improved. One of your problems is that you're checking the process for each item in your list. You should compile a list of processes, and check that. This avoids the problem of duplicate processes for the same application. It also deals with the issue of the process list changing during script execution.

set appList to {"Caffeine", ...}

tell application "System Events" 
    set procList to (name of every process)
end tell

repeat with appName in appList
    if (procList contains appName) is true then
        tell application appName to quit
    else
        tell application appName to activate
    end if
end repeat


If you still get errors, you might have to enclose the tell application statements in try blocks.

One more thing: the approach you're taking doesn't work well if only some of the applications are open, and some are not. You're checking each individually and quitting if it's open, launching if it's not. So your list of applications will still be split between open/shut down. It sounds like you want to open a "set" of applications and close a "set" of applications using the same script.

Therefore, you may want to consider splitting this into two scripts, "open set" and "quit set", and/or checking whether your "main" application is open and cascading the open/close of your application list depending on that one application's state.