ADC Home > Reference Library > Technical Q&As > Scripting & Automation > Carbon >

Calling AppleScript from an Application


Q: My application is written in C, but I would like to use AppleScripts to perform some operations. How can I do this?

A: To run an AppleScript inside of your application, your application should call the AppleScript component to compile and execute a script. The basic steps required to do this are illustrated in Listing 1.




#if TARGET_API_MAC_CARBON
#ifdef __APPLE_CC__
#include <Carbon/Carbon.h>
#else
#include <Carbon.h>
#endif
#else
#include <Types.h>
#include <OSA.h>
#include <AppleScript.h>
#endif
#include <string.h>

    /* LowRunAppleScript compiles and runs an AppleScript
    provided as text in the buffer pointed to by text.  textLength
    bytes will be compiled from this buffer and run as an AppleScript
    using all of the default environment and execution settings.  If
    resultData is not NULL, then the result returned by the execution
    command will be returned as typeChar in this descriptor record
    (or typeNull if there is no result information).  If the function
    returns errOSAScriptError, then resultData will be set to a
    descriptive error message describing the error (if one is
    available).  */
static OSStatus LowRunAppleScript(const void* text, long textLength,
                                    AEDesc *resultData) {
    ComponentInstance theComponent;
    AEDesc scriptTextDesc;
    OSStatus err;
    OSAID scriptID, resultID;

        /* set up locals to a known state */
    theComponent = NULL;
    AECreateDesc(typeNull, NULL, 0, &scriptTextDesc);
    scriptID = kOSANullScript;
    resultID = kOSANullScript;

        /* open the scripting component */
    theComponent = OpenDefaultComponent(kOSAComponentType,
                    typeAppleScript);
    if (theComponent == NULL) { err = paramErr; goto bail; }

        /* put the script text into an aedesc */
    err = AECreateDesc(typeChar, text, textLength, &scriptTextDesc);
    if (err != noErr) goto bail;

        /* compile the script */
    err = OSACompile(theComponent, &scriptTextDesc,
                    kOSAModeNull, &scriptID);
    if (err != noErr) goto bail;

        /* run the script */
    err = OSAExecute(theComponent, scriptID, kOSANullScript,
                    kOSAModeNull, &resultID);

        /* collect the results - if any */
    if (resultData != NULL) {
        AECreateDesc(typeNull, NULL, 0, resultData);
        if (err == errOSAScriptError) {
            OSAScriptError(theComponent, kOSAErrorMessage,
                        typeChar, resultData);
        } else if (err == noErr && resultID != kOSANullScript) {
            OSADisplay(theComponent, resultID, typeChar,
                        kOSAModeNull, resultData);
        }
    }
bail:
    AEDisposeDesc(&scriptTextDesc);
    if (scriptID != kOSANullScript) OSADispose(theComponent, scriptID);
    if (resultID != kOSANullScript) OSADispose(theComponent, resultID);
    if (theComponent != NULL) CloseComponent(theComponent);
    return err;
}


    /* SimpleRunAppleScript compiles and runs the AppleScript in
    the c-style string provided as a parameter.  The result returned
    indicates the success of the operation. */
static OSStatus SimpleRunAppleScript(const char* theScript) {
    return LowRunAppleScript(theScript, strlen(theScript), NULL);
}


/* example:
   SimpleRunAppleScript(
       "tell application \"Finder\"\n"
       "  activate\n"
       "  select folder \"Documents\" of startup disk\n"
       "  open selection\n"
       "end tell");
   */

Listing 1. Example illustrating how to call an AppleScript from C.



Applications that require more specialized control over the script compilation and execution process, such as, for example, caching precompiled scripts, can use other routines defined in OSA.h. To use these routines, applications must link with either CarbonLib or AppleScriptLib.



Note:
This Q&A illustrates a simple way to run AppleScripts inside of your application. Developers concerned about speed, will want to consider using precomiled scripts and opening the scripting component only once when they are initializing their application. For more information about these techniques, consult the AppleScript documentation.



Downloadables

qa1026.hqx

C source files used for code listing (8K)

Download



[Apr 11 2001]


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.