I use Xojo 2022r3.2 on a Mac mini M1. I am currently trying to port on MacOS a Xojo app developed for windows. My app uses Office automation to interact with Microsoft Word. I therefore need to replace the OLE commands by Applescripts.
I therefore created an Applescript to get some of the styles from a word document, putting the styles in a list and returning the list as text to my Xojo app. It works under the script editor, I can see the list returned by the script. The script has been dragged-dropped to the XOJO UI and appears in the list of scripts available for my app.
But the code in Xojo receives an empty result. No error, just the result Xojo gets is empty.
My script âlisterstylesâ is this:
on run
tell application "Microsoft Word"
set monmodel to make new document
set maliste to {}
set b to count of Word styles of monmodel
repeat with a from 1 to b
set nomitem to name local of Word style a of monmodel as text
if nomitem contains "titre" or nomitem contains "heading" then
set end of maliste to nomitem & ","
end if
end repeat
close monmodel saving no
end tell
return maliste as text
end run
My Xojo code is this:
dim malistemac() as string
dim applescriptresult as string
applescriptresult = listerstyles
MessageBox(applescriptresult) 'this is for verification propose; this is supposed to display the items returned, but mess box piping up is empty
malistemac() = applescriptresult.Split(",")
In the Xojo debug window the âapplescriptresultâ variable appears empty (in fact there is nothing in âtextâ tab, and there are some hexa data in the left column of the binary tab),
Any idea why Xojo does not receive the value returned by the AppleScript?
You may want to verify that the applescript actually gets the proper value. This will display an applescript dialog showing maliste. If the dialog does not show in the IDE, try the same script in the script editor.
on run
tell application "Microsoft Word"
set monmodel to make new document
set maliste to {}
set b to count of Word styles of monmodel
repeat with a from 1 to b
set nomitem to name local of Word style a of monmodel as text
if nomitem contains "titre" or nomitem contains "heading" then
set end of maliste to nomitem & ","
end if
end repeat
close monmodel saving no
end tell
display alert maliste
return maliste as text
end run
Thanks so much for this snippet Beatirx. Iâve been beating my head for days trying to work out why a perfectly functional Applescript wonât work in Ventura when called in the same way it has for many years. Is this documented somewhere?
Apple is slowly putting the clamp down on AppleScript for (perfectly valid) security reasons. Putting this bit of stuff into your appâs info.plist informs the system that it needs to use Apple Events (the underlying technology behind AppleScript). Without it, the OS silently drops your AppleScript requests and returns null. Itâs not a great design.
When your app tries to run a script for the first time, the system will ask the user if itâs OK for the app to do this. If the user says yes, the system remembers this setting for the future, and you will see a listing for the app in System Preferences > Security & Privacy > Automation.
Thanks for the explanation -I was wondering how Apps found their way into the Automation area. It seems Apple components are spared needing to do this as I could happily run scripts with simple dialogs etc without issue.
If the app isnât authorized to send Apple Events â i.e., if the user says âno wayâ when the system asked them for permission - the AppleScript never even gets executed, so your try blocks do nothing.
'get permissions for new app
dim target as NSAppleEventDescriptorMBS = NSAppleEventDescriptorMBS.descriptorWithBundleIdentifier(BundleID)
// we ask for all apple events
PermissionsForApp = NSAppleScriptMBS.DeterminePermissionToAutomateTarget(target, "****", "****", true)
PermissionsDictionary.Value(BundleID) = PermissionsForApp
if PermissionsForApp = 0 or PermissionsForApp = -1 then
'everything okay
Return True
else
'show the user what they need to do
end if
From my AppleScript handler ârunASâ (Xojo + Alfred)
You can add a script in the Xojo Build:
Right click on âmacOSâ in âBuild Settingsâ, then âAdd to âBuild settingsââ - âBuild Stepâ - âScriptâ.
In this script paste the code:
If (CurrentBuildTarget = 7) or (CurrentBuildTarget = 16) Then ' Mac OS 32bit ou Mac OS 64bit
Dim TpTextA, TpTextB, TpTxtErr as String ' https://www.mbsplugins.de/archive/2019-03-31/Required_keys_for_infoplist_fi
' OpenFile(CurrentBuildLocation) ' "c:\projects\IDEScriptTest.xojo_binary_project")
' OpenFile(CurrentBuildLocationNative)
' OpenFile("/Volumes/MBtom-HD2/Tampon/TextBatchConv.app/Contents/Resources/fr.lproj/Localizable.strings") ' Ouvre dans l'IDE
' Mac for Test : TpTextA = CurrentBuildLocationNative + "/" + CurrentBuildAppName + "/Contents/Resources/fr.lproj/Localizable.strings" ' NativePath
TpTextA = CurrentBuildLocation + "/" + CurrentBuildAppName ' + ".app"
' Print(ProjectShellPath)
TpTxtErr = ""
' ####################
TpTextB = DoShellCommand("/usr/bin/defaults write " + TpTextA + "/Contents/Info ""NSAppleEventsUsageDescription"" ""Modify folder window view, Add login item, Make alias, Select item.""")
If not(TpTextB = "") Then
If TpTxtErr = "" Then
TpTxtErr = TpTextB
Else
TpTxtErr = TpTxtErr + EndOfLine + TpTextB
End If
End If
' ####################
TpTextB = DoShellCommand("/usr/bin/defaults write " + TpTextA + "/Contents/Info ""NSContactsUsageDescription"" ""Read Contacts in your AddressBook.""")
If not(TpTextB = "") Then
If TpTxtErr = "" Then
TpTxtErr = TpTextB
Else
TpTxtErr = TpTxtErr + EndOfLine + TpTextB
End If
End If
' ####################
If not(TpTxtErr = "") Then Print(TpTxtErr)
End If
There are 2 Plist modifications between the 3 â####################â. The first one is to allow Applescript in your application, the 2nd is to allow it to access AddressBook.
I modify this script from what I copied here in the Xojo forum with the help of the members.