AppleScript and non-scriptable applications - applescript

I'm wondering how can I script applications which has no dictionary. All information that I've found tells me nothing. But my experience says me that there is a way.
For example:
tell application "Firefox"
return count of windows
end tell
Will work. And it will work with "Opera" and other applications without dictionary at all. So the questions are:
1) Why does it work?
2) What else work in such a manner? Is there a list of all such actions?
Thank in advance!

You can to some extent script applications without an applescript dictionary by using 'tell application "System Events"'
tell application "Keynote" activate
tell application "System Events" to keystroke "c" using {command down}
end tell
end tell
This example activates Keynote and then copies the current selection. You can use similar code in many applications even if they don't have an applescript dictionary provided you also have the "Enable access for assistive devices" option checked in the "Universal Access" System Preference.
Edit:
This document gives some details of how Cocoa provides some support for Applscript in all applications:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ScriptableCocoaApplications/SApps_about_apps/SAppsAboutApps.html
Under the heading Built-in Support for Standard and Text Suites

You can open the scripting dictionary of FireFox. Just open AppleScript Editor and go File → show dictionary, and choose FireFox from the list.
It just shows a very rudimentary dictionary. What happens is that the system library provides at least a basic set of commands (called the Standard Suite) to any Carbon or Cocoa app. This is what contains the definitions of window you used.
As Ian already wrote, in order to do more with such an app, you use the so-called UI scripting via System Events.
This nice website is a good place to start.

Related

Automator permissions error when running AppleScript in Safari – Alternatives and security risks?

I want to use Automator and AppleScript to fill out a form in Safari. I have a functioning script that looks something like this toy example:
on run {}
tell application "System Events" to keystroke "Hello"
tell application "System Events" to keystroke tab
tell application "System Events" to keystroke "World"
end run
I wish to execute it with a keyboard shortcut when I'm at a specific point in my browser. However, when I do this, I run into permission issues:
The action "Run AppleSCript" encountered an error:
"System Events got an error: Automator Workflow Runner
(WorkflowServiceRunner, my_script_name) is not allowed to send keystrokes"
In System Prefrences -> Security & Privacy -> Privacy -> Accessibility I have allowed both Automator and AppleScript Utility, and under the Automation tab, I have allowed System Events for Safari.
I can get it to work, at least temporary, if I allow Safari in Accessibility too, but that seems to be too drastic and a security risk to have Safari to always have full control just to run a script from time to time.
How should I approach this? I want the script to be easy to use, and wouldn't want to go into the settings each time to temporary allow Safari. Or can this be automated too? Is there a completely different approach than Automator and AppleScript that would allow me to do this in a more user friendly and safe way? Basically, I want to do something similar to what AutoHotKey would be able to do in Windows.
I’m guessing that what you’ve done is set up a Quick Action and then given that Quick Action a shortcut under “Services” in “Keyboard:Shortcuts” in System Preferences. I was able to duplicate the problem by doing that: attempting to run the script requires that Safari itself have access to “control your computer”. If that is not what you’ve done, this solution should still work, but you may also want to update your question, in case a better solution is available.
What you can do is use redirection. Create an application that can be given permission to control your computer, and then create a Service that will launch the application.
Use Automator (or Script Editor) to create an Application with the above steps, adding as the first step tell application "Safari" to activate. You need that step because opening the app will take the focus away from Safari.
Save this Application. (If using Automator, you tell Automator that it’s an application when you start creating the script; if using Script Editor, you tell Script Editor that it’s an application when you save the script.)
Use Automator to create a Quick Action. Give it the action “Launch Application” and tell it to launch the application you just created.
Drag the application you created in step 2 into the “Accessibility” list in System Preferences’s “Security & Privacy” settings. (You may have to unlock those settings to allow changes.) It should be checked automatically when you drag it in, but if not you can check it.
In the “Services” list in the “Keyboard:Shortcuts” settings of System Preferences, the Quick Action you created in step 3 should be listed. Give it a keyboard shortcut.
At this point, you should be able to use the keyboard shortcut to run the application, and only that application needs to have permission to control your computer.

If Preview.app in OS X is not Applescriptable why does this work?

I have asked another question on AskDifferent about Preveiw scripting dictionaries, and have done a subsequent search here which says Preview is not scriptable.
However when I run:
tell application "Preview"
set save_location to ¬
(choose file with prompt "Choose the png to be modified")
activate
open save_location
end tell
It works. Does that mean that Preview.app is scriptable with Applescript 2.2.1 and Max OS X 10.7.5 which is what I am using?
If so then where can I find a listing of the objects?
All Mac applications respond to the Open and Activate commands even if they do not have dictionaries. Your script works because it exploits the built-in capabilities of any application. The absence of a dictionary means that you cannot query or manipulate open documents and windows (i.e. the application's data model).
However, you can use UI Scripting to select menu items, click buttons within windows, and send keystrokes to the application.
You can find out what Preview's dictionary is by launching /Applications/Utilities/AppleScript Editor and choosing File>Open Dictionary from the menu bar, finding Preview in the list of applications shown there, and clicking Choose.

MacOSX or AppleScript: get current URL from Firefox

How can I get the current URL from Firefox (3 or 4)? All solutions I have found so far either don't work (e.g. those with "class curl") or are ugly hacks which are no solution for me (sending key presses to copy the URL to clipboard).
Well, I have one solution now: I am reading it out of the current session store of Firefox. This works but it is always up to 10 seconds out-of-date.
Here is the code:
https://github.com/albertz/foreground_app_info/blob/master/mac/app-scripts/url%20of%20Firefox.py
tell application "Firefox" to activate
tell application "System Events"
keystroke "l" using {command down}
keystroke "c" using {command down}
end tell
Easy, if you install two components:
the mozrepl firefox extension (github)
and WWW::Mechanize::Firefox perl module
If you have installed both, the following command
perl -MWWW::Mechanize::Firefox -E 'say WWW::Mechanize::Firefox->new(tab=>'current')->base()'
will print the topmost active firefox url, in like:
http://stackoverflow.com/questions/5296995/macosx-or-applescript-get-current-url-from-firefox
Since Firefox 87 you can use native AppleScript GUI scripting to get the current URL. That's because Firefox now has support for VoiceOver.
First enable Firefox support for VoiceOver by going to about:config and setting the accessibility.force_disabled property to -1. Note that VoiceOver doesn't have to be enabled, only the support in Firefox. (Extra info at [2].)
After that, you can use:
tell application "System Events" to get value of UI element 1 of combo box 1 of toolbar "Navigation" of first group of front window of application process "Firefox"
[1]: Enabling VoiceOver support makes Firefox expose the internal structure of its window for GUI scripting.
[2]: For extra info and a non-permanent option (toggling AXEnhancedUserInterface via AppleScript) look at this bug report.
A window's URL is not exposed via the Applescript API; not even a window's tabs. The only way you'll be able to get it is through GUI scripting.
Firefox's Applescript implementation is simply awful, and I don't know why they even bother.
Firefox 3's AppleScript implementation is lame enough that you have to resort to copying the URL out of the Location field, as shown in the last post is this thread.

How can I open the Dropbox preferences window using Applescript?

How can I open the Dropbox preferences window using Applescript?
I'm assuming it would be something along the lines of
tell application "System Events"
tell application "Dropbox"
keystroke "," using command down
end tell
end tell
But this isn't working. Perhaps it's because Dropbox is running in the tray / background? ie: I can't switch to it using command-tab.
Thanks!
Unfortunately there is no way to do this. NSStatusItems (of which Dropbox is one) are not visible via accessibility. This weblog entry and this bug provide more information. Please file a bug and reference that bug number if this is important to you.

What can you do with AppleScript?

Everything I know about AppleScript I taught myself and was wondering if I missed any cool features. I know you can make the computer talk to and control applications but is there anything else it can do or is it time to move on to a new language?
The coolest thing about Applescript I've recently discovered, is that you can script almost anything on your mac. So even application, which don't support Applescript natively, can be used in a workflow.
This is possible, because you can just "press" buttons as if you're sitting on the computer.
tell application "GhostReader" to activate
tell application "System Events" to keystroke "n" using command down
I used this to copy and paste a website from Safari and have it read by GhostReader, a proprietary text to speech tool.
When it comes to Applescript, application control is where the action is. There's not much of a "wow" factor within Applescript itself unless you're a real language nerd. It's really more about presenting a set of easy-to-use tools to control the "wow" factor of other applications.
I've seen (and have) examples of Applescript playing simple card games and other text-based fun (well...as much fun as one can have viewing one display dialog after another), but these are (at best) academic exercises to show off the robustness of the language itself or a specific feature of Applescript.
Simple, but I use this all the time!
tell application "System Events"
display dialog "$msg" with icon stop buttons {"Foo", "Bar", "OK"} default button "OK"
end tell
Whenever I'm doing some shell programming, it's convenient for my operation to bring awareness into Finder, via a dialog.
Very handy.
You can automate everything on your Mac, this is a great time saver.
I remember coding shell on C++ on Windows, it's just a pain to automate Windows.

Resources