Opening programs in applescript using "Choose file" - macos

I have an application were the user chooses an application to send a command to. but I keep getting an error message when I run it.
set setApp to choose file
tell application [setApp]
end tell

There's a special dialog for choosing an application:
set theApp to choose application
tell theApp to activate

Related

How to close file picker dialog on mac with AppleScript?

I have file picker in my macos application that works through AppleScript command:
choose file of type {"", "png", "jpeg", "jpg"} with prompt ""
The problem I currently have is that users can open multiple file picker dialogs at once. I am looking for a way to close all of the opened file picker dialogs before opening a new file picker dialog but I have not no progress with this.
Is there any way to close previously opened file picker dialogs?
Following script will close "Choose File" dialogs of all instances of your app opened before.
set processName to "Script Editor" -- edit here the name of your app
tell application "System Events"
repeat with aProcess in (processes whose name is processName)
set frontmost of aProcess to true
try
click button "Cancel" of window "Choose a File" of aProcess
end try
end repeat
end tell
NOTE: to test the script above with "Script Editor", you should open 2 instances of "Script Editor" (with single "choose file" code line) then open 3rd instance of "Script Editor" with script above and run all of them. First, run 2 firstly created instances.
You can open the instances of Script Editor (or, other app) with this helper script:
use framework "AppKit"
use framework "Foundation"
use scripting additions
set theApp to choose application
set appPath to POSIX path of (path to theApp)
set appURL to current application's class "NSURL"'s fileURLWithPath:appPath
set theWorkspace to current application's class "NSWorkspace"'s sharedWorkspace()
set startOptions to current application's class "NSWorkspaceOpenConfiguration"'s configuration()
set startOptions's activates to true
set startOptions's createsNewApplicationInstance to true
theWorkspace's openApplicationAtURL:appURL configuration:startOptions completionHandler:(missing value)

How do I tell if the frontmost window is a NSOpenPanel / file open dialog in MacOS using Applescript?

I'm trying to automatically change the directory of the frontmost "file open dialog" or NSOpenPanel dialog with AppleScript, whether that window is part of any application. The idea is that I hit a hotkey, and it will control that dialog to switch to a particular folder.
I can't seem to find out how to find the attributes of a window that would filter it for a "file open dialog". Using the Accessibility Inspector I can find that the "class" is NSOpenPanel. How can I get the class of a window using Applescript?
If you run the following AppleScript, you can see the properties of the foremost window:
tell application "anApp" to activate
delay 1
tell application "System Events"
tell process "anApp"
properties of window 1
end tell
end tell
The app has to be active to see the properties of the windows; You will not get consistent results if the app is in the background.
The NOOpenPanel ought to be recognizable by testing for some combination of the following properties:
role description:"dialog"
title:"Open"
subrole:"AXDialog"
name:"Open"
description:"dialog"
Personally, I'd probably rely on name and role description, which should be the same anytime an app throughs up a standard 'Open' dialog. 'Save' dialogs will be the same, except that title and name will be 'save' rather than 'open'.
If you have an app that presents a open or save sheet (a sub window attached to the titlebar), not a separate dialog, then you'll shift things a little. The AppleScript to get the properties looks like this:
tell application "anApp" to activate
delay 1
tell application "System Events"
tell process "anApp"
tell window 1
properties of sheet 1
end tell
end tell
end tell
and the relevant testable properties are as follows:
accessibility description:"save"
role description:"sheet"
role:"AXSheet"
description:"save"
You'll probably have to add logic to test whether the front window has a sheet, which should distinguish between dialogs and sheets.
Some apps use non-standard open/save dialogs, and you'll have to account for them on a case-by-case basis. There's no magic bullet for that.

With Applescript I need to use System Events to navigate a Finder Window that opens within an application

I'm currently writing some Applescript to import some material into software which doesn't have much applescript support and virtually no documentation on Applescript. The two methods are to somehow adapt this script to work:
on adding folder items to this_folder after receiving these_items
try
tell application "Isadora"
import media into document 1 from these_items
end tell
on error msg
display dialog "Error importing file into Isadora: " & msg
end try
end adding folder items to
However when I try to use "import media into document 1 from ________" I always get an error, in every incarnation of that combination.
My second approach then is using System Events to navigate through the menu bar to import everything. When I get to the import part of things where I can navigate and select the files, a finder window pops up. My question is:
How do I navigate this finder window within the application? This is like the inception of scripts. A finder window within a program.
I tried a few simple things like calling the front window of finder to navigate somewhere and what not. The current script that gets me to the import window is:
tell application "IsadoraCore"
activate
delay 2
tell application "System Events"
click menu bar item "File" of menu bar 1 of application process "IsadoraCore"
click menu item "Import Media..." of menu "File" of menu bar item "File" of menu bar 1 of application process "IsadoraCore"
end tell
end tell
Any help would be appreciated!
I would guess the "import media" window is a Finder window where you select a file to import. This window is easy to handle. To select the file you must have the posix path of the file. In that window if you keystroke "shift-command-g" then you get a text field where you can keystroke the posix path. For example, let's say I want to open a file in TextEdit. The file is on my desktop with the name test.txt. I can do this...
set filePath to (path to desktop as text) & "test.txt"
set posixPath to POSIX path of filePath
set aShortDelay to 0.5
tell application "TextEdit" to activate
delay aShortDelay
tell application "System Events"
keystroke "o" using command down -- bring up the "open dialog window"
end tell
delay aShortDelay
tell application "TextEdit" to activate
delay aShortDelay
tell application "System Events"
keystroke "g" using {shift down, command down} -- bring up the "goto folder sheet" in the open dialog window
delay aShortDelay
keystroke posixPath -- enter the posix file path
delay aShortDelay
keystroke return -- dismiss the "goto folder sheet"
delay aShortDelay
keystroke return -- dismiss the "open dialog window"
end tell
Notice I have delays after every command. That is good practice when you're using this type of scripting. You don't want the code to run faster than the computer can perform the tasks so the delay gives the computer time to keep up with the code. Notice that I use a variable for the delay. This way I can play with aShortDelay making it longer or shorter as needed to make the script run properly.
Good luck.
Aren’t you asking Isadora to import a list of folders? Perhaps it can only handle one folder at a time?
I don’t have Isadora to test, but you might try this:
on adding folder items to this_folder after receiving these_items
try
tell application "Isadora"
repeat with the_item in these_items
import media into document 1 from the_item
end repeat
end tell
on error msg
display dialog "Error importing file into Isadora: " & msg
end try
end adding folder items to

AppleScript -> Activate window of a non-scriptable application

I have opened 2 "Finder" window A & B, A is in the front while B underneath, the following snippet brings B to the front the topmost:
tell application "Finder"
activate
activate window 2
end tell
But for applications that do not support scripting, the code just mentioned won't help.
Any ideas for activating a window of non-scripting application.
You can usually turn to system events in these cases. System events knows about the windows of running processes and you can usually manipulate those windows. Something like this will show you some of the things you can do. Just play around with the code and see if you can do what you want.
tell application "System Events"
tell process "Whatever"
properties of windows
end tell
end tell
EDIT: One of the properties of a window is its "title". So you might be able to use that. This approach uses the fact that many applications have a "Window" menu and under that menu many times the name of the windows are listed and you can switch windows by clicking the approprite menu item. So something like this might work... my example uses TextEdit.
tell application "TextEdit" to activate
tell application "System Events"
tell process "TextEdit"
set windowTitle to title of window 2
click menu item windowTitle of menu 1 of menu bar item "Window" of menu bar 1
end tell
end tell
What is your definition of non-scriptable? Just about everything is scriptable to some degree, but for the sake of an example lets use, does not contain an AppleScript dictionary, e.g. AppName.sdef within its application bundle.
For example, the macOS included Stickies application does not contain the Stickies.sdef file, and when trying to add it to the Library in Script Editor is says, "Unable to add the item because it is not scriptable."
In a case such as this, then System Events is needed to talk to the application process, e.g.:
Example AppleScript code:
if running of application "Stickies" then
tell application "System Events"
tell application process "Stickies"
set frontmost to true
if exists window 2 then ¬
perform action "AXRaise" of window 2
end tell
end tell
end if
Notes:
I've included error handling in the example AppleScript code, which can be removed if you prefer.

Simple GUI scripting question

I am trying this simple GUI script to open a new window of Safari:
tell application "Safari"
activate
end tell
tell application "System Events"
tell process "Safari"
try
tell menu bar 1
tell menu bar item 3
click menu item 1
end tell
end tell
on error theError
display dialog ("An error occurred while performing requested action" & theError) buttons "OK" default button "OK"
end try
end tell
end tell
but it is giving this error message:
Expected end of line but found """
Can anyone suggest me where I may be wrong?
Thanks,
Miraaj
Wow, that was weird. Your script broke AppleScript Editor. After running your script and it not working... I tried to recompile the script and then the error you posted starting showing up. So somehow your code caused AppleScript editor to break and thus the error. I had to quit and relaunch AppleScript Editor to get it working again.
I used the application UI Browser and found the problem. Your reference to the menu item was wrong. There's an extra menu in there that we can't see... and you didn't reference that extra menu. This is the problem with gui scripting. And even if a gui script works it may break at some future date as an application is updated. As such avoid gui scripting if at all possible.
Anyway, here's what your code should look like...
tell application "Safari"
activate
end tell
tell application "System Events"
tell process "Safari"
try
tell menu bar 1
tell menu bar item 3
click menu item 1 of menu 1
end tell
end tell
on error theError
display dialog ("An error occurred while performing requested action " & theError) buttons "OK" default button "OK"
end try
end tell
end tell
EDIT:
As I mentioned in my comment below, if you can't find a native command from an application's dictionary, the next most reliable method is using keyboard shortcuts. Most menu items have them. For example, if I wanted to open a new tab in a window that menu item has the keyboard shortcut command-t. So we can use that like this. Note there is a native command to open a new tab without using keystrokes, I'm just showing this as an example.
tell application "Safari" to activate
tell application "System Events"
keystroke "t" using command down
end tell
end
Keyboard commands don't usually change between application updates whereas gui commands often do because programmers redesign their interface in updates... and when that happens gui scripting goes haywire. One of the gotcha's with both gui scripting and keystrokes is that sometimes the script goes too fast and these techniques can't keep up with the speed of the program, so they often error. When this happens you need to slow down the script using small delays to allow the interface to keep up with the script.

Resources