How do you run inline Applescript from a JXA/JavaS

2020-03-08 05:54发布

I have a script written in JavaScript which needs to run one small piece of AppleScript (to achieve some functionality I've been unable to implement due to a number of factors natively in JS).

It should be able to take a single string argument, and is pretty much a tell-endtell one liner.

Is it possible to assemble this nanoprogramme as a string in JavaScript then pass the string to the AppleScript environment for execution, and how would that be done?

There's plenty of explanations online about how to run JavaScript from Applescript, but not as much coming the other way.

Would this - in all likelihood - involve a shell invocation of osascript -e to achieve, or are there cleaner, more JXA-ey ways?

2条回答
够拽才男人
2楼-- · 2020-03-08 06:22

Use Standard Additions' run script command.

(BTW, my standard recommendation is to stick to using AppleScript for application automation as it's the only [supported] option that works right. JXA's various bugs, defects, and omissions were known about before even it shipped, and Apple couldn't be bothered to fix them back then, so they certainly won't be fixed now the Automation team has been eliminated. The whole Mac Automation platform's dying anyway, but at least AppleScript should bitrot slower than JXA, which was never right to begin with.)

查看更多
女痞
3楼-- · 2020-03-08 06:40

Here is an evalAS function for ES6 (Sierra onwards) macOS.

(() => {
    'use strict';

    // evalAS :: String -> IO String
    const evalAS = s => {
        const
            a = Application.currentApplication(),
            sa = (a.includeStandardAdditions = true, a);
        return sa.doShellScript(
            ['osascript -l AppleScript <<OSA_END 2>/dev/null']
            .concat([s])
            .concat('OSA_END')
            .join('\n')
        );
    };

    return evalAS('tell application \"Finder\" to the clipboard');

})();

The advantage of the shell approach is simply that scripting additions are automatically available in the evaluation environment.

If we use the following alternative definition of evalSA, we need to explicitly prepend our expression string with 'use scripting additions\n'

(() => {
    'use strict';

    // evalAS2 :: String -> IO a
    const evalAS2 = s => {
        const a = Application.currentApplication();
        return (a.includeStandardAdditions = true, a)
            .runScript(s);
    };

    return evalAS2(
        'use scripting additions\n\
        tell Application "Finder" to the clipboard'
    );
})();
查看更多
登录 后发表回答