Accessing script run handler from NSAppleScript

  • Hi

    I am trying to call as wide as possible a variety of AppleScripts from
    cocoa using NSAppleScript and am having trouble
    finding a way of calling a script with a parameterised run handler.

    eg: a script called beepn.scpt and containing

    on run (n, interval)
    repeat n times
      beep
      delay interval
    end repeat
    end run

    can be executed from the terminal as:

    osascript beepn.scpt 2 1

    As yet I have been unable to call such a script from NSAppleScript.

    So far my approach has been.

    1. If the script has no specified run handler or a run handler without
    parameters then
        use the NSAppleScript - executeAndReturnError method.

        This works for scripts such as:

    beep
        or

            on run
              beep
          end run

    2. if the script contains a specified handler then I construct an
    NSAppleEventDescriptor
        specifying the handler and parameters  and call the NSAppleScript
    - executeAppleEvent method.

        This works for scripts such as:

        on beep(n, interval)
            repeat n times
              beep
              delay interval
          end repeat
        end beep

    Unfortunately neither of these methods can handle a script with run
    handler parameters.

    Calling NSAppleScript -executeAndReturnError gives no output - as may
    be expected.

    Calling the run handler explicitly by name with NSAppleScript -
    executeAppleEvent results in:

    Error -1708 occured the run(Hello) call: (null)

      which evaluates to errAEEventNotHandled    -1708    Event wasnt handled
    by an Apple event handler.
    Passing an empty or nil handler name also does not work.

    Of course I can change the run handler name but that means editing the
    script, which I would like to avoid if at all possible.

    Any thoughts would be welcome.
  • <jonathan...> wrote:

    > I am trying to call as wide as possible a variety of AppleScripts
    > from cocoa using NSAppleScript and am having trouble
    > finding a way of calling a script with a parameterised run handler.
    > [...]

    > Calling the run handler explicitly by name with NSAppleScript -
    > executeAppleEvent results in:
    >
    > Error -1708 occured the run(Hello) call: (null)

    'run' is an AppleScript-defined keyword, not a user-defined
    identifier, so make sure you're using the appropriate AE codes
    ('aevt'/'oapp' in this case). Example:

    #import "Appscript/Appscript.h"

    int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    // Create AEMApplication object for building AEMEvents
    AEMApplication *app = [[AEMApplication alloc] init];

    // Create AEMCodecs object for unpacking script results
    AEMCodecs *codecs = [[AEMCodecs alloc] init];

    // Build parameter list for script
    NSArray *params = [NSArray arrayWithObjects:@"Hello ", @"World!", nil];

    // Create 'aevtoapp' (AppleScript subroutine) AEMEvent
    AEMEvent *evt = [app eventWithEventClass:kCoreEventClass
                                        eventID:kAEOpenApplication];

    // Add parameter list to AEMEvent
    [evt setParameter:params forKeyword:keyDirectObject];

    // Compile (or load) the AppleScript
    NSAppleScript *scpt = [[NSAppleScript alloc] initWithSource:
      @"on run {arg1, arg2}\n"
      @" return arg1 & arg2\n"
      @"end run"];

    // Get an NSAppleEventDescriptor from AEMEvent
    NSAppleEventDescriptor *evtDesc = [evt appleEventDescriptor];

    // Send event to AppleScript
    NSDictionary *error;
    NSAppleEventDescriptor *resDesc = [scpt executeAppleEvent:evtDesc
    error:&error];

    // Unpack script result
    id res = [codecs unpack:resDesc];
    NSLog(@"Result = %@", res); // "Result = Hello World!"

    [scpt release];
    [codecs release];
    [app release];
    [pool release];
    return 0;
    }

    Notes:
    - An aevt/oapp event will work even for scripts that don't have
    explicit run handlers.

    - While you must pass all parameters expected by the script, any
    excess parameters are simply ignored.  That means you can always pass
    parameters, and if the script doesn't need them it can simply ignore
    them.

    has
    --
    http://appscript.sourceforge.net
    http://rb-appscript.rubyforge.org
  • Great reply. Googling for AEMApplication shows that you have more or
    less answered my question on the list before.
    Apologies that I didn't find it.

    Many thanks

    Jonathan

    > FROM : has
    > DATE : Fri Jan 04 23:46:36 2008
    >
    > <email_removed> wrote:
    >
    >> I am trying to call as wide as possible a variety of AppleScripts
    >> from cocoa using NSAppleScript and am having trouble
    >> finding a way of calling a script with a parameterised run handler.
    >> [...]
    >
    >
    >> Calling the run handler explicitly by name with NSAppleScript -
    >> executeAppleEvent results in:
    >>
    >> Error -1708 occured the run(Hello) call: (null)
    >
    >
    > 'run' is an AppleScript-defined keyword, not a user-defined
    > identifier, so make sure you're using the appropriate AE codes
    > ('aevt'/'oapp' in this case). Example:
    >
    > #import "Appscript/Appscript.h"
    >
    >
    > int main (int argc, const char * argv[]) {
    > NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    >
    > // Create AEMApplication object for building AEMEvents
    > AEMApplication *app = [[AEMApplication alloc] init];
    >
    > // Create AEMCodecs object for unpacking script results
    > AEMCodecs *codecs = [[AEMCodecs alloc] init];
    >
    > // Build parameter list for script
    > NSArray *params = [NSArray arrayWithObjects:@"Hello ", @"World!",
    > nil];
    >
    > // Create 'aevtoapp' (AppleScript subroutine) AEMEvent
    > AEMEvent *evt = [app eventWithEventClass:kCoreEventClass
    > eventID:kAEOpenApplication];
    >
    > // Add parameter list to AEMEvent
    > [evt setParameter:params forKeyword:keyDirectObject];
    >
    > // Compile (or load) the AppleScript
    > NSAppleScript *scpt = [[NSAppleScript alloc] initWithSource:
    > @"on run {arg1, arg2}\n"
    > @"    return arg1 & arg2\n"
    > @"end run"];
    >
    > // Get an NSAppleEventDescriptor from AEMEvent
    > NSAppleEventDescriptor *evtDesc = [evt appleEventDescriptor];
    >
    > // Send event to AppleScript
    > NSDictionary *error;
    > NSAppleEventDescriptor *resDesc = [scpt executeAppleEvent:evtDesc
    > error:&error];
    >
    > // Unpack script result
    > id res = [codecs unpack:resDesc];
    > NSLog(@"Result = %@", res); // "Result = Hello World!"
    >
    > [scpt release];
    > [codecs release];
    > [app release];
    > [pool release];
    > return 0;
    > }
    >
    >
    > Notes:
    > - An aevt/oapp event will work even for scripts that don't have
    > explicit run handlers.
    >
    > - While you must pass all parameters expected by the script, any
    > excess parameters are simply ignored.  That means you can always pass
    > parameters, and if the script doesn't need them it can simply ignore
    > them.
    >
    > has
    > --
    > http://appscript.sourceforge.net
    > http://rb-appscript.rubyforge.org
previous month january 2008 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today