Xojo initiated AppleScript will not launch Keyboard Maestro

Mac: Mojave
Xojo seems to be happy to run AppleScripts. In the documentation, the example is given of a simple AppleScript to open iTunes. I can implement that, and it works just fine.

Keyboard Maestro is Mac application that runs scripts. It can be called using AppleScript specifying the name or UUID of the script that you want to run. This is a three-line AppleScript and works just fine when I run it from the ScriptEditor. However, when I try and run it from Xojo, nothing happens. I find this baffling.

I can even make a composite AppleScript that opens iTunes and tries to fire up the Keyboard Maestro script. iTunes opens up appropriately but nothing happens on the Keyboard Maestro side of things.

Does anyone have an explanation for this? Has anybody run into something like this?

1 Like

I think this is a “feature” of Mojave and later. Apple continues to lock down more and more useful stuff, even of their own making such as Applescript. For example see this forum thread from 2018.

I haven’t followed all the status of Applescript because I chose to just ignore it and find alternatives for what I wanted to do. Most often using various MBS plugin features. Note that I don’t think this is a problem with Xojo per se; I believe it is Apple restrictions blocking otherwise useful features. Or making you jump through hoops to use them.

Others who still try to use Applescript may chime in with more useful answers.

Apple Script is on my list of articles to write for my blog, because of the steps required to use it modern versions of the macOS.

I recently added Apple Script support to an alpha of App Wrapper 4 as it’s required to access certain features in DropDMG.

  1. I used my own NSAppleScript object from the Ohanaware App Kit to execute the Apple Script. I have not tested with the built-in Xojo functions or other libraries.
  2. Code sign your application with the harden runtime option.
  3. Make sure it uses entitlements, as you need to provide the entitlement to be able to send Apple events.
  4. Make sure you’ve specified a “Privacy Usage” message. You can only provide one message, to encompass all of the applications that your app is targeting.
  5. Specifying which application that you’re sending Apple Events too, didn’t appear to make any difference.
  6. For each build of the application, there should be a dialog box asking the user if they approve of it using Apple Script.
  7. Handle the result, you need to check for an error. If the user clicked on “Don’t Allow”, a specific error is returned, at which point you can alert the user that they need to manually allow access for this functionality to work.
  8. There is API to check to see if your application can script an application, before you call the Apple Script. I found this to be unreliable and to cause more problems that simply trying and capturing the failure message.

If AW4 was able to do what it needed without Apple Script, I would have given up and used the alternative method. The above described process was pieced together with information from Apple’s developers forums (not their documentation) and tweaked until it worked. I spent a lot of time getting this far.

The above process can be done with AW3, but I’ll confess that I haven’t tried yet. I was going to do so when I wrote the article for my blog.

Lastly: If you are considering the Mac App Store and the application you’re controlling doesn’t support “Scripting Groups”. I would recommend you consider if it is worth it. You’ll face a higher chance of being rejected for using the “legacy” Sandbox entitlements, than being accepted. You may be able to talk your way around it, you may not.

Did you use DeterminePermissionToAutomateTarget method in NSAppleScriptMBS class to query status?

I have written this up for my blog, which I’ll keep updated when and if things change.

Sam, thanks for sharing.
You may want to revise your blog to spell AppleScript correctly (no space) so that searches will find it.

lol… Thank you, writing, spelling and grammar are one of my worst enemies! I’ll correct it in the morning.

As Douglas Handy/Sam Rowlands/Christian Schmitz have alluded to, my fundamental problem of being able to have Xojo fire off some AppleScripts and not others is related to increasing security measures that Apple has introduced with Mojave and Catalina. I was trying to run from Xojo an AppleScript that would initiate a Keyboard Maestro macro. This was not permitted although there were other AppleScripts that I could run that were permitted. While I got answers on this forum that pointed me in the right direction, they were over my head in terms of implementing what I was trying to do. A contributor (tiffle) to the Keyboard Maestro forum was able to help and for the benefits of people who might come to this thread in the future, I include his very complete response: (KM = Keyboard Maestro)

I’ve owned Xojo for several years so this discussion caught my eye. I hasten to add I am NOT a Xojo expert. It just so happened that a few years ago I had to develop a database app and Xojo was the easiest approach to use.

I’ve tried to do what you did and discovered that the Xojo log itself reveals the cause of the problem.

Here’s the screenshot:

You can access the log by clicking the icon at the bottom (circled in red).

As to why the script is not authorised to send Apple events to KM is another matter. The Xojo Applescripts documentation talks about Apple Events on Mohave and later. Reading through I tried this: in the app produced by building the Xojo project, I edited the info.plist file and added a line for NSAppleEventsUsageDescription . You can see this in the screenshot below:

Now, when I run the app (the one whose info.plist I just edited) it executes the KM macro as intended.

I wanted to post this asap so you can see all is not lost with Xojo but I’ve yet to figure out how to get Xojo to put the need extra permission into the info.plist file at build time, rather than having to do it manually. If I get time I’ll have a look later.

In the meantime, stay safe!

This was immediately followed by a second post:

So, replying to my own post, this is how to get Xojo to automatically give permission to apps to use Applescripting…

As I said, Xojo needs to add some extra information to the info.plist file it creates in the app bundle when you build your application. This is documented but simply, you just have to create your own info.plist file with the extra information in it and tell Xojo to add that to the one it builds by default.

To save you the trouble, here is a zipped version of that file: Info.plist.zip (992 Bytes) and it contains this:

CleanShot 2020-09-29 at 11.37.45
All you need do is then unzip this file and drag the result into you Xojo project, like this:

It appears as info in the Xojo navigator.

When you run your compiled and built app, it will popup a dialog telling you that the app wants to control KM to which you click OK. When you’ve done that, your app will appear in the Automation section of the Privacy system preferences, like this:

201011SecurityPrivacy

Obviously, the apps you build with Xojo will not necessarily be called My Application.app

I hope this helps. If I’ve left some gaps in the explanation, or you find out other things, keep the discussion going!

Using tiffle’s suggestions, I was able to accomplish what I wanted which was to use an AppleScript imbedded in Xojo to fire off a Keyboard Maestro script.

The screenshot below shows the navigation bar with the file that tiffle supplied (Info2) and the AppleScript (AardvarkPrepare). Both have been dragged to this location.


AardvarkPrepare is very simple.

At this point, all works pretty well. It is cool that in Xojo you can just write a line of code

AardvarkPrepare

in, for example, the action event of a button and the AaarvarkPrepare.scpt in the navigation bar of the same name will run. It will even auto-complete when you are typing that line of code. And this particular AppleScript will launch the Keyboard Maestro macro.

201011AaardvarkPrepareScript

__

For the record, when I attempted a more complex Keyboard Maestro, I ran into a problem that stumped me for a considerable time. The Keyboard Maestro macro that I was running bounced around various apps (one of the magic powers of Keyboard Maestro) and then returned to the Xojo app to get some additional information. The whole process was initiated by a menu event handler in Xojo. When the logic of the macro brought it back to Xojo a second menu event handler in Xojo was used to keep the chain of Keyboard Maestro commands going.

This did not work. I am not sure exactly why, but when I tried debugging the situation it was apparent that, while nothing crashed, I did not end up with the desired outcome. If I launched the same Keyboard Maestro macro using a hotkey trigger in Keyboard Maestro then things worked just fine.

For whatever reason, the menu event handlers in Xojo never really completed until after all the Keyboard Maestro steps had been run. In some sense, it was suspended. So if I wrote some code to time-stamp and log the ending (last line of code) of the menu event handlers those lines of code did not happen until after everything in Keyboard Maestro had completed.

To deal with this situation, I changed tactics slightly. I did not imbed the AppleScript script in the navigation bar of Xojo. Rather I saved the AppleScript as an app rather than the default complied script. Xojo was informed of the path of this app on the file system of the computer.

Var NAME_KM_MACRO As String // The simple AppleScript app that initiates KM script
NAME_KM_MACRO = “AardvarkPrepare.app”

Var f As folderitem = SpecialFolder.Desktop.Child(NAME_KM_MACRO)
If f <> Nil And f.exists Then
f.open
End

So the Keyboard Maestro macro was fired off by opening the app (AardvarkPrepare.app). That overcame the issue. It involves having to know where in the file system the app lives and making sure that the location corresponded to the Xojo code but it works. (In the example I put the code on the Desktop)

So in this special circumstance, I use the

f.open

technique but usually I can just put the AppleScript title in the navigation bar and access it from there.