AppleEvent sending Activate command gives an error

I am working on C application which uses AppleEvents. So far I am trying to do simple example which sends Activate to the Terminal. This is what I have:


int main()

{

AppleEvent theEvent;

char* arg = "com.apple.Terminal";

AEAddressDesc addDesc;

OSErr err = AECreateDesc( typeApplicationBundleID, &arg, strlen( arg ), &addDesc );

printf("AECreateDesc error --> %d\n", err);

if( noErr == err )

{

// my event creation

// create event:

err = AECreateAppleEvent( 'misc', 'actv', &addDesc, kAutoGenerateReturnID, kAnyTransactionID, &theEvent );

}

printf("AECreateAppleEvent error --> %d\n", err);

if (noErr == err)

{

AESendMode aeSendMode = kAEAlwaysInteract | kAEWaitReply;

//err = AESend( &theEvent, NULL, aeSendMode, kAENormalPriority, kAEDefaultTimeout, NULL, NULL );

err = AESendMessage(&theEvent, NULL, aeSendMode, kAEDefaultTimeout);

}

printf("AESend error --> %d\n", err);

return 0;

}

But when I run the program it always prints AESend error --> -600 which I have seen that means process not found

Could someone tell me what is wrong here please?

Note: I do not want to use AppleScript, I want to use this, so please no recommendations about using AppleScript


Thanks in advance and regards

Replies

Use AppleScript (-:

Seriously though, writing Apple event code by hand is a royal pain. If you can get away with using AppleScript, you should.

Note that this does not necessarily mean that you have to write your entire app in AppleScript. You can use

NSAppleScript
to run chunks of AppleScript in your app, as I showed in my recent response on your other thread.

If you can’t use AppleScript then you should at least use the Cocoa Apple event API, that is,

<Foundation/NSAppleEventDescriptor.h>
. That is much nicer to use than the original C API.

As to your

procNotFound
error, I suspect you’re hitting that due to the new Apple event authorisation system on 10.14. Make sure your app has a value for the
NSAppleEventsUsageDescription
key in its
Info.plist
.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I have added this to my info.plist file:


<key>NSAppleEventsUsageDescription</key>

<string>I need to access automation</string>


But I still see same error. Isn't this supposed to show auth message or something similar? I am running my application from XCode though

What am I missing?

Regards

My final goal is to build an applicacion which gets browser URL get it is opened.

Are you saying that with new MacOS 10.14 either using AppleScriot or raw AppleEvents I would have to wait for user confirmation when the app tries to get that URL ?

This would be kind of annoying to final user, isnt it? What alternatives would I have, then?

Please help me to clarify this.

But I still see same error.

Weird. I considered writing a snippet that shows how to do this but that reminded me of the actual Apple events you’re sending, namely:

err = AECreateAppleEvent( 'misc', 'actv', &addDesc, kAutoGenerateReturnID, kAnyTransactionID, &theEvent );

You don’t need to use Apple events to activate another app. You can do that using

-[NSRunningApplication activateWithOptions:]
. For example:
NSArray<NSRunningApplication *> * allTerminals = [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.Terminal"];
if (allTerminals.count == 0) {
    NSLog(@"Terminal is not running");
    return;
}
[allTerminals.firstObject activateWithOptions:0];

And as for your ultimate goal, getting the current URL from Safari, I showed how to do than in your other thread.

Are you saying that with new MacOS 10.14 either using AppleScriot or raw AppleEvents I would have to wait for user confirmation when the app tries to get that URL?

Yes. This is a deliberate security-hardening change. WWDC 2018 Session 702 Your Apps and the Future of macOS Security has the details.

The authorisation decision made by the user is saved by the system, so the authorisation dialog should only show up once. After that the user can change the setting in System Preferences > Security & Privacy > Privacy > Automation.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"