了解MainApp是否由HelperApp发布

时间:2013-03-24 13:58:05

标签: cocoa sandbox launching-application

我真的被一个简单的任务困在这里,但仍然无法让它发挥作用。

我设法使用HelperApp实现'LaunchAtLogin'功能,如this article中所述。 但是我的应用程序应该对启动辅助应用程序按用户启动操作做出不同的反应。所以我现在的任务是获得某种标志,表明MainApp是由HelperApp发布的。

我知道有很多类似的问题,但仍然没有一个解决方案适合我。 Sandbox似乎削减了我尝试发送给MainApp的所有参数。

我在这里尝试过:

- [NSWorkspace - launchApplicationAtURL: options: configuration: error:]
 - [NSWorkspace - openURLs: withAppBundleIdentifier: options: additionalEventParamDescriptor: launchIdentifiers:]
 - LSOpenApplication()

直到最近,当用户手动启动应用程序时,我认为我可以依赖Finder发送的 -psn 参数。但即使MainApp由HelperApp发布,这个论点也会在10.8发送。

在上面提到的article中,作者建议使用[NSWorkspace - launchApplicationAtURL: options: configuration: error:]。发送参数,但没有任何内容到达MainApp。

有没有人成功完成此(或类似)任务?

需要帮助! 提前谢谢!

2 个答案:

答案 0 :(得分:4)

在搜索和试验之后,我准备回答我自己的问题,以便其他人可以节省他们的时间和精力。

我的结论是,目前HelperApp无法在Sandbox下使用一些参数启动MainApp。至少我没有找到任何办法。

像这样启动MainApp:

[[NSWorkspace sharedWorkspace] launchApplication:newPath];

在MainApp中添加以下内容:

Application_IsLaunchedByHelperApp = YES;

ProcessSerialNumber currPSN;
OSStatus err = GetCurrentProcess(&currPSN);
if (!err)
{
    // Get information about our process
    NSDictionary * currDict = [(NSDictionary *)ProcessInformationCopyDictionary(&currPSN,
                                                                                kProcessDictionaryIncludeAllInformationMask) autorelease];

    // Get the PSN of the app that launched us. Its not really the parent app, in the unix sense.
    long long temp = [[currDict objectForKey:@"ParentPSN"] longLongValue];

    long long hi = (temp >> 32) & 0x00000000FFFFFFFFLL;
    long long lo = (temp >> 0) & 0x00000000FFFFFFFFLL;
    ProcessSerialNumber parentPSN = {(UInt32)hi, (UInt32)lo};

    // Get info on the launching process
    NSDictionary * parentDict = [(NSDictionary*)ProcessInformationCopyDictionary(&parentPSN,
                                                                                 kProcessDictionaryIncludeAllInformationMask) autorelease];

    // analyze
    // parent app info is not null ?
    if (parentDict && parentDict.count > 0)
    {
        NSString * launchedByAppBundleId = [parentDict objectForKey:@"CFBundleIdentifier"];
        if (![launchedByAppBundleId isEqualToString:HELPER_APP_BUNDLE_ID])
        {
            Application_IsLaunchedByHelperApp = NO;
        }
    }
}

就是这样。 Application_IsLaunchedByHelperApp现在具有正确的价值。

解决方案不是我的。我在网上找到了它(cocoabuilder,我猜)。祝大家好运!感谢您关注我的问题。

<强>更新 看起来在登录应用程序显示launchedByAppBundleId = @"com.apple.loginwindow"时启动了一些情况。所以代码的最后部分将如下所示:

    //
    // analyze
    //

    // parent app info is not null ?
    if (parentDict && parentDict.count > 0)
    {
        NSString * launchedByAppBundleId = [parentDict objectForKey:@"CFBundleIdentifier"];
        if (![launchedByAppBundleId isEqualToString:HELPER_APP_BUNDLE_ID] &&
            ![launchedByAppBundleId isEqualToString:@"com.apple.loginwindow"])
        {
            Application_IsLaunchedByHelperApp = NO;
        }
    }

答案 1 :(得分:1)

寻求答案的地方是Apple开发者论坛 - 民间已经处理了有关帮助应用程序和沙箱的各种问题。搜索应用程序组和自定义URL方案(例如,1 - 2年)可能会找到满足您需求的解决方案。如果你仍然坚持在这些论坛上发帖提问,有人可能会知道你需要什么。

如果您不是Apple开发人员,因此无法访问这些论坛,或者无意通过Mac App Store分发,那么只需关闭沙盒 - 在当前状态下,这不是您选择使用的技术...... HTH。