¿Applescript se ejecuta desde la barra de menú?

Soy consciente del menú del editor de secuencias de comandos. Eso no es lo que estoy buscando.

¿Hay alguna manera de ejecutar un Applescript desde la barra de menú? Puedo guardarlo como un archivo y ejecutarlo desde el menú del Editor de secuencias de comandos, y puedo guardarlo como una aplicación y pegarlo en mi base. ¿Existe algún formato de archivo que permita ejecutarlo desde la barra de menús, como hacen muchas aplicaciones? ¿O una forma de editar el código que hace lo mismo?

Respuestas (4)

Cocoa-AppleScript como secuencia de comandos o aplicación AppleScript creada en el Editor de secuencias de comandos es compatible con la aplicación Barra de menús. Este script se ejecuta en macOS 10.12 (tal vez se ejecuta en 10.10.x, 10.11.x). Este script se puede guardar como aplicación.

--AppleScript: menu bar script -- Created 2017-03-03 by Takaaki Naganoya
--2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
--http://piyocast.com/as/archives/4502

property aStatusItem : missing value

on run
    init() of me
end run

on init()
    set aList to {"Piyomaru", "Software", "", "Takaaki", "Naganoya", "", "Quit"}
    set aStatusItem to current application's NSStatusBar's systemStatusBar()'s statusItemWithLength:(current application's NSVariableStatusItemLength)

    aStatusItem's setTitle:"🚗"
    aStatusItem's setHighlightMode:true
    aStatusItem's setMenu:(createMenu(aList) of me)
end init

on createMenu(aList)
    set aMenu to current application's NSMenu's alloc()'s init()
    set aCount to 1
    repeat with i in aList
        set j to contents of i
        if j is not equal to "" then
            set aMenuItem to (current application's NSMenuItem's alloc()'s initWithTitle:j action:"actionHandler:" keyEquivalent:"")
        else
            set aMenuItem to (current application's NSMenuItem's separatorItem())
        end if
        (aMenuItem's setTarget:me)
        (aMenuItem's setTag:aCount)
        (aMenu's addItem:aMenuItem)
        if j is not equal to "" then
            set aCount to aCount + 1
        end if
    end repeat

    return aMenu
end createMenu

on actionHandler:sender
    set aTag to tag of sender as integer
    set aTitle to title of sender as string

    if aTitle is not equal to "Quit" then
        display dialog aTag as string
    else
        current application's NSStatusBar's systemStatusBar()'s removeStatusItem:aStatusItem
    end if
end actionHandler:

Previamente edité el código original , publicado por Piyomaru, justo hasta el punto en que compilaría y quería agregar información adicional para hacer que el código de ejemplo sea más útil para cualquiera que sea relativamente nuevo en AppleScript.

Actualmente, en el código de ejemplo , si se guarda como una aplicación , no tiene ningún código para salir de la aplicación , solo elimina el objeto de la barra de menú. Entonces, en el actionHandler controlador del script , agregue lo siguiente a la else rama de la if declaración , después del código existente :

        if (name of current application) is not "Script Editor" then
            tell current application to quit
        end if

Está codificado, por lo que si se ejecuta desde el Editor de secuencias de comandos, no intentará cerrar el Editor de secuencias de comandos. Puede usarlo sin el bloque de if instruccionestell current application to quit y usarlo solo si no va a ejecutarlo desde el Editor de scripts.

Debido a que esta secuencia de comandos utiliza Cocoa-AppleScript, una vez que se ejecuta desde el Editor de secuencias de comandos, debe volver a compilarse justo antes de guardarla para eliminar los punteros C y Objective-C creados por el código Cocoa-Applescript , ya que los punteros no se pueden guardar en la secuencia de comandos. Simplemente haga clic en el ícono del martillo en la barra de herramientas, o: Editor de secuencias de comandos > Script > Compilar ⌘K

Además, cuando se guarda como una aplicación , debe marcar la casilla de verificación Permanecer abierto después de ejecutar el controlador al guardarla y, de forma predeterminada, el mosaico del Dock de la aplicación se mostrará en el Dock cuando se ejecute. Como esto podría ser un comportamiento no deseado para una aplicación de la barra de menús, use el siguiente comando en la Terminal para agregar la clave necesaria al archivo Info.plist de la aplicación para que no se muestre en el Dock.

defaults write /Applications/name_of_app.app/Contents/Info.plist LSUIElement -bool yes
  • Reemplácelo name_of_appcon el nombre real con el que lo guardó y, si es necesario, cambie la ruta si no está en /Applications.
  • Tenga en cuenta que si arrastra la aplicación al Dock, su Dock Tile aún se mostrará en el Dock, solo que no tendrá un indicador abierto debajo cuando esté abierto. Esta clave agregada al archivo Info.plist es para evitar que el Dock Tile se muestre en el Dock cuando se ejecuta, cuando la aplicación no se ha arrastrado al Dock en primer lugar.

En el actionHandler controlador del código de ejemplo original , solo muestra un cuadro de diálogo con el número de elemento del menú en el que se hizo clic, lo que sin duda está bien para el código de ejemplo , sin embargo, me gustaría mostrar un ejemplo diferente de cómo ejecutar un código separado basado en en qué elemento del menú se hizo clic. El siguiente código de ejemplo podría reemplazar todo el actionHandler controlador en el script original :

on actionHandler:sender
    set aTitle to title of sender as string
    if aTitle is equal to "Quit" then
        current application's NSStatusBar's systemStatusBar()'s removeStatusItem:aStatusItem
        if (name of current application) is not "Script Editor" then
            tell current application to quit
        end if
    else if aTitle is equal to "Piyomaru" then

        --  # Your code to run for this menu choice goes here:

    else if aTitle is equal to "Software" then

        --  # Your code to run for this menu choice goes here:

    else if aTitle is equal to "Takaaki" then

        --  # Your code to run for this menu choice goes here:

    else if aTitle is equal to "Naganoya" then

        --  # Your code to run for this menu choice goes here:

    end if
end actionHandler:

Ahora, esto podría escribirse de manera diferente, es decir, "Salir" como elseo else ifen la parte inferior, pero lo hice de esta manera porque quiero que todos los demás comandos de menú sean una else ifopción, aunque lógicamente es más probable que se haga clic en cualquier otro comando de menú dado. luego "Salir". Para mí, creo que es más fácil agregar/editar/eliminar el código del comando de menú cuando se escribe de esta manera. Es solo una preferencia personal, así que hágalo cuando sienta que es lo correcto para usted.

Una nota de discusión de la Guía del lenguaje AppleScript:

Una declaración if puede contener cualquier número de cláusulas else if ; AppleScript busca la primera expresión booleana contenida en una cláusula if o else if que sea verdadera , ejecuta las sentencias contenidas en su bloque (las sentencias entre un else if y la siguiente cláusula else if o else ), y luego sale de la sentencia if .

Una declaración if también puede incluir una cláusula else final. Las sentencias en su bloque se ejecutan si no pasa ninguna otra prueba en la sentencia if .

Para la mayor parte del código de ejemplo original, solo debería tener que modificar dos líneas de código en el init controlador :

set aList to {"Piyomaru", "Software", "", "Takaaki", "Naganoya", "", "Quit"}
  • Esto establece el nombre de los comandos de menú en su orden y ""es para un separador.

Para un icono diferente:

aStatusItem's setTitle:"🚗"
  • Cambie el "🚗" a algo más que prefiera, desde: Editor de secuencias de comandos> Editar> Emoji y símbolos

Con suerte, es obvio que el ifbloque de declaraciones en el actionHandler controlador se corresponderá con aListel init controlador , así que haga coincidir los nombres en aTitle is equal toel actionHandler controlador con los nombres en aListel init controlador .

El resto del código no debería necesitar ser modificado, aunque ciertamente puede serlo si es necesario o si se desea.

Edité su respuesta porque, tal como está escrito, no se compilaría, debería hacerlo ahora. Además, este script usa Cocoa-AppleScript, no solo AppleScript normal o estándar. +1 sin embargo.
No puedo guardarlo, ya sea como script o como aplicación. He realizado el paso de compilación, pero sigo recibiendo: El documento "xxx" no se pudo guardar automáticamente. Los punteros C y Objective-C no se pueden guardar en scripts. ¿Qué estoy haciendo mal?
El archivo de documento AppleScript no puede guardar punteros C y Objective-C en él. Entonces, debe editar AppleScript (por ejemplo, agregar líneas en blanco o eliminar líneas en blanco), luego puede guardarlo. Es una operación normal para el editor de scripts original de Apple.
Mi publicación está demasiado editada por otros moderadores sin conocimiento sobre el último AppleScript. La versión actual contiene muchos malentendidos y no es correcta. Entonces, mostraré los enlaces a mis artículos en mi blog. Funciona. piyocast.com/as/archives/996 piyocast.com/as/archives/1700 piyocast.com/as/archives/1851

AppleScript normal como secuencia de comandos o aplicación AppleScript creada en el Editor de secuencias de comandos no es compatible como aplicación de la barra de menús. Tendría que usar Cocoa-AppleScript o crear una aplicación en Xcode (o usar un iniciador de terceros) si no desea usar el menú Script en la barra de menú.

Aquí hay una aplicación de ejemplo hecha en Xcode usando Swift: WeatherBar .

Una aplicación confiable desde hace mucho tiempo que hace esto es FastScripts , y aunque se parece al menú Scripts, ofrece funcionalidad adicional. Puede ejecutarse como una aplicación gratuita, hasta 10 atajos de teclado o actualizarse por $9.95 para desbloquear atajos de teclado ilimitados.

No tengo afiliación con Red Sweater Software, LLC, excepto como usuario de FastScripts como aplicación gratuita.

FastScripts es bueno porque le permite asignar atajos de teclado para los elementos de su menú. El "menú del Editor de secuencias de comandos" de Apple dejó de permitirle asignar accesos directos a sus elementos de menú hace años y años,

Dependiendo de lo que quiera hacer exactamente con su secuencia de comandos de Apple, tal vez xbar / swiftbar podría ser adecuado para su propósito.

En general, estas aplicaciones le permiten mostrar el resultado de una variedad de secuencias de comandos en la barra de menú; muchas secuencias de comandos ya están disponibles, pero también puede escribir las suyas propias.

También se pueden utilizar para ejecutar applescripts. Los uso, por ejemplo, para ejecutar un applescriptguardado como servicellamándolo a través de un pequeño script bash:

#!/bin/bash
echo "blub"
echo "---"
echo "1 | bash=/Users/username/Library/Services/Space_1 terminal=false"

Hay un menú de "Servicios" poco utilizado (en el menú bajo el nombre de la aplicación) y puede guardar scripts como servicios y ponerlos a disposición en el menú de servicios para una aplicación específica.

También existe el concepto de aplicaciones que son "conectables", estas aplicaciones le permiten agregar scripts a los comandos del menú de la aplicación. Pero las aplicaciones que se pueden adjuntar parecen raras.

¿Algo de eso se ajusta a lo que buscas?

No. Estoy buscando una aplicación que se ejecute desde la barra de menú, no un servicio. ¿Tienes la aplicación Speedtest? Algo así, donde la aplicación en sí está en la barra de menú, no solo se inicia desde ella.