SMAppService register() - 如何检测启动/登录时的启动与常规启动?

问题描述 投票:0回答:2

我们使用新的 MacOS Ventura SMAppService 功能为用户提供“登录时启动”功能。我们以非常简单的方式做到这一点:

SMAppService.mainApp.register()

如果我们在启动/登录时启动,我们希望进行一些特定的处理,而如果只是定期启动,我们就不会这样做。具体来说,如果在启动时作为菜单栏应用程序启动,我们的用户不希望看到任何窗口/UI。

有什么方法可以检测我们的应用程序是否已在启动/登录时启动,而不是常规用户启动的启动?

也许是命令行参数或者我们可以寻找特殊的父进程?似乎没有办法传递命令行参数,而且我们不知道可以寻找任何特殊的父进程。

macos authentication cocoa service-management
2个回答
2
投票

回答我自己的问题,事实证明这是可能的。受到这个旧答案的启发,它适用于非 Ventura API/范式。

在您的 AppDelegate 中:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    NSAppleEventDescriptor* event = NSAppleEventManager.sharedAppleEventManager.currentAppleEvent;
    
    BOOL launchedAsLoginItem = (event.eventID == kAEOpenApplication &&
       [event paramDescriptorForKeyword:keyAEPropData].enumCodeValue == keyAELaunchedAsLogInItem);

    ...
}

和斯威夫特:

let event = NSAppleEventManager.shared().currentAppleEvent
let launchedAsLogInItem =
    event?.eventID == kAEOpenApplication &&
    event?.paramDescriptor(forKeyword: keyAEPropData)?.enumCodeValue == keyAELaunchedAsLogInItem

0
投票

在您的助手应用程序中

- (void)applicationDidFinishLaunching: (NSNotification *)aNotification
{
    // Prepare a dictionary to pass to the App   
    NSDictionary                    *env = @{@"launcher" : [[NSBundle mainBundle] bundleIdentifier]};
    NSWorkspaceOpenConfiguration    *configuration = [NSWorkspaceOpenConfiguration new];
    [configuration setEnvironment:env];
    
    // Let's say your bundleIdentifier is "com.yourdomain.Helper"
    // I used "--a" but you can use your arguments
    [configuration setArguments:@[@"--a", [[NSBundle mainBundle] bundleIdentifier]]];

    [configuration setPromptsUserIfNeeded:YES];
    
    // This is the path to your App
    NSArray     *pathComponents = [[[NSBundle mainBundle] bundlePath] pathComponents];
    pathComponents = [pathComponents subarrayWithRange:NSMakeRange(0, pathComponents.count - 4)];
    NSString    *path = [NSString pathWithComponents:pathComponents];
    
    // Now the helper launches your App
    [[NSWorkspace sharedWorkspace] openApplicationAtURL:[NSURL fileURLWithPath:path]
                   configuration:configuration completionHandler:^(NSRunningApplication* app, NSError* error)
     {
        if(error){
          NSLog(@"•••• Helper applicationDidFinishLaunching: Failed to run the app: %@", error.localizedDescription);
        }
        else{
            //NSLog(@"•••• Helper applicationDidFinishLaunching: OK to run the app.");
        }
        exit(0);
    }]; 
}  

在您的应用程序中

- (void)applicationDidFinishLaunching:(NSNotification*)aNotification
{
    NSArray *arguments = [[NSProcessInfo processInfo] arguments];
    
    NSLog(@"•••• App applicationDidFinishLaunching!!! >>>>>>>>>> arguments %@", arguments);
    
    // You will get the log with an array like the following one, containing
        // The path to your app
        // The argument --a you defined above
        // The Helper identifier you defined above
    /*
        •••• App applicationDidFinishLaunching!!! >>>>>>>>>> arguments (
        "/PathToYourApp.app/Contents/MacOS/YourApp",
        "--a",
        "com.yourdomain.Helper"
    )
    */
    
    
    BOOL launchedByHelper = [arguments indexOfObject:@"com.yourdomain.Helper"] != NSNotFound;
    
    if(launchedByHelper){
        // Here you can run your code when the app
        // has been launched by the Helper
    }
    else{
    
    }
    
}
© www.soinside.com 2019 - 2024. All rights reserved.