AppleScript Broken After Security Update

I wrote the following script, a few years ago, with some help from some great folks, online. It worked great, until Mavericks. Under Mavericks, the script would no longer hide all of the applications. It would hide a few of them, but, not all of them, as it previously had done. In fact, it would hide different applications, each time that I ran the script. I installed Yosemite, and, this script behaved the same as it did, in Mavericks.

Recently, I installed the OS X security update, with a hitch. The next morning, I launched this script. It stopped at FaceTime, and, it displayed an error message. I dismissed the error message. Then, I launched the script, again. This time, it launched the remaining applications, and, the hiding behavior remained the same. i.e. unpredictable. Each morning, after my Mac restarts, I launch this script, and, I observe the same response. The script stops at FaceTime, I dismiss the error message, and, I relaunch the script.

I have examined the script, but, I can’t identify a reason for it to stop of FaceTime. Have I overlooked something?

tell application “Safari” to activate
tell application “Mail” to activate
tell application “Messages” to activate
tell application “FaceTime” to activate
tell application “Contacts” to activate
tell application “Calendar” to activate
tell application “Notes” to activate
tell application “Maps” to activate
tell application “TextEdit” to activate
tell application “Preview” to activate
tell application “Adobe Reader” to activate
tell application “Microsoft Word” to activate
tell application “Microsoft Excel” to activate
tell application “AlphaX” to activate
tell application “iTunes” to activate

tell application “Finder”
activate
set visible of every process whose visible is true and name is not “Finder” to false
end tell

tell application “Finder”
if the (count of windows) is not 0 then
set collapsed of every window to true
end if
end tell

Thank you for any and all assistance.

Kurt

Hi.

Have you tried using ‘run’ instead of ‘activate’? You shouldn’t need to hide the processes then.

tell application "Safari" to run
tell application "Mail" to run
tell application "Messages" to run
tell application "FaceTime" to run
tell application "Contacts" to run
tell application "Calendar" to run
tell application "Notes" to run
tell application "Maps" to run
tell application "TextEdit" to run
tell application "Preview" to run
tell application "Adobe Reader" to run
tell application "Microsoft Word" to run
tell application "Microsoft Excel" to run
tell application "AlphaX" to run
tell application "iTunes" to run

tell application "Finder"
	if ((count windows) > 0) then
		set collapsed of every window to true
	end if
end tell

Hello, Nigel.

Nice to hear from you, again.

I had omitted some code from my posting, for the sake of brevity. Perhaps, I should have supplied the entire file contents, in my original posting. Here is what I have:

tell application “Safari” to run
tell application “Mail” to run
tell application “Messages” to run
tell application “FaceTime” to run
tell application “Contacts” to run
tell application “Calendar” to run
tell application “Notes” to run
tell application “Maps” to run
tell application “TextEdit” to run
tell application “Preview” to run
tell application “Adobe Reader” to run
tell application “Microsoft Word” to run
tell application “Microsoft Excel” to run
tell application “AlphaX” to run
tell application “iTunes” to run

tell application “Finder”
set screen_resolution to bounds of window of desktop
set screen_width to item 3 of screen_resolution
set screen_height to item 4 of screen_resolution
end tell

try
tell application “Safari”
activate
set the bounds of the first window to {(screen_width * (1 - 0.6) / 2), 0, (screen_width * (1 + 0.6) / 2), screen_height}
end tell
end try

try
tell application “Mail”
activate
set the bounds of the first window to {(screen_width * (1 - 0.6) / 2), 0, (screen_width * (1 + 0.6) / 2), screen_height}
end tell
end try

try
tell application “Contacts”
activate
set the bounds of the first window to {(screen_width * (1 - 0.6) / 2), 20, (screen_width * (1 + 0.6) / 2), screen_height * 0.945}
end tell
end try

try
tell application “Calendar”
activate
set the bounds of the first window to {(screen_width * (1 - 0.9) / 2), 0, (screen_width * (1 + 0.9) / 2), screen_height}
end tell
end try

try
tell application “Maps”
activate
set the bounds of the first window to {(screen_width * (1 - 0.8) / 2), 0, (screen_width * (1 + 0.8) / 2), screen_height}
end tell
end try

(*tell application “Finder”
activate
set visible of every process whose visible is true and name is not “Finder” to false
end tell

tell application “Finder”
if the (count of windows) is not 0 then
set collapsed of every window to true
end if
end tell*)

(*tell application “Finder”
activate
end tell

tell application “System Events”
tell process “Finder”
tell menu bar 1
tell menu bar item “Finder”
tell menu “Finder”
click menu item “Hide Others”
end tell
end tell
end tell
end tell
end tell*)

(tell application “Finder”
if ((count windows) > 0) then
set collapsed of every window to true
end if
end tell
)

1: The run commands have accomplished what the activate commands wouldn’t. Thank you for your suggestion.

2: I added your code, after I set the size of Maps. Unfortunately, this did not work.

3: I tried using the original code, commented above. This did not work.

4: I tried using a different approach, using menu items, commented above. This didn’t work.

I’m at a bit of a loss.

Thank you.

Kurt

Hi Kurt.

This version works for me ” except that I don’t have either of the Microsoft applications or AlphaX. Basically, I’ve tried to limit the number of applications coming to the front and the number of times each does so.

tell application "Finder"
	set screen_resolution to bounds of window of desktop
	set screen_width to item 3 of screen_resolution
	set screen_height to item 4 of screen_resolution
end tell

try
	tell application "Safari"
		activate
		set the bounds of the first window to {(screen_width * (1 - 0.6) / 2), 0, (screen_width * (1 + 0.6) / 2), screen_height}
	end tell
end try

try
	tell application "Mail"
		activate
		set the bounds of the first window to {(screen_width * (1 - 0.6) / 2), 0, (screen_width * (1 + 0.6) / 2), screen_height}
	end tell
end try

tell application "Messages" to run
tell application "FaceTime" to run

try
	tell application "Contacts"
		activate
		set the bounds of the first window to {(screen_width * (1 - 0.6) / 2), 20, (screen_width * (1 + 0.6) / 2), screen_height * 0.945}
	end tell
end try

try
	tell application "Calendar"
		activate
		set the bounds of the first window to {(screen_width * (1 - 0.9) / 2), 0, (screen_width * (1 + 0.9) / 2), screen_height}
	end tell
end try

tell application "Notes" to run

try
	tell application "Maps"
		activate
		set the bounds of the first window to {(screen_width * (1 - 0.8) / 2), 0, (screen_width * (1 + 0.8) / 2), screen_height}
	end tell
end try

tell application "TextEdit" to run
tell application "Preview" to run
tell application "Adobe Reader" to run
tell application "Microsoft Word" to run
tell application "Microsoft Excel" to run
tell application "AlphaX" to run
tell application "iTunes" to run

tell application "Finder"
	activate
	if ((count windows) > 0) then
		set collapsed of every window to true
	end if
end tell

tell application "System Events"
	tell process "Finder"
		set frontmost to true
		tell menu bar 1
			tell menu bar item "Finder"
				tell menu "Finder"
					click menu item "Hide Others"
				end tell
			end tell
		end tell
	end tell
end tell

Since ‘window’ and ‘bounds’ are standard terms (in Apple applications which implement them, anyway), the code for dealing with applications whose window bounds need adjusting could be put into a single handler:

tell application "Finder"
	set screen_resolution to bounds of window of desktop
	set screen_width to item 3 of screen_resolution
	set screen_height to item 4 of screen_resolution
end tell

openAndSetWindowBounds("Safari", {(screen_width * (1 - 0.6) / 2), 0, (screen_width * (1 + 0.6) / 2), screen_height})
openAndSetWindowBounds("Mail", {(screen_width * (1 - 0.6) / 2), 0, (screen_width * (1 + 0.6) / 2), screen_height})

tell application "Messages" to run
tell application "FaceTime" to run

openAndSetWindowBounds("Contacts", {(screen_width * (1 - 0.6) / 2), 20, (screen_width * (1 + 0.6) / 2), screen_height * 0.945})
openAndSetWindowBounds("Calendar", {(screen_width * (1 - 0.9) / 2), 0, (screen_width * (1 + 0.9) / 2), screen_height})

tell application "Notes" to run

openAndSetWindowBounds("Maps", {(screen_width * (1 - 0.8) / 2), 0, (screen_width * (1 + 0.8) / 2), screen_height})

tell application "TextEdit" to run
tell application "Preview" to run
tell application "Adobe Reader" to run
tell application "Microsoft Word" to run
tell application "Microsoft Excel" to run
tell application "AlphaX" to run
tell application "iTunes" to run

tell application "Finder"
	activate
	if ((count windows) > 0) then
		set collapsed of every window to true
	end if
end tell

tell application "System Events"
	tell process "Finder"
		set frontmost to true
		tell menu bar 1
			tell menu bar item "Finder"
				tell menu "Finder"
					click menu item "Hide Others"
				end tell
			end tell
		end tell
	end tell
end tell

on openAndSetWindowBounds(appName, theBounds)
	try
		tell application appName
			activate
			set the bounds of the first window to theBounds
		end tell
	end try
end openAndSetWindowBounds

By the way, when posting AppleScript code here, could you please use the [applescript] and [/applescript] tags provided by this BBS? They make the code appear in a box as above with a clickable link which opens it in people’s default script editors.

Edit: Another thing which occurs to me, having noticed that your subject line says “. After Security Update”, is that you may need to enable the application running the script (the script itself if you’ve saved it as an applet) in System Preferences’s Security settings:

System Preferences → Security & Privacy → “Privacy” tab → “Accessibility”

Hello, Nigel.

This lengthy message describes my experiences, this far.

1: I had opened System Preferences, and, I solved the Accessibility problem. Thank you, just the same.

2: The use of “openAndSetWindowBounds” returns the error message “«script» doesn’t understand the “openAndSetWindowBounds” message.”

3: I have tried all of your code suggestions, including some variations of them. Unfortunately, every suggestion, and variation of them, leave windows visible on the screen. The results are not consistent, from test to test. That is to say, each test, with the same script, leaves different windows still visible on the screen. I cannot discern a pattern to this behavior.

I was especially baffled by these results when I used the code:


tell application "System Events"
	tell process "Finder"
		set frontmost to true
		tell menu bar 1
			tell menu bar item "Finder"
				tell menu "Finder"
					click menu item "Hide Others"
				end tell
			end tell
		end tell
	end tell
end tell

When I run a script that includes this code, various windows remain on the screen. Immediately, I click on Finder, and, I select Hide Others. This action hides all windows. The above code should be perform the same steps as Finder → Hide Others. Yet, it does not.

So, I created a new script. This script contains the above code, only. Each time that I run this new script, regardless of window visibility configuration, it hides all windows. Therefore, this code is not performing its function, when it resides inside the script after the run application commands and the set window size and position commands, but, it does perform its function, when it exists and runs autonomously of other code. Perhaps, this is timing related. I wondered if this code could be executing, too quickly, after the preceding run application and set window size and position code? I decided to test my hypothesis.

I added “delay 5”, before the code that I supplied, above. Sure enough, the script works properly. It launches my fifteen applications. It sets the window size and position for five of the applications. It hides all of the windows.

I tried the “delay 5” line in the following examples (after the launch application and set windows size and position commands). Here are the results:

The following code does not properly hide the windows, after launching the applications and setting the windows sizes and positions:


delay 5

tell application "Finder"
	activate
	set visible of every process whose visible is true and name is not "Finder" to false
end tell


tell application "Finder"
	if the (count of windows) is not 0 then
		set collapsed of every window to true
	end if
end tell

The following code does not properly hide the windows, after launching the applications and setting the windows sizes and positions:


delay 5

tell application "Finder"
	activate
	if ((count windows) > 0) then
		set collapsed of every window to true
	end if
end tell

The following code properly hides the windows, after launching the applications and setting the windows sizes and positions:


delay 5

tell application "Finder"
	activate
end tell

tell application "System Events"
	tell process "Finder"
		set frontmost to true
		tell menu bar 1
			tell menu bar item "Finder"
				tell menu "Finder"
					click menu item "Hide Others"
				end tell
			end tell
		end tell
	end tell
end tell

Using this third solution, I reduced the delay value to “3”, then, to “1”, then, to “0.5”, then, to “0.1”. The “0.1” and “0.5” delay values returned inconsistent results. So, I increased the delay value to “1”.

So far, the script works, almost, perfectly. Occasionally, Mail remains open. The working code, follows:


tell application "Finder"
	set screen_resolution to bounds of window of desktop
	set screen_width to item 3 of screen_resolution
	set screen_height to item 4 of screen_resolution
end tell

try
	tell application "Safari"
		activate
		set the bounds of the first window to {(screen_width * (1 - 0.6) / 2), 0, (screen_width * (1 + 0.6) / 2), screen_height}
	end tell
end try

try
	tell application "Mail"
		activate
		set the bounds of the first window to {(screen_width * (1 - 0.6) / 2), 0, (screen_width * (1 + 0.6) / 2), screen_height}
	end tell
end try

tell application "Messages" to activate
tell application "FaceTime" to activate

try
	tell application "Contacts"
		activate
		set the bounds of the first window to {(screen_width * (1 - 0.6) / 2), 20, (screen_width * (1 + 0.6) / 2), screen_height * 0.945}
	end tell
end try

try
	tell application "Calendar"
		activate
		set the bounds of the first window to {(screen_width * (1 - 0.9) / 2), 0, (screen_width * (1 + 0.9) / 2), screen_height}
	end tell
end try

tell application "Notes" to activate

try
	tell application "Maps"
		activate
		set the bounds of the first window to {(screen_width * (1 - 0.8) / 2), 0, (screen_width * (1 + 0.8) / 2), screen_height}
	end tell
end try

tell application "TextEdit" to activate
tell application "Preview" to activate
tell application "Adobe Reader" to activate
tell application "Microsoft Word" to activate
tell application "Microsoft Excel" to activate
tell application "AlphaX" to activate
tell application "iTunes" to activate

tell application "Safari" to activate
tell application "Mail" to activate
tell application "Messages" to activate
tell application "FaceTime" to activate
tell application "Contacts" to activate
tell application "Calendar" to activate
tell application "Notes" to activate
tell application "Maps" to activate
tell application "TextEdit" to activate
tell application "Preview" to activate
tell application "Adobe Reader" to activate
tell application "Microsoft Word" to activate
tell application "Microsoft Excel" to activate
tell application "AlphaX" to activate
tell application "iTunes" to activate

delay 1

tell application "Finder"
	activate
end tell

tell application "System Events"
	tell process "Finder"
		set frontmost to true
		tell menu bar 1
			tell menu bar item "Finder"
				tell menu "Finder"
					click menu item "Hide Others"
				end tell
			end tell
		end tell
	end tell
end tell

The run command prevented the above script from returning the desired results. The activate command solved that problem. I’m not certain of the reason. Furthermore, the repeated list of activate application commands, causes this script to work. Without them, the script returns inconsistent results, vis-a-vis visible windows on the screen.

I would welcome your thoughts on both my observations and my code.

Thank you.

Kurt

Hello, Nigel.

I added some code to set the window size and position for other applications, to my script. All of them work, as I expect, except for Messages, FaceTime, and, iTunes.


try
	tell application "Messages"
		activate
		set the bounds of the first window to {(screen_width * (1 - 0.2) / 2), (screen_height * (1 - 0.8) / 2), (screen_width * (1 + 0.2) / 2), (screen_height * (1 + 0.8) / 2)}
	end tell
end try

try
	tell application "FaceTime"
		activate
		set the bounds of the first window to {(screen_width * (1 - 0.5) / 2), 0, (screen_width * (1 + 0.5) / 2), screen_height}
	end tell
end try

try
	tell application "iTunes"
		activate
		set the bounds of the front window to {(screen_width * (1 - 0.7) / 2), 0, (screen_width * (1 + 0.7) / 2), (screen_height * (1 + 0.85) / 2)}
	end tell
end try


Unlike my code to set the window size and position for other applications, this code either does not work, or, it misbehaves. For example, the Messages code offsets the window to the right, instead of centering it on the screen. The FaceTime code does not work. The iTunes code requires the “(screen_height * (1 + 0.85) / 2)” command in order to make the window fit the screen in the vertical axis. The command “screen_height” does not work, as it does for other applications. This is a long standing problem, that goes back several iTunes versions.

Are you familiar with these issues? Can you suggest solutions? I don’t want to resize my FaceTime window to larger dimensions, every time that I want to use it.

Thank you.

Kurt

Hi Kurt.

That should only happen if the handler’s omitted from the script.

Putting a delay before hiding the processes probably gives all the applications time to complete their activation procedures first.

The Finder only handles processes as a legacy function. You should use System Events for processes now.

Setting a process’s ‘visible’ to false should hide it and its windows. The ‘collapsed’ part of the above code only affects windows belonging to the Finder and it collapses them into the Dock rather than hiding them as such.

I’ve no idea why that should be. I used ‘run’ to solve the problems caused by all the ‘activate’ commands in the original script ” which it did on my machine! :slight_smile:

Messages’s sign-in window isn’t resizable, so your code’s putting the top-left corner where specified but the other two co-ordinates are being ignored.

FaceTime isn’t scriptable.

‘screen_height’ does work on my machine, placing the bottom of the iTunes window on the bottom of the screen. You don’t say what “does not work” means, but I notice that your position for the top of the window is 0, so that its top 22 rows of pixels are hidden under the menu bar. See if you like these coordinates any better:

try
	tell application "iTunes"
		activate
		set the bounds of the front window to {(screen_width * (1 - 0.7) / 2), 23, (screen_width * (1 + 0.7) / 2), screen_height}
	end tell
end try

Hello, Nigel.

Thank you for the information.

I don’t know what this means: “That should only happen if the handler’s omitted from the script.”

Thank you for clarifying Message’s and FaceTime’s scripting limitations. Perhaps, Apple will add scripting, to them.

I used a poor choice of words, regarding iTunes. As you said, screen_height places the bottom of the iTunes window at the bottom of the screen, not, at the top of the Dock, as it does for my other applications. I’ll try your idea, later today. My code positions the top of the iTunes window at the bottom of the menubar

I discovered a very peculiar problem, last night and this morning. Once I established a code base, that served my needs, I created an application, and, I tested it. It worked well, as does running the code from the open script file. I copied the AppleScript file and the application file to my other Mac (Mac 2). I tested them. The script would stop at Contacts, and, display a message that contained error code -10661. I researched this error code. I found http://applehelpwriter.com/category/address-book/. I performed these steps, on both Macs (I attempt to maintain both Macs in as close to an identical configuration, OS-wise and application-wise, as I can). Problem solved. I performed several “restart, launch script” sequences. It worked without a hitch, every time.

This morning, I ran the script application, on Mac 1. It skipped Contacts, and, it performed the remainder of the script functions, despite having performed properly, through multiple “restart, launch script” tests, on Mac 1, last night. This morning, I ran the script application, on Mac 2. It returned identical results, as Mac 1. I observed the following on both Macs. With no applications running, I run my script, either from inside the script, or, from the script application. It launches all applications, except for Contacts, and, it positions and sizes the proper windows, and, it hides all windows. Also, it displays an error message. (An error of type -10661 has occurred. An error of type -10661 has occurred. (-10661)) The script application icon bounces in the dock, until I dismiss the error message. However, if all applications are running, including Contacts, and then, I run the script, either from inside the script, or, from the script application, it runs to completion, and then, it quits. If I dismiss the error message, and, I DON’T launch Contacts, and then, I run the script again, then, it displays the error message, and, the script icon bounces in the dock.

In summary, the script ran properly on Mac 1, last night. It stumbled on Contacts, on Mac 2, last night. I resolved the problem, and, it ran properly on both Macs. This morning, it stumbles on Contacts, on both Macs.

Are you familiar with this problem?

Regards,

Kurt

Hello, Nigel.

Have you had an opportunity to look at my posting concerning the Contacts not launching from script, problem?

Kurt

I’ve no idea what’s causing the trouble, Kurt. It’ll be some peculiarity on your computer(s) rather than anything to do with the script.

It’s possible one of these two methods may sidestep the problem, but they won’t actually cure it.


set ContactsPath to (path to applications folder as text) & "Contacts.app" -- Assuming Contacts is in the main Applications folder.

tell application ContactsPath
	activate
	set the bounds of the first window to {(screen_width * (1 - 0.6) / 2), 20, (screen_width * (1 + 0.6) / 2), screen_height * 0.945}
end tell

Or:


set ContactsPath to (path to applications folder as text) & "Contacts.app" -- Assuming Contacts is in the main Applications folder.

tell application "System Events" to open file package ContactsPath

tell application "Contacts" to set the bounds of the first window to {(screen_width * (1 - 0.6) / 2), 20, (screen_width * (1 + 0.6) / 2), screen_height * 0.945}

For an applet to script Calendar or Contacts, it needs permission in System Preferences → Security & Privacy → Privacy. Once you give an app permission, its code should not change. If you edit it, or the act of running it modifies it (which usually happens because top-level variables and properties are stored between runs), the permission can be lost and needs to be set again. Once you get the script working, try locking it, or removing the write permission of the actual Main.scpt file inside the app.

Hello, Nigel.

As I alluded, in my message, I suspect that the problem lies in OS X, not in your script. I was hoping that you might be familiar with this problem, which apparently, others have encountered, in the past. The procedures that I discovered in the website, who’s URL I provided in my previous posting, were a few years old. Did you have a chance to review them?

Hello, Shane.

Nigel and I had discussed your concern, previously. In fact, I addressed it before Nigel brought it to my attention. But, thank you, nevertheless.

Kurt

I did look at the article, which was written with Mavericks in mind but may also apply to Yosemite. I tried the ‘locate lsregister’ command in terminal and got the message about the database not existing:

But I didn’t go any further with it, since I do have a file at /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister (apparently the reply I’d get if the database did exist) and I don’t have any problem activating Contacts by script.

Hi Shane.

I think that’s to do with accessing the actual contacts and calendars rather than scripting the applications to activate and resize their windows.

You’re probably right.