2

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

如本文所述,我已设法使用 HelperApp 实现“LaunchAtLogin”功能。但是我的应用程序对启动助手应用程序启动用户操作的反应应该不同。所以我现在的任务是有某种标志表明 MainApp 是由 HelperApp 启动的。

我知道有很多类似的问题,但仍然没有一个解决方案适合我。沙盒似乎切断了我试图发送到 MainApp 的所有参数。

这是我尝试过的:

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

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

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

有没有人成功完成这个(或类似的)任务?

需要帮忙!提前致谢!

4

2 回答 2

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;
        }
    }
于 2013-03-25T10:43:19.810 回答
1

寻求答案的地方是 Apple 开发者论坛——那里的人们已经处理了有关帮助应用程序和沙盒的各种问题。搜索应用程序组和自定义 URL 方案可以追溯到 1-2 年,可能会找到满足您需求的解决方案。如果您仍然无法在这些论坛上发布问题,那么有人可能会知道您需要什么。

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

于 2013-03-24T21:56:06.597 回答