AppleScript - AppleEvent handler failed - applescript

I've got a script than on login, ask a user if they want to watch a movie. For the most part it works great. However on occasion and for reasons unknown to me I get an AppleEvent handler failed error. I've read other post on this error but they all seem to be unique. So, if possible can someone please take a look at my script and tell me why this occasionally pops up and if there's anything i can do to prevent it?
One thing that might help to know, is the one thing in the script that fails when this error occurs is the movie doesn't play. It opens in quicktime but doesn't start.
Thanks in advance, here's the script.
tell application "Welcome" to activate
set question to display dialog "Would you like a welcome video?" buttons {"No, I've seen it", "Yes, please"} default button 2
set answer to button returned of question
if answer is equal to "Yes, please" then tell application "QuickTime Player"
set theMovie to "Macintosh HD:Library:Desktop Pictures:Mac ML Opening Chalkbaord Video.mov"
set openMovie to open theMovie
present openMovie
play openMovie
delay 30
quit
end tell
if answer is equal to "No, I've seen it" then tell application "Welcome"
quit
tell application "System Events"
delete login item "Welcome"
end tell
end tell

My guess is that you probably need a delay between opening and playing the movie. Sometimes the code runs faster than the computer can react. If that's the case then the movie may still be trying to open when the code tells the movie to play... thus the error. As such I added 2 repeat loops which checks for things to make sure they're available before proceeding to the next step in the code. You also need "open file" in the code instead of just "open".
Your approach in your if statements of telling an application to do something is unusual. I wouldn't do that. I would also combine your if statements into one if/else if statement. Anyway, here's how I would write your code (I'm assuming application "Welcome" is the code itself). I hope this helps!
set theMovie to "Macintosh HD:Library:Desktop Pictures:Mac ML Opening Chalkbaord Video.mov"
tell me to activate
set question to display dialog "Would you like a welcome video?" buttons {"No, I've seen it", "Yes, please"} default button 2
set answer to button returned of question
if answer is equal to "Yes, please" then
tell application "QuickTime Player"
activate
set openMovie to open file theMovie
-- delay until the movie opens
set startTime to current date
repeat until exists document 1
delay 0.2
if (current date) - startTime is greater than 10 then return -- a precaution so you don't get stuck in the repeat loop forever
end repeat
present openMovie
play openMovie
-- delay until the movie stops playing
repeat until document 1 is not playing
delay 1
end repeat
quit
end tell
else if answer is equal to "No, I've seen it" then
tell application "System Events" to delete login item "Welcome"
end if

Related

How to fix "original file could not be found" error via apple script

I have an issue with my music library.
Some songs I am unable to play because they cannot be found locally.
Here's an example of the error messages I get when playing a specific song:
The song ... could not be used because the original file could not be found. Would you like to locate it?
I can simply press Cancel and the song will be matched via the Apple Music Service.
This allows me to then play the song.
This issue has been discussed here, albeit not in an automated way. Hence, I would like to find an automated solution.
For this, I took the approach of looping through my library by playing each song.
By default, if a song cannot be found, the script automatically skips to the next song.
However, I would like the script to deal with the "file not found" errors and press Cancel.
My current attempt unfortunately does not work:
-- Play first song in library (turn off shuffle and repeat)
set i to 4000 --number of songs in library
repeat while i > 0
tell application "Music" to play (next track)
tell application "System Events"
key code 53
end tell
set i to i - 1
end repeat
How can I force the script to deal with these pop-up errors?
Note: I am also open to any other, more efficient solution to my problem if you have any suggestions. I decided not to go for the Locate option because it takes more time and I will delete any unreferenced songs from my disk at a later stage anyways.
UPDATED VERSION. Following script doesn't play tracks and programatically clicks button "Cancel" when track is corrupted. Like described by OP fixing tracks manually workflow:
tell application "Music"
activate -- required
tell source "Library"
repeat with nextTrack in tracks
try
with timeout of 2 seconds
set theResult to play (contents of nextTrack)
end timeout
theResult
on error
delay 1
tell application "System Events" to tell process "Music" to tell window 1 to if UI element "Cancel" exists then click UI element "Cancel"
end try
stop
end repeat
end tell
end tell

Open/search Spotify track in Apple Music (with Applescript)

I'd like an easy way to switch from a Spotify release to the same release in Apple Music.
I already found a way to search for the currently playing Spotify track in the Apple Music web player with Applescript:
tell application "Spotify"
if player state is not stopped then
set currentArtist to artist of current track as string
set currentTrack to name of current track as string
open location "https://music.apple.com/search?term=" & currentArtist & " " & currentTrack
end if
end tell
I'd love to:
Open the search in the native Music.app, not the web player. Is this supported?
Ideally not do a search, but go straight to the same release. Maybe with ISRC codes?
Take any selected Spotify track, not just the currently playing one. Looking at the Spotify Applescript dictionary tells me this in not possible.
had a similar problem right now and quickly hacked it out. In my case I want to simply trigger a search on the Music app.
Opened Automator and created a new "Service".
Workflow receives current > "Text" > in "every application".
Here's the AppleScript:
on run {input, parameters}
tell application "Music"
activate
end tell
tell application "System Events"
tell process "Music"
set window_name to name of front window
set value of text field 1 of UI element 1 of row 1 of outline 1 of splitter group 1 of window window_name to input
keystroke ""
key code 36
end tell
end tell
return input
end run
I saved it as "Find on Music" in Automator and now I can select text, right click > Service > Find on Music and Music plops open and shows me the results for the selected text. I hope you can use some parts of it.
I just figured out how to pass text from wherever to the search field in Music, with help from daemon's answer, which no longer works. This should work for what you want to do in conjunction with what you have.
Replace your "open location" line with a variable name for your concatenated string. Add this code below yours and pass that variable in place of 'input' (in my case 'input' is text from any application, which I use to select text of an artist name in an email/webpage/message that I want to send to Music's search).
First it checks to see if the main Music window is open vs the MiniPlayer, and open it if not to enable search via cmd-O, the cmd-F to find, then passes the input and hits return:
tell application "Music"
activate
end tell
tell application "System Events"
if not (exists (window "Music" of process "Music")) then
tell process "Music"
keystroke "0" using command down
end tell
end if
tell process "Music"
keystroke "f" using command down
keystroke input
key code 36
end tell
end tell
So, something like this (I don't have Spotify to check that section, but this should work assuming your code there is correct):
tell application "Spotify"
if player state is not stopped then
set currentArtist to artist of current track as string
set currentTrack to name of current track as string
set spotTrack to currentArtist & " " & currentTrack
end if
end tell
tell application "Music"
activate
end tell
tell application "System Events"
if not (exists (window "Music" of process "Music")) then
tell process "Music"
keystroke "0" using command down
end tell
end if
tell process "Music"
keystroke "f" using command down
keystroke spotTrack
key code 36
end tell
end tell
The only thing I couldn't figure out is how to check if the search field is already in focus, because if it is, the cmd-F causes a system alert sound. Generally not an issue as typically you'll search and interact with something else before running this script again, so calling it good. :)

Applescript: Photoshop: How to find out whether the image is really open

We have an automation tool for Photoshop, using a control app, which calls Applescripts controlling Photoshop.
One situation is that we must open a RAW image in the CameraRAW plug-in, and then open it in Photoshop. This part is handled, via an applet using System Events. When that applet terminates, we run the processing script for Photoshop.
As some pictures take quite a bit of time to open, we have to make sure that the picture is really open before the script can run. … and that's where I am stuck.
At the moment, I am using the following code which is intended to wait until the image is open (the criterion for "open" is correct (and tested manually), so that's not the issue here).
tell application "Adobe Photoshop CC 2015"
activate
tell application "System Events"
tell application process "Photoshop CC"
--
display alert "Waiting for Window"
--
repeat
try
set wn to name of window 1 as text
try
if (wn contains "(RGB/16") then
set wn to "image is open: " & wn
end if
end try
if (wn contains "(RGB/16") then
display alert "We are there, quitting now… " & wn
exit repeat
end if
end try
delay 1
end repeat
end tell
end tell
--
display alert "Ready for process"
--
-- and here comes the processing code
end tell
I also tried to set a variable which is tested as argument for repeat, and changed when the exit condition is fulfilled.
Trying to create even alerts within the repeat loop, does not lead to any effect; the script ends up in an infinite loop.
It is well possible that I miss the obvious… So, I am grateful for any helpful hint.
Thanks in advance.
I think you have a few small issues with your script that are causing your problem.
You are using name of window 1 when I believe you need name of document 1. With your first try block structured as it was you weren't realizing it was actually giving an error on name of window 1
The name that is returned doesn't contain the color space and bit count, so I've changed the result test to an empty string
Notice the modifications to the try block around getting the document name
I don't believe it's necessary or see a reason to use "System Events" in this case, so I've modified the version below without it.
Example Script
tell application "Adobe Photoshop CC 2015"
display alert "Waiting for Window"
repeat
try
set wn to name of document 1 as text
on error
set wn to ""
end try
try
if wn is not equal to "" then
set wn to "image is open: " & wn
end if
end try
if wn is not equal to "" then
display alert "We are there, quitting now… " & wn
exit repeat
end if
delay 1
end repeat
display alert "Ready for process"
end tell

Applescript to check App Store

Thanks for taking the time to read my question.
It's pretty simple, but i am a complete noobie to this, so am having some trouble.
Is it possible to have an applescript that will check the mac app store for updates, and if there are, output the number of updates to someplace?
A good example of this is (if you are aware of it) the geeklets that check for unread mail, and then outputs it to the desktop.
EDIT:
I downloaded a geeklet for the unread mail (as referenced above), and using that as a starting point, I tried to write my own script.
set run_bool to 1
tell application "System Events"
set run_bool to count (every process whose name is "App Store")
end tell
if run_bool is 1 then
tell application "App Store"
set update_count to 0
set output_string to ""
repeat with upd in Apps in Updates
if upd's download is not true then
set update_count to update_count + 1
end if
end repeat
if update_count is 0 then
set output_string to "zero"
else if update_count is 1 then
set output_string to "one"
else
set output_string to "two"
end if
end tell
else
set output_string to "not running"
end if
return output_string
now this is not my final code, but simply to check to see if it will work and what the output would be.
On compilation I get an error saying
error "The variable Updates is not defined." number -2753 from "Updates"
as well as
Syntax Error
Expected end of line but found unknown token
Also, when I stopped compilation, this appeared below the last line in my code
tell application "GeekTool Helper"
activate
«event ascrgsdf»
Any help is appreciated.
#foo is pretty right on with his idea. This code only requires one line. In the second line, I used display notification, but you substitute it with you preferred method to pass on the value.
tell application "System Events" to tell (first application process whose ¬
frontmost is true) to set returnValue to title of ((first menu item whose title ¬
begins with "App Store") of menu "Apple" of menu bar 1)
display notification returnValue
Result:
"App Store…, 1 update"
menu bar items are accessible everywhere (e.g. windowed/numeral desktop mode, fullscreen mode, dock hidden/disabled).
Make sure accessibility is enabled for Script Editor, or whichever app you use to invoke the script, to gain access to the UI.
There is just one weird thing: if I had used begins with "App Store..." instead of begins with "App Store", the code would be a dud. I don't know why - it might has to do with escaped characters and the .... Anyone who knows please enlighten me with a comment.
As for your code, I can tell from AppleScript Dictionary that Updates is not a property of App Store.app. Nor is any other categories in the UI. To get to the Dictionary, open Script Editor and press CMD+SHIFT+O
In addition, if you want to use return statement, you need an explicit handler. In other words, you need to wrap the code between on run and end run.

Applescript for controlling iTunes and Rdio

I have an Applescript I use in conjunction with Alfred that plays or pauses the current track in iTunes or Rdio, depending on which I have open. In my script Rdio takes precedence because I always have iTunes open and only open Rdio when I need it for a specific purpose.
Often, when a track is playing in iTunes and I hit my global shortcut to run this script it takes up to 15 seconds to stop the track. I wanted to share the script here and see if there might be a glaring issue, or if there is a much simpler, more efficient way to handle it.
I appreciate any help I can get!
tell application "System Events"
if (name of processes) contains "iTunes" then
set iTunesRunning to true
else
set iTunesRunning to false
end if
if (name of processes) contains "Rdio" then
set RdioRunning to true
else
set RdioRunning to false
end if
end tell
if RdioRunning then
tell application "Rdio"
if player state is paused or player state is stopped then
play
else if player state is playing then
pause
end if
end tell
else if iTunesRunning then
tell application "iTunes"
if player state is paused or player state is stopped then
play
else if player state is playing then
pause
end if
end tell
end if
It's difficult to track down such issues. In general your script looks fine. Here's some ideas that may help with your problem though.
In general applescripts are interpreted at run-time which means that every time you run your script the byte-code has to be changed into machine language code by another program (applescript runner)... this is normally not a problem but in your case maybe it's causing some slowness. So the idea is to write your script so that doesn't need to happen. We can do that by saving the script as an applescript application because applications are saved in the machine language form and thus do not require another program to execute the code. In addition we can take advantage that the commands for both applications are identical, so we can use a "using terms from" block. In your code you query system events for the "name of processes" twice, so the last optimization we can make is to only do that once.
So try this and see if it helps. I'm not certain it will but it's worth a try. Remember to save it as an application.
tell application "System Events" to set pNames to name of application processes
if "Rdio" is in pNames then
set appName to "Rdio"
else if "iTunes" is in pNames then
set appName to "iTunes"
else
return
end if
using terms from application "iTunes"
tell application appName
if player state is paused or player state is stopped then
play
else if player state is playing then
pause
end if
end tell
end using terms from
EDIT: If the above code doesn't work then try this. As mentioned, try it as an application and see if it helps. The same principles apply... one less query of system events and saving as an application to prevent needing to interpret the code.
tell application "System Events" to set pNames to name of application processes
if "Rdio" is in pNames then
tell application "Rdio"
if player state is paused or player state is stopped then
play
else if player state is playing then
pause
end if
end tell
else if "iTunes" is in pNames then
tell application "iTunes"
if player state is paused or player state is stopped then
play
else if player state is playing then
pause
end if
end tell
end if

Resources