Best way to use: tell application "System Events" - applescript

I was thinking about what is the best way to use this statement for GUI Scripting:
tell application "System Events"
There is any difference with
tell application "System Events"
tell process "Finder"
-- do something with the GUI
end tell
end tell
and
tell application "Finder"
tell application "System Events"
-- do something with the GUI
end tell
end tell
Moreover It seems that "process" statement can access the GUI while application one can't.

It seems like you answered your own question. The first example works and is correct, the second example does not work and should not be used.

If you write
tell application "Finder"
tell application "System Events"
end tell
end tell
you need to keep the "Finder" tell structure open for as long as you need the "System Events" tell structure. This might mess up your code and it could cause problems if multiple apps have conflicting commands.
"System Events" rarely or never conflicts with anything and is needed relatively often. It makes sense to have a very long "System Events" tell structure but it doesn't make sense to have a very long "Finder" tell structure.
Whether you use process or application has nothing to do with it. Both can access GUI scripting, but you may need System Events to do this while controlling an app other than Finder.

Related

Script Editor hiding when telling a different application to close/hide

Why does the following Applescript hide Script Editor?
tell application "Last.fm" to launch
tell application "System Events" to tell process "Last.fm" to keystroke "h" using command down
This code I found will hide "Last.Fm", but also hides Script Editor. Ideally, I want to replace the keystroke "h" with a keystroke "w" but then I get an error:
The document can’t be closed while the script is running.
Why does the script I wrote effect Script Editor?
I don't have Last.fm, so I tried this:
tell application "TextEdit" to launch
delay 2
tell application "System Events" to tell process "TextEdit" to keystroke "h" using command down
And sure enough, it's true, TextEdit was hidden but so was Script Editor.
Then I tried this:
tell application "TextEdit" to launch
tell application "TextEdit" to activate
delay 2
tell application "System Events" to tell process "TextEdit" to keystroke "h" using command down
TextEdit was hidden, but Script Editor was not. So I would guess that this will help in your code too. Having the target app frontmost appears to be crucial (which makes a certain amount of sense, after all).
What is the functionality you're trying to achieve here? Is this the whole script? You want last.fm to launch, and then, ideally, to close the window?
tell application "System Events" to tell process
Doesn't work because it is highly misleading - it will not actually direct a keystroke to a particular application, the keystroke goes wherever it would go when it's hit regardless of the "tell process" statement, which is annoying.
I don't use last.fm, but either of these works for me:
tell application "TextEdit"
launch
activate
end tell
delay 0.1
tell application "System Events"
keystroke "w" using command down
end tell
or
tell application "TextEdit"
launch
activate
end tell
delay 0.1
tell application "System Events"
click menu item "Close" of menu 1 of menu bar item "File" of menu bar 1
end tell
Note that if you plan to run the script from a key command or the script menu, and don't want it to steal focus to last.fm, you can have it launch, close the window (or hide it), and then return you to the front app when the script was run:
set appPath to the path to the frontmost application
tell application "Finder"
set appName to the name of file appPath
set appName to text 1 thru ((offset of "." in appName) - 1) of appName
end tell
tell application "TextEdit"
launch
activate
end tell
delay 0.1
tell application "System Events"
keystroke "w" using command down
end tell
tell application appName to activate

Applescript halts at a line and then won't continue (telling a not running app to hide)

So I have a very basic Applescript here that basically hides all my social networking related apps, and then a similar one that unhides them. Problem is that if one of these apps isn't running then the entire thing halts at that line and won't set the ones below that line to hidden either.
Here's the script:
tell application "System Events" to set visible of process "Twitter" to false
tell application "System Events" to set visible of process "Wedge" to false
tell application "System Events" to set visible of process "Facebook" to false
tell application "System Events" to set visible of process "Adium" to false
tell application "System Events" to set visible of process "Messages" to false
Am I doing this the wrong way? Do I have to check to see if each one of these is running first, or is there some way to get it to continue with the script either way?
EDIT: Experiencing the same thing with this script, which I use with an Alfred hotkey to quit specific apps and start the screensaver when I leave work:
tell application "Adium" to quit
tell application "Messages" to quit
tell application "1Password" to quit
tell application "iTunes" to quit
tell application "ScreenSaverEngine" to activate
So basically if iTunes - for instance - isn't running then the screensaver will not start, but the 3 apps before that line will all quit.
You can wrap each statement in a try block so it will fail silently:
set myApps to {"iTunes", "1Password"}
repeat with anApp in myApps
try
tell application anApp to quit
end try
end repeat
You Could use the try command as specified above and use on error do nothing to do it.
Hint: with the [Enhanced Application Object Model][1] you can also do things like this:
if application "iTunes" is running then
tell application "iTunes" to quit
end if
or
tell application "iTunes"
if it is running then
pause
end if
end tell
[ How to check in AppleScript if an app is running, without launching it - via osascript utility ]

keystroke "1" using command down - beeps instead of working

I'm writing a simple applescript that should focus an app and click "cmd+1".
This is what I wrote:
tell application "System Events"
tell application process "appname"
--Lobby focus
activate
keystroke "1" using command down
end tell
end tell
But instead of working, there's one beep and the application doesn't even take focus.
How can I solve this?
You can't tell processes to activate. Change it to set frontmost to true:
tell application "System Events"
set frontmost of process "Finder" to true
keystroke "1" using command down
end tell
Or tell the application to activate:
activate application "Finder"
tell application "System Events"
keystroke "1" using command down
end tell
If the application has no open windows, reopen opens a new default window:
tell application "Finder"
reopen
activate
end tell
tell application "System Events"
keystroke "1" using command down
end tell

Unnamed Window in Applescript

I'm scripting iTunes with applescript using UI scripting. Depending on what I'm doing an iTunes notification will appear, at which point I need to handle it. The name of the window is AXWindow: "", and I can't seam to get applescript to handle it. I've tried using the literal "", I've tried defining a variable to "", I've tried both cases with escape characters, and I've tried getting the name of the frontmost process.
tell application "System Events"
set processName to name of front window
end tell
tell button "whatever" of window processName
click
end tell
But that comes up with "error "System Events got an error: Can't get window 1. Invalid Index."" Any help on this would be greatly appreciated.
You can do something like this:
tell application "iTunes" to activate
tell application "System Events"
tell process "iTunes"
set xxx to first UI element whose role description is "dialog"
end tell
end tell
Or to find them all:
tell application "iTunes" to activate
tell application "System Events"
tell process "iTunes"
set xxx to every UI element
end tell
end tell
Well, usually notifications or user dialogs will show up as the frontmost window and stay on top of the other windows of the same application until the user (or the script) clicks something.
Thus, the dialog window (if there is any) should be accessible via the specifier window 1. You can then further check if that really is the window you're interested in by reading its properties:
tell application "System Events" to tell application process "iTunes"
properties of window 1
end tell

Why is my applescript not working?

I'm trying to make an applescript that will click in the same spot over and over again buy i can't get it to work.
tell application "Safari"
activate
end tell
repeat
tell application "System Events"
click at {1, 1}
end tell
delay 1
end repeat
You will have to tell System Events in which application the click should be executed, like the following example (this should theoretically open your bookmarks, if you have a maximised Safari window):
tell application "System Events" to tell application process "Safari"
click at {5, 75}
end tell
On a side note, you should think about a better title for your question next time, this is too general.

Resources