sending Apple event to console application - applescript

I have console app named "MyApp" it is running and I see it in the activity monitor.
I'm writing in AppleScript Editor the script:
tell application "MyApp"
display dialog "Hello World"
end tell
When running the script the editor asks me where is MyApp? And it doesn't appear in the list it shows. When I'm trying to brows it's location, I can't select MyApp's bundle.
How can I deal with it? Thanks!

You need to add NSAppleScriptEnabled to Info.plist. The entry looks like:
<key>NSAppleScriptEnabled</key>
<true/>
You can find this entry in all scriptable apps, such as:
open /Applications/Preview.app/Contents/Info.plist
Because it's manually added, you might need to re-add the code if you recompile the app.

The solution I found is to addressing the bundle identifier and not the application name.
tell application id "com.MyApp.app"
display dialog "Hello World"
end tell

Related

`AXFocusedUIElement` <- does not get focused element (folder, file), it points to `Finder` menu

trying to reproduce right-click context menu on my Mac.
I found such an article:
https://beebom.com/how-right-click-using-keyboard-mac/
I did accordingly but when I click my keyboard shortcut I get Finder menu not a currently selected file/folder menu.
This is an apple script used,
on run {input, parameters}
tell application "System Events" to set frontApp to name of first process whose frontmost is true
tell application "System Events"
tell application process frontApp
set _selection to value of attribute "AXFocusedUIElement"
tell _selection to perform action "AXShowMenu"
end tell
end tell
return input
end run
Spent hours trying to get this basic and obvious to every Windows user functionality to work, lost of time and very frustrating!
I think code is correct, maybe there is something specific on my computer that stops it from working as expected?
Please help :-)
Not sure i understood what is actually not working for you, but i had problem to reproduce the same script, once i wrote it in Automator.app i tried to press "play" button to see if the script was working and it was telling me something like "syntax error, can't get attribute AXFocusedUIElement of application process Automator" (from memory, not sure it's exactly what was written)
and struggled for a while as well untill i realised there was a pop window that i didn't see, saying me that "automator wants permission to control this computer using accessibility features (this thing in the system preference, security and privacy, privacy, accessibility), so i opened, there was a list of apps allowed to control my computer, i ticked Automator.app and after that it worked
Then every app that i was trying to do a right click was showing me the same pop up and i had to do the same for each one (safari, finder etc...)
And then it worked
Hope might help you!
Encountered same issue.
Allow 'Finder' to control computer at System Preferences>Security & Privacy>Privacy>Accessibility.
Worked for me

exploring avaliable commands in an applescript program

I have an application and I can do the following command on (I know this because I googled for it):
tell app "TextMate" to reload bundles
What I would really like is to be able to ask the "TextMate" program:
tell app "TextMate" to list all commands
and have it list out all the things I can ask it to do:
... 'reload bundles', 'exit', 'open files'...
is there a way to do that with applescript?
The way to find all the commands of an app is to open its dictionary in your script editor. Usually "Open Dictionary ... " in the File menu, or drop the application onto the script editor.
[EDIT]
For applications that have AppleScript support, you can actually script opening the app itself with the Script Editor, a la:
set pathToApp to (choose file of type "APPL")
tell application "Script Editor"
open pathToApp
end tell
BUT this will be problematic with a non-scriptable app. You'll get an error, but Script Editor will actually open some part of the app (and it will be slow about it), then give you an unusable document. There's no way to catch this error. If you use the Smile script editor, you can use this method ...
set p to (choose file of type "APPL")
try
OpenDictionary(alias (p as string))
on error e
end try
... to open the dictionary of an app, and if it doesn't work (if the app doesn't have a dictionary), it returns an error but doesn't do anything else (but again, you can't catch the error and not have it complain, without hacking Smile)
[EDIT 2]
A rabbit hole to go down is trying System Events or the Finder to check for boolean of has scripting terminology property of a process, but I don't recommend it because I haven't found it to be reliable.
[EDIT 3]
Ach! I knew there was another method, but forgot what it was. As #mklement0 points out (thank you), you can do this to check for an app's script-ability prior to opening the app in Script Editor:
set pathToApp to (choose file of type "APPL") as text
set isScriptable to false
try
class of application pathToApp
-- only AppleScriptable applications have a class property
set isScriptable to true
end try
isScriptable

Is it possible to write an applescript so that when I close one program it also closes another?

The example I can think of that is most relevant to me is to be able to close the last.fm app when I close iTunes. I quite often forget to close last.fm and I find it rather annoying. I'm sure there are other uses...
Yes you can.
Over on my Blog thecocoaquest I have two posts that cover this.
The first Post shows you a methods of doing this with a applescript and using a Launch Agent.
Applescript – Quit or Launch Application if another is or is not running
Here is one of the examples:
If I have one App running the second app will launch and will always be running while the first app is running.
Or when I quit the first App the second app will also quit
#!/usr/bin/osascript
#Copyright Mark Hunte 2012
#http://www.markosx.com/thecocoaquest/kill-one-application-if-another-is-not-running-applescript
set appMustBeRunning to "xcode"
set appToKill to "Snippets"
tell application "System Events"
set appMustBeRunningID to (unix id of processes whose name is appMustBeRunning)
set appToKillID to (unix id of processes whose name is appToKill)
end tell
if appMustBeRunningID is {} then
try
tell application "Snippets" to quit
end try
else if appToKillID is {} then
tell application "Snippets" to launch
end if
The Second post is a revision showing how to add more than one master & slave application
Applescript – Quit or Launch Application script.. ( Revised )
Also has an a script for if you just want to run the Applescript as an Application.

AppleScript syntax to automate Xcode 4.1 to Clean, Build then Run

I appreciate that there are already questions on this topic, but having read the ones I can find (particularly this one: Tell AppleScript To Build XCode Project), they all seem to be a couple of years old and the answers do not seem to apply to the current version of Xcode.
Similarly to the linked question, I am attempting to automate opening an Xcode project, building it and then running the app in the iPhone Simulator (v4.3). The project in question is the Selenium project's iPhoneDriver (see here for details: http://code.google.com/p/selenium/wiki/IPhoneDriver)
Based on the answer in the other question, I have written the following script:
tell application "Xcode"
open "/Users/<username>/Documents/Code/Selenium/iphone/iWebDriver.xcodeproj"
tell project "iWebDriver"
clean
build
try
debug
end try
end tell
end tell
Unfortunately, when I run this I get the following:
tell application "Xcode"
open "/Users/ben.adderson/Documents/Code/Selenium/iphone/iWebDriver.xcodeproj"
--> project document "iWebDriver.xcodeproj"
clean project "iWebDriver"
--> missing value
build project "iWebDriver"
--> missing value
debug project "iWebDriver"
--> error number -1708
end tell
If I run just the open command, Xcode opens the project without issue. But as soon as I include the rest of the script the Xcode icon in the dock bounces, but that's all I get, apart from the above from the AppleScript Editor.
Can anybody advise what I'm doing wrong? This is the first time I've used AppleScript or Xcode, so I'm struggling to diagnose the problem.
I've tried looking at the Xcode AppleScript Dictionary, but without worked examples I can't quite determine the syntax I need.
Thanks in advance for any help!
Using a mix of AppleScript, and command line tool (xcodebuild), I came up with this:
-- This script will clean, build then run the project at the path below.
-- You will need to slightly modify this script if you have more than one xcodeproject at this path
set pathOfXcodeProject to "/Users/<username>/Documents/Code/Selenium/iphone/iWebDriver.xcodeproj"
-- End of configuration
do shell script "cd " & pathOfXcodeProject & " && /usr/bin/xcodebuild clean build "
tell application "Xcode"
open pathOfXcodeProject
activate
end tell
tell application "System Events"
get system attribute "sysv"
if result is greater than or equal to 4144 then -- Mac OS X 10.3.0
if UI elements enabled then
tell application process "Xcode"
click menu item "Run" of menu 1 of menu bar item "Product" of menu bar 1
end tell
else
beep
display dialog "GUI Scripting is not enabled" & return & return & "Open System Preferences and check Enable Access for Assistive Devices in the Universal Access preference pane, then run this script again." with icon stop
if button returned of result is "OK" then
tell application "System Preferences"
activate
set current pane to pane "com.apple.preference.universalaccess"
end tell
end if
end if
else
beep
display dialog "This computer cannot run this script" & return & return & "The script uses GUI Scripting technology, which requires an upgrade to Mac OS X 10.3 Panther or newer." with icon caution buttons {"Quit"} default button "Quit"
end if
end tell
Let me know if this works for you.
I tested it against Xcode 4.2.1 on Lion, with an iPhone project.
If you're ok with Xcode coming to the foreground, I would use this instead:
tell application "Xcode"
activate
open "/Users/<username>/Documents/Code/Selenium/iphone/iWebDriver.xcodeproj"
end tell
tell application "System Events"
key code 15 using {command down}
end tell
Although I vote and cheer the above AppleScript, which is really good (and also works…) being all professional, taking care of old versions, and extreme cases etc. The script suggested by the question should have worked in the first place.
The reason it doesn't work is broken Xcode scriptability. Not only "clean" doesn't work. Most everything I tried to do with the internal object model of Xcode doesn't work.
AppleScript architecture (OSA) requires an application to expose a "human understandable" object graph that AppleScripts can reference. In Xcode it may look like:
tell target "my library" of project "my project" of workspace "my workspace" to clean.
or
tell application "Xcode" to close all projects whose name contains "Lib"
User-Interface scripting is the last resort of the scripter when application scriptability is poor. Because the UI hierarchy is standard in nature, and its scriptability is free from Cocoa, it most always work.

Create AppleScript for a program that isn't installed on the current computer

I'm trying to make two copies of an AppleScript, one that works for Entourage and one for out Outlook. I only have Entourage installed on the current computer.
According to the info on Microsoft's site, both applications have the same library of AppleScript commands, and I should be able to simply change the application name referenced within the script.
Changing:
Tell application "Microsoft Entourage"
to
Tell application "Microsoft Outlook"
Prevents me from saving the script because I don't have outlook installed on this computer. Is there any way around this? Do I need to use a text editor to edit the actual script file and change it there?
Thanks!
The following work-around may do the trick. On the computer where Entourage is installed, a using terms directive will let you compile the script, even if Outlook is not installed:
set theApp to a reference to application "Microsoft Outlook"
using terms from application "Microsoft Entourage"
tell theApp
get version
...
end tell
end using terms from
Upon compiling and saving the script the AppleScript Editor will bug you about the missing Outlook application, but it will nevertheless produce a compiled AppleScript file (.scpt).
Applescript is a pre-complied file format, meaning that every time you click "Save" it runs through a series of steps to ensure the script will work, but just short of actually running through the script's logic. Part of those steps is to look for the application to see if it exists on the Mac.
In short, if you want to save the script as an Applescript, you need the target application installed, otherwise you can save the script as a text file and move the file over to the target Mac to save as an Applescript over there.
It should be possible to make one script that works with both Entourage and Outlook, without bugging you if one isn't found either when you compile or when you run. I don't have either Entourage or Outlook but it should work like this:
using terms from application "Microsoft Entourage"
script theScript
tell application "Finder" to try
set theApp to application file id "Entourage's Bundle ID" as text
on error
set theApp to application file id "Outlook's Bundle ID" as text
end try
tell application theApp
-- do stuff
end tell
end script
end using terms from
store script theScript in "MyScript.scpt"
"using terms from" is only relevant when compiling the script - it isn't needed when running, though for some reason you'll still get bugged if that app isn't found. So by wrapping it around a script object and then writing out that script to file, the resultant script will still run but won't contain "using terms from" and so won't bug the user.
For getting a reference to the right app, Finder can look for it by ID and simply error if it isn't found rather than bugging the user. You'll need to insert the proper ID's there, I don't know what they are.

Resources