문제

I am really stuck here with a simple task, but still cannot get it working.

I've managed to implement 'LaunchAtLogin' feature with the HelperApp as described in this article. But my application should react differently on launch-by-helper-app and launch-by-user actions. So my task now is to have some kind of flag indicating that MainApp was launched by HelperApp.

I know there are many similar questions, but still none of the solutions works for me. Sandbox seems to cut all the parameters I am trying to send to the MainApp.

Here what I have tried:

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

Until recently I thought I can rely on -psn argument sent by Finder when user manually launches the application. But this argument is sent on 10.8 even when MainApp is launched by HelperApp.

In the article mentioned above, author suggests using [NSWorkspace - launchApplicationAtURL: options: configuration: error:]. Parameters are sent, but nothing arrives to the MainApp.

Has anyone succeeded to accomplish this (or similar) task?

Need help! Thanks in advance!

도움이 되었습니까?

해결책

After hell of searching and experimenting I am ready to answer my own question, so others can save their time and efforts.

My conclusion is that for now there is no way HelperApp can launch MainApp with some arguments under the Sandbox. At least I have not found any way to do that.

Launch MainApp like this:

[[NSWorkspace sharedWorkspace] launchApplication:newPath];

In MainApp add the following:

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;
        }
    }
}

That's it. Application_IsLaunchedByHelperApp now has correct value.

The solution is not mine. I've found it on the web (cocoabuilder, I guess). Good luck to everyone! And thanks for your attention to my questions.

UPDATE Looks like there are cases when launched at login app shows launchedByAppBundleId = @"com.apple.loginwindow". So the last part of code will look like this:

    //
    // 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;
        }
    }

다른 팁

The place to seek an answer is the Apple Developer Forums - folk there have dealt with all sorts of issues around helper apps and the sandbox. Searching for application groups and custom URL schemes going back, say, 1-2 years may turn up a solution that meets your needs. If you are still stuck post a question on those forums, someone will probably know what you need.

If you are not an Apple Developer so have no access to those forums, or do not intend to distribute via the Mac App Store, then just turn off the sandbox - in its current state this isn't technology you choose to use... HTH.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top