Hi Kevin g,
Thanks, that seems to be my issue, can you suggest some code to do that?
The script is compiled and launched, so the problem is making it an AppleScript application rather than a scrip… the script has to be run manually, while the application will run on launching.
Thanks Beatrix,
The script is name-dependent, so it will work for John Doe but not Jane Doe.
The script has to be made each time the app is used.
Thanks again.
Lennox
I’m not sure to understand your problem but if I do, this may help.
Add at the beginning of your script: on run {MyStg1, MyStg2, MyStg3} -- We receive string from Xojo
If you need only one string, just put only one. In Xojo you do:
MyAppleScript(“John”, “Doo”) or MyAppleScript(“John Doo”) depending what you prefer.
I suppose the name will be in a Xojo var string, then you write in Xojo:
MyAppleScript(MyXojoStringWithName)
Just in case you want to use something the applescript return, just write at the end of your applescript: Return MyStringEnd -- Variable which contains what I need in Xojo.
And in Xojo: AppleScriptReturnStg = MyAppleScript(MyXojoStringWithName)
Note: I repeat, AppleScript can only receive and return string. It can receive more than one string but can return only one.
See runAs from Xojo + Alfred . This allows you to define and AppleScripts in Xojo code. The below script runs an AppleScript for all available accounts in Mail:
'make script when there isn't one
if AccountTypeAppleScript = nil then
AccountTypeScript.Add "property theAccount: ''"
AccountTypeScript.Add "tell application id 'com.apple.mail'"
AccountTypeScript.Add "set theAccountType to (get account type of account theAccount)"
AccountTypeScript.Add "return theAccountType"
AccountTypeScript.Add "end tell"
AccountTypeAppleScript = new RunAS(AccountTypeScript, array(0), false, true)
end if
'run with current account
dim theAccountDictionary as Dictionary = RunAS.MakeDictionary("theAccount", theAccount)
AccountTypeAppleScript.ExecuteScriptWithParameters(theAccountDictionary)
return AccountTypeAppleScript.getResult
I am a gynaecologist and I see several patients per day.
There is the Data Protection Act which has lots of requirements, including not displaying any patients data.
So after I have seen a patient, several windows are displayed on my two monitors.
I have to close all those windows before the next patient comes in.
When I close my main window which has the patient’s current medical data, I would like all those windows to be closed at the same time.
I have this code at the bottom of my CancelClose event…
Dim TheAppleScriptScript as FolderItem
TheAppleScriptScript = SpecialFolder.Desktop.child("TheAppleScriptScript.scpt")
Dim TOS as TextOutputStream
If TheAppleScriptScript <> Nil and TheAppleScriptScript.Exists then TheAppleScriptScript.delete
If TheAppleScriptScript <> Nil and not TheAppleScriptScript.Exists then
TOS = TextOutputStream.append(TheAppleScriptScript)
TOS.WriteLine "tell application ""Finder"""
TOS.WriteLine "try"
TOS.WriteLine "close (window " + """" + app.gmyPatientFilesFolder.name + """" + ")" //""Hx Jane Doe 1981-07-28"")"
TOS.WriteLine "close (window ""The Patient Records Folder"")"
TOS.WriteLine "end try"
TOS.WriteLine "end tell"
TOS = Nil
end if
TheAppleScriptScript.Launch
It works, but the AppleScript is displayed and I have to manually click the “Run” icon to close those windows, then I now have to manually quit Script editor.
It would be far easier to send an AppleEvent to the Finder to close the given window:
var ae As new AppleEvent("core","clos","com.apple.finder")
var o As AppleEventObjectSpecifier=GetNamedObjectDescriptor("cwin",nil,"Window's title")
ae.ObjectSpecifierParam("----")=o
call ae.Send
(replacing “Window’s title” with the actual title, of course)
var ae As new AppleEvent("core","clos","com.apple.finder")
var o As AppleEventObjectSpecifier=GetNamedObjectDescriptor("cwin",nil,app.gmyPatientFilesFolder.name)
ae.ObjectSpecifierParam("----")=o
call ae.Send
'var ae As new AppleEvent("core","clos","com.apple.finder")
o = GetNamedObjectDescriptor("cwin",nil,"The Patient Records Folder")
ae.ObjectSpecifierParam("----")=o
call ae.Send
That’s weird; I wrote and checked the code before submitting. If you’re sure the window’s title matches exactly, you may possibly just try this code in a blank project (this avoids others possible issues).
Is your app notarised?
Anything that needs permissions may need a permanent version of the app or macOS will forget the permission when the debug app is killed. And even in debug the app needs to be signed for full disk access. I don’t remember if this is also true for AppleScript.
If you own (or want to try) the MBS plugin, this could work (permissions must be granted):
Var source As String = "tell application ""Finder""" + EndOfLine.Macintosh + _
"try" + EndOfLine.Macintosh + _
"close (window " + """" + app.gmyPatientFilesFolder.name + """" + ")" + EndOfLine.Macintosh + _
"close (window ""The Patient Records Folder"")" + EndOfLine.Macintosh + _
"set result to errMsg" + EndOfLine.Macintosh + _
"end try" + EndOfLine.Macintosh + _
"end tell"
Var n As New NSAppleScriptMBS(source)
Var d As Dictionary
Var result As NSAppleEventDescriptorMBS = n.execute(d)
If d <> Nil Then
// display errormessage
MessageBox (d.Value(NSAppleScriptMBS.NSAppleScriptErrorMessage))
End if
I read your code but I do not know how to use it for my needs.
All I want is to close two windows when I close my app, the code will go in the close event of my app.
The two windows are:
“The Patient Records Folder”
and
“Hx Jane Doe 1981-07-28”
My apple script works, regardless of the location of the folders, once the windows are opened, on closing my app the AppleScript is launched but I have to click “Run the script” icon for the windows to close.
That works but I have to manually click “Run the script” and then quit Script Editor.
I do not want to perform those two clicks manually.
Any other suggestions/code will be appreciated.
My app is an app for my personal use, t is not being old.
go into the privacy and security pane and make sure that your application has permissions to control the finder via automation. You may have to reset this after each build of the app, but you may not it does not seem consistent to me. You may not be able to get this working for a debug build as the app will go away when you’re done running it and so you can’t add it to the list. If you can put a delay before you run the script then it may work OK.
Then just pass your file to osascript in the terminal. So after you’ve written the file out do something like:
dim sh as new shell
sh.execute( “/usr/bin/osascript “ + TheAppleScriptScript.shellPath)
Just as I had it before, the AppleScript is created and launched.
I now save it as an app, put it in the patients folder and launch ehe AppleScript.app when I am closing the patient’s main file… works great, I do not have to make those clicks again.
The drawback is that I have to create the AppleScript.app for each patient, but I only have to do it once for each new patient.
Thanks everyone for their inputs, concern and willingness to help.