2

I have discovered a very strange bug with Services.

To witness this behavior, please do the following:

  • Make sure that Safari is in your Dock.

  • Open Automator. Create a new Service.

  • Set the service to receive "no input" in "any application."

  • Insert a "Run AppleScript" action.

  • Paste the following into the action:

    on run {input, parameters}
    
        delay 5
        display dialog "Hello"      
        tell application "Safari" to activate
    
        return input
    end run
    
  • Save the Service.

  • Close the Service.

  • Re-open the Service.

  • Automator should present you with a dialog asking, "Do you want to install the “ServiceName” service?" Click "Install."

  • When given the "Installation complete" dialog, click "Done."

Now, run the Service. To do this, click on the current-application title in the top-left corner of the screen (the second item in the menu bar). Then click on the Service title.

You will notice that Safari will immediately open (evidenced by the black dot underneath its logo in the Dock). Safari will open before the 5 second delay and before the "Hello" dialog is displayed.

Placing the activate statement in a subroutine does not fix the issue.

Can someone confirm that this is a bug? I am convinced that this is a bug with the Services feature because when you run the Service from within Automator (by clicking the "play" button in the top-right corner of the Automator window), the code runs correctly.

If this is a bug, does anyone have a workaround so that the application is not in fact opened before the previous code runs?


My Macbook Pro is running OS X El Capitan, 10.11.6.


The bug might be related to another piece of strange behavior that I noticed:

  • Quit out of Safari.app and Automator.app, if they are running.

  • Pull up the folder where the computer's Services are stored (/Users/Me/Library/Services/) in Finder.

  • Right-click the Service file and open the file with Automator.

You will notice that opening the .workflow file with Automator will activate Safari. It shouldn't do that.

  • I can replicate the issues you've described under OS X El Capitan 10.11.6. – user3439894 Feb 3 '17 at 4:04
  • Thanks for checking @user3439894! Can you think of any workarounds? – rubik's sphere Feb 3 '17 at 4:47
  • The only workaround I've found after testing several different scenarios is to wrap the Safari commands within a do shell script command, e.g. do shell script "osascript -e 'tell application \"Safari\" to activate'". Note that with osascript, multiple −e options may be given to build up a multi-line script. – user3439894 Feb 3 '17 at 5:38
  • That works great! If you post that as an answer, I'll accept it. Also, if you don't mind, can you expand on that final sentence a little bit? I don't really understand what it means. – rubik's sphere Feb 3 '17 at 19:44
  • I've noticed that merely compiling an AppleScript that contains tell application "Whatever" to ... will activate that app. That's probably the underlying cause. – BallpointBen Jul 18 '18 at 12:23
2

The only workaround I've found after testing several different scenarios is to wrap the Safari commands within a do shell script command, e.g. do shell script "osascript -e 'tell application \"Safari\" to activate'". Note that with osascript, multiple −e options may be given to build up a multi-line script.

From the manual page for osascript:

−e statement

Enter one line of a script. If −e is given, osascript will not look for a filename in the argument list. Multiple −e options may be given to build up a multi-line script. Because most scripts use characters that are special to many shell programs (e.g., AppleScript uses single and double quote marks, “(”, “)”, and “*”), the statement will have to be correctly quoted and escaped to get it past the shell intact.

Example AppleScript code:

tell application "Safari"
    activate
    make new document in front
    set URL of front document to "http://apple.stackexchange.com/questions/271133/services-bug-that-prematurely-activates-an-application"
end tell

An example of the AppleScript code above, written as a do shell script command using osascript with the -e option, as necessary.

do shell script "osascript -e 'tell application \"Safari\"' -e 'activate' -e 'make new document in front' -e 'set URL of front document to \"http://apple.stackexchange.com/questions/271133/services-bug-that-prematurely-activates-an-application\"' -e 'end tell'"

As you can see, each line of AppleScript code from the normal tell block statement is its own -e option, and as noted in the manual page for osascript with the -e option, escaping with a backslash has been done as necessary for the code to compile correctly before being run.

In other words, this turn the normal tell block statement and its included commands to a one-line do shell script command so as to circumvent the apparent bug in the use case scenario presented in the OP.

Note that you should be able to do similar with other applications triggered by the same bug, by substituting the appropriate application name (and commands) as needed.

  • 1
    Thanks for providing and explaining an example! I now understand the concept. – rubik's sphere Feb 4 '17 at 0:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .