“因为它不受SIP保护". -macOS Mojave中的Apple事件错误 [英] "because it is not SIP-protected" - Apple event error in macOS Mojave

查看:274
本文介绍了“因为它不受SIP保护". -macOS Mojave中的Apple事件错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在macOS中有一个正确的沙盒应用程序,即Objective-C,可通过Apple Events(例如Adobe InDesign)与第三方应用程序对话.

I have a properly sandboxed application in macOS, Objective-C that talks to third party applications by Apple Events (e.g. Adobe InDesign).

在macOS Mojave中,一切中断都会导致Apple的新SIP(

In macOS Mojave everything breaks cause Apple's new SIP (https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/Introduction/Introduction.html) doesn't allow the communication.

我尚未找到任何解决方案.任何帮助表示赞赏.

I didn't find any solution yet. Any help appreciated.

这是错误消息:

跳过了脚本附加内容"/Library/ScriptingAdditions/Adob​​e Unit Types.osax",因为它不受SIP保护.

skipped scripting addition "/Library/ScriptingAdditions/Adobe Unit Types.osax" because it is not SIP-protected.

这是问题的一个很好的总结: https://www.felix- schwarz.org/blog/2018/06/apple-event-sandboxing-in-macos-mojave

This is a pretty good summary of the problem: https://www.felix-schwarz.org/blog/2018/06/apple-event-sandboxing-in-macos-mojave

推荐答案

Apple仍需对此进行处理,它并不完美,它对用户不友好,并且没有很好的文档记录.但这是一个可行的解决方案.

Apple still has to work on this, it's not perfect, it's not user friendly, it's not well documented. But here is a working solution.

从OSX 10.14(Mojave)开始,您必须询问OSX的系统完整性保护(SIP),如果用户允许您的应用程序与他人进行通信.

Beginning from OSX 10.14 (Mojave) you have to ask OSX's System Integrity Protection (SIP) if the user allowed your application to communicate with others.

要使其正常工作,您需要在应用程序的.plist文件中添加一个条目:

For making it to work you need to add an entry to your app's .plist file:

key: NSAppleEventsUsageDescription
value: [Some description why you need to use AppleEvents]

注意:您不能将更多条目用于更多应用程序.它的一项.因此,请明智地选择您的描述.此说明将显示在Apple的对话框中,要求用户接受.

Note: You can not use more entries for more applications. Its one entry. So choose your description wisely. This description will be shown in Apple's dialog asking the user for acceptance.

如果您像我一样拥有XPC服务,请将其放置在您的MAIN应用中,而不是在服务中.

If you have an XPC service like i do, place this in your MAIN app, not in the service.

现在在您的应用程序中-在使用Apple事件之前-检查当前状态(是否允许使用AppleEvent).我写了这个方法:

Now in your application - before using Apple events - check for the current state (if AppleEvents allowed or not). I wrote this method:

- (BOOL)checkSIPforAppIdentifier:(NSString*)identifier {

    // First available from 10.14 Mojave
    if (@available(macOS 10.14, *)) {

        OSStatus status;
        NSAppleEventDescriptor *targetAppEventDescriptor;

        targetAppEventDescriptor = [NSAppleEventDescriptor descriptorWithBundleIdentifier:identifier];

        status = AEDeterminePermissionToAutomateTarget(targetAppEventDescriptor.aeDesc, typeWildCard, typeWildCard, true);

        switch (status) {
            case -600: //procNotFound
                NSLog(@"Not running app with id '%@'",identifier);
                break;

            case 0: // noErr
                NSLog(@"SIP check successfull for app with id '%@'",identifier);
                break;

            case -1744: // errAEEventWouldRequireUserConsent
                // This only appears if you send false for askUserIfNeeded
                NSLog(@"User consent required for app with id '%@'",identifier);
                break;

            case -1743: //errAEEventNotPermitted
                NSLog(@"User didn't allow usage for app with id '%@'",identifier);

                // Here you should present a dialog with a tutorial on how to activate it manually
                // This can be something like
                // Go to system preferences > security > privacy
                // Choose automation and active [APPNAME] for [APPNAME]

                return NO;

            default:
                break;
        }
    }
    return YES;
}

这样称呼它:

[self checkSIPforAppIdentifier:@"com.apple.mail"];

您可以在AppleEvents.h中找到详细信息-这是所用方法的副本:

You may find detailed information in AppleEvents.h - here's a copy for the used method :

AEDeterminePermissionToAutomateTarget()

AEDeterminePermissionToAutomateTarget()

讨论:确定当前应用程序是否能够发送 具有给应用程序的给定eventClass和eventID的AppleEvent 描述为targetAddressDesc.

Discussion: Determines whether the current application is able to send an AppleEvent with the given eventClass and eventID to the application described as targetAddressDesc.

Mac OS 10.14和更高版本对应用程序提出了其他要求 当他们将AppleEvents发送到其他应用程序以确保 用户了解并同意允许此类控制或 信息交流.通常,这涉及到提示用户 以安全的方式在应用程序首次尝试发送 AppleEvent转移到另一个应用程序.

Mac OS 10.14 and later impose additional requirements on applications when they send AppleEvents to other applications in order to insure that users are aware of and consent to allowing such control or information exchange. Generally this involves the user being prompted in a secure fashion the first time an application attempts to send an AppleEvent to another application.

如果用户同意,则此应用程序可以将事件发送到 目标.如果用户不同意,则以后可能会尝试发送 AppleEvents将导致失败,并显示errAEEventNotPermitted 回来.某些AppleEvents允许在不提示的情况下发送 用户.将eventClass和eventID的typeWildCard传递给 确定是否允许从该应用程序发送每个事件 到目标.

If the user consents then this application can send events to the target. If the user does not consent then any future attempts to send AppleEvents will result in a failure with errAEEventNotPermitted being returned. Certain AppleEvents are allowed to be sent without prompting the user. Pass typeWildCard for the eventClass and eventID to determine if every event is allowed to be sent from this application to the target.

应用程序可以确定,而无需将AppleEvent发送到目标 应用程序,是否允许他们将AppleEvents发送到 使用此功能的目标.如果askUserIfNeeded为true,则此 应用程序尚无权限将AppleEvents发送到 目标,然后将询问用户是否可以授予权限;如果 askUserIfNeeded为false且未授予权限,则 errAEEventWouldRequireUserConsent将被返回.

Applications can determine, without sending an AppleEvent to a target application, whether they are allowed to send AppleEvents to the target with this function. If askUserIfNeeded is true, and this application does not yet have permission to send AppleEvents to the target, then the user will be asked if permission can be granted; if askUserIfNeeded is false and permission has not been granted, then errAEEventWouldRequireUserConsent will be returned.

目标AEAddressDesc必须引用已经运行的应用程序.

The target AEAddressDesc must refer to an already running application.

结果

如果当前应用程序被允许发送给定的AppleEvent 到目标,则将返回noErr.如果当前 不允许应用程序发送事件errAEEventNotPermitted 将被退回.如果目标应用程序未运行,则 procNotFound将被返回.如果askUserIfNeeded为false,则此 尚不允许应用程序将AppleEvents发送到目标, 然后将返回errAEEventWouldRequireUserConsent.

If the current application is permitted to send the given AppleEvent to the target, then noErr will be returned. If the current application is not permitted to send the event, errAEEventNotPermitted will be returned. If the target application is not running, then procNotFound will be returned. If askUserIfNeeded is false, and this application is not yet permitted to send AppleEvents to the target, then errAEEventWouldRequireUserConsent will be returned.

Mac OS X线程:

Mac OS X threading:

从10.14版开始,线程安全.不要在您的计算机上调用此函数 主线程,因为如果用户返回可能需要花费很长时间 需要提示您同意.

Thread safe since version 10.14. Do not call this function on your main thread because it may take arbitrarily long to return if the user needs to be prompted for consent.

参数:

目标:

指向地址描述符的指针.致电之前 AEDeterminePermissionToAutomateTarget,您可以将描述符设置为 确定Apple事件的目标应用程序.目标 地址描述符必须引用正在运行的应用程序.如果目标 应用程序在另一台计算机上,则必须将Remote AppleEvents 在该计算机上为用户启用.

A pointer to an address descriptor. Before calling AEDeterminePermissionToAutomateTarget, you set the descriptor to identify the target application for the Apple event. The target address descriptor must refer to a running application. If the target application is on another machine, then Remote AppleEvents must be enabled on that machine for the user.

theAEEventClass:Apple事件的事件类,用于确定 许可.

theAEEventClass: The event class of the Apple event to determine permission for.

theAEEventID:Apple事件的事件ID,用于确定权限

theAEEventID: The event ID of the Apple event to determine permission for.

askUserIfNeeded:布尔值;如果为true,并且此应用程序不 仍具有将事件发送到目标应用程序的权限,然后 提示用户获得许可.如果为假,则不提示 用户.

askUserIfNeeded: a Boolean; if true, and if this application does not yet have permission to send events to the target application, then prompt the user to obtain permission. If false, do not prompt the user.

结论:

如前所述,它并不完美.

As mentioned before, it's not perfect.

  • 目标应用必须运行-否则它将返回-600
  • 一旦被拒绝,用户只能手动激活它-感觉并不顺畅.
  • 它的线程安全,因此您不应在主线程中调用它(手动激活对话框除外)

这篇关于“因为它不受SIP保护". -macOS Mojave中的Apple事件错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆