Bypass “Can't get window” error in AppleScript - applescript

I'm trying to make a bash script to close certain finder windows (I'm on MacOSX). Unfortunately, the script terminates as soon as the first window is found to not be open. (ex: No window titled "Communication" open, yet window "Editors" is open; No window is closed). If I open a window titled Communication, it does close, but nothing after the first command fails. I've tried exit and on error, and taking out "set -e", but nothing seems to be working. Here is my script:
#!/bin/bash
set -e
osascript <<EOF
tell application "Finder"
close window "Communication"
close window "Editors"
close window "Gaming"
close window "Music"
close window "Technical"
close window "Text Editors"
close window "Utilites"
close window "Camera"
close window "External"
close window "TAB Actual"
end tell
It gives me
error: 24:57: execution error: Finder got an error: Can't get window <"first window found to not be open">. (-1728) (1)
I don't know if this means anything, but the code is being run through Automator.
Thanks to anyone that can help me, and yes, I am very new to bash.

You can use the ignoring application responses statement, for example:
#!/bin/bash
set -e
osascript <<EOF
tell application "Finder"
ignoring application responses
close window "Communication"
close window "Editors"
# More windows here...
end ignoring
end tell
More details about control statements in the Applescript Language Guide: https://developer.apple.com/library/mac/documentation/AppleScript/Conceptual/AppleScriptLangGuide/reference/ASLR_control_statements.html

This is what try statements are for:
set windowNames to {"Communication", "Editors", "Gaming"}
tell application "Finder"
repeat with wName in windowNames
try
close window wName
end try
end repeat
end tell

Related

Show/hide Finder, and create new window if none exist via AppleScript

I'd like to create an AppleScript to trigger via key command in Keyboard Maestro that allows me to toggle showing or hiding the Finder window(s) directly. And if when toggling to show the Finder, if there are no existing windows, create one and open it up to my home directory.
The following AppleScript works. However, there seems to be a race condition between activating the finder and detecting if there are any open windows with if not (window 1 exists), hence the delay 0.5.
The problem (which I think is a race condition in detecting the presence of an existing Finder window) results in this script frequently creating new Finder windows when one already existed. The if not (window 1 exists) doesn't always get it right.
Any thoughts, tweaks, or affirmations that this is just the way it is would be appreciated!
tell application "System Events"
set activeApp to name of application processes whose frontmost is true
if ((activeApp as string) is equal to "Finder") then
set visible of process "Finder" to false
else
tell application "Finder"
activate
delay 0.5
if not (window 1 exists) then
make new Finder window
set thePath to POSIX file "/Users/jon"
set the target of the front Finder window to folder thePath
end if
end tell
end if
end tell
Please try this simpler syntax, it uses only Finder terminology
tell application "Finder"
if frontmost then
set visible of process "Finder" to false
else
if (count windows) is 0 then reveal home
activate
end if
end tell
Edit:
To run a Keyboard Maestro macro, open Keyboard Maestro Editor, select the macro and then select Copy as > Copy UUID from the Edit menu.
Then in AppleScript write
tell application "Keyboard Maestro Engine" to do script "<Script-UUID>"
replacing <Script-UUID> with the copied real UUID
Ultimately I needed to activate Finder before running the count windows command or I'd get inconsistent window counts. Sometimes it'd be 0 even when there was a window open already. This code is working well for me so far.
tell application "Finder"
if frontmost then
set visible of process "Finder" to false
else
activate
if (count windows) is 0 then
open home
tell application "Keyboard Maestro Engine" to do script "<Script-UUID>"
end if
end if
end tell

applescript: how to terminate an executing terminal

I'm trying to make an apple script to allow me to manage a cpp project automatically. And I used Jenkins too.
Basically, the cpp project is a kind of infinite loop, which will execute in a terminal. And I set Jenkins rebuild and execute it per 20 sec. In other words, my pc should do the tasks below:
1) rebuild the project;
2) execute the project;
3) wait for 20 sec;
4) close the terminal.
However, when I arrive at 4), a dialog will pop up: Do you want to close this window?
So I have to click the button "Close".
My question is: how to code in applescript to do the 4) automatically?
Here is my applescript:
tell application "Terminal"
do script "cd /Users/Shared/Jenkins/Home/workspace/test"
do script "make clean" in window 1
do script "make" in window 1
do script "./matrix.out" in window 1
delay 20
close window 1 # problem's here
end tell
However, when I arrive at 4), a dialog will pop up: Do you want to close this window? So I have to click the button "Close".
But you can do that using AppleScript too (via GUI scripting thru System Events), so nothing you've said is a problem so far.
tell application "Terminal" to activate
tell application "System Events"
tell application process "Terminal"
tell its window 1
tell its sheet 1
click button "Close"
end tell
end tell
end tell
end tell
I wonder if this might help:
Running process in background after closing terminal
The problem might be that what you're lastly running in the terminal is a process (matrix.out) that will get killed by closing the window, and you don't want that, right? So it may be that you need to alter the matrix.out script using the technique described (if possible) to keep it from doing that.
It may also be possible to solve your problem by making matrix.out executable (chmod it to executable or use Kilometre) and just "open it" using vanilla applescript.

How can I move a dialog window in Applescript?

I've been told that, technically, you can't move a dialog in AppleScript. Amazingly, the following code works.
I'm running a script for InDesign that creates a dialog box. Opening a new AppleScript Editor window and running this code will move the dialog box:
tell application "System Events"
tell application process "Adobe InDesign CS6"
set position of window 1 to {1000, 400}
end tell
end tell
The problem is: I can't figure out a way to incorporate this code directly into my original script -- it just doesn't work, no matter what I try or where I insert it into the code. I have to run it from AppleScript Editor
Any ideas?
Dialog boxes are usually blocking in the host application. You can certainly tell System Events to move a window, but Adobe InDesign itself is busy throwing up a blocking dialog box at the time, so it can't move its own dialog box.
If you want to get clever, you can fork off a process at the correct time and with the magically correct delays to move your dialog for you. This would be something like
do shell script "osascript -e 'delay 4' -e " & (quoted form of "tell application \"System Events\" to tell application process \"Adobe InDesign CS6\" to set position of window 1 to {1000, 400}") & " > /dev/null 2>&1 &"
Customize the delay as needed. This will be a magical value you that will have to figure out. Depending your needs, you might be able to put in a test to see if the dialog has disappeared before the script continues.
The bit at the end, > /dev/null 2>&1 &, tells bash to redirect stdout to /dev/null (junk it) and redirects stderr to stdout, then tells the whole command to run in the background. Without this entire chunk, this statement will block AppleScript from continuing until the shell script finishes executing.

Can I manipulate the location of a dialog displayed through osascript?

I've been playing around with various UNIX commands and came across this one to display a dialog:
osascript -e 'tell app "System Events" to display dialog "Hello World"'
I'd like to change the position of the dialog. For most commands, I can just use man command to figure out how to do something for that command. However, man osascript doesn't tell me how I can change the position of the dialog box. How can I modify the command to put the dialog in a different place?
First, to get help with applescript just open the AppleScript Editor application and look under the help menu. The applescript language guide is in there and other tools. Also under the file menu is "Open Dictionary" which will show you the specific commands for applications.
To see the information about display dialog, open the dictionary of StandardAdditions and use the search field to find the command.
To answer your question, no, you cannot specify the location of a "display dialog" window. There are no parameters in that command for positioning the window, as you'll see in the dictionary. In addition, no other commands will help you either because you can't issue other commands while the dialog window is open because the code pauses while the window is open waiting for a response from the dialog window (like when you press the OK button).
If you need to set the position of a window to display information to a user then you'll need to use some other dialog tool other than "display dialog". You could create your own window in cocoa or google for some alternatives like cocoaDialog, SKProgressBar, and Notification Center.
There is a round-about way to go about this, which may be useful in some scenarios. Try the following:
on displayMessage(msg)
tell application "Finder"
activate
set c to (count windows)
ignoring application responses
display dialog msg with icon note
end ignoring
end tell
tell application "System Events"
tell application process "Finder"
repeat until ((count windows) > c)
delay 0.2
end repeat
set position of window 1 to {0, 22}
end tell
end tell
end displayMessage
displayMessage("I'm over here!")
Credit for this little script goes to a post here.
In implimenting this myself, I found it was limited to whether or not the application that is being called (Finder, in the example) supports the count window command (or whether it has API support at all).
I realise I've dragged up a question from 2013. I am posting this answer here in case it is of use to the OP or, more likely, someone else with a similar question.

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