帮助应用程序无法被杀死,也无法启动主应用程序

时间:2017-07-23 16:52:00

标签: macos cocoa nsapplication

关于在登录时启动沙盒应用程序,我还有其他问题,显然没有解决方案:herehere

如您所知,您必须创建一个帮助应用程序,它将启动主应用程序并消亡。

那里的所有教程都说要将它添加到助手代表中:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

  // Get the path for the main app bundle from the helper bundle path.
  NSString *basePath = [[NSBundle mainBundle] bundlePath];
  NSString *path = [basePath stringByDeletingLastPathComponent];
  path = [path stringByDeletingLastPathComponent];
  path = [path stringByDeletingLastPathComponent];
  path = [path stringByDeletingLastPathComponent];

  [[NSWorkspace sharedWorkspace] launchApplication:path];
  [[NSApplication sharedApplication] terminate:self];
}

此代码完全没有任何效果,因为主应用程序未启动(由于您将在其他问题上看到的原因)并且作为奖励,帮助程序不会被杀死。

我曾尝试使用各种方法杀死助手,例如

[NSApp terminate:self];

甚至这种戏剧性的方法

NSArray *runningApplications = [[NSWorkspace sharedWorkspace] runningApplications];
  NSString *theName;
  NSNumber *pid;
  for ( NSDictionary *applInfo in runningApplications ) {
    if ( (theName = [applInfo objectForKey:@"NSApplicationName"]) ) {
      if ( (pid = [applInfo objectForKey:@"NSApplicationProcessIdentifier"]) ) {
        //NSLog( @"Process %@ has pid:%@", theName, pid );  
        if( [theName isEqualToString:@"MyHelper"] ) {
          kill( [pid intValue], SIGKILL );
        }
      }
    }
  }

没有什么可以杀死帮助者。

作为另一个奖励,当我手动启动主应用程序并且它位于菜单栏上时,我可以选择从主应用程序本身选择QUIT,因此我可以退出应用程序,但主应用程序本身也不是可以使用相同的编程方法。

发生了什么事?

我已按照@vadian说明操作,但无效。 我已将概念验证项目上传到here 。您将看到帮助程序加载但不加载应用程序。

1 个答案:

答案 0 :(得分:1)

您的方法无法正常工作,因为它不完整。至少你必须添加这两个路径组件来获取主应用程序的可执行文件的路径(用MacOS文件夹中的可执行文件的名称替换MyApp

path = [path stringByAddingPathComponent:@"MacOS"];
path = [path stringByAddingPathComponent:@"MyApp"];

然而,推荐和可靠的方法是检查主应用程序是否已经运行并向主应用程序发送LaunchConfigurationArgument以指示应用程序是在登录时启动的(当然还要使用现代URL NSBundleNSWorkspace)的相关API:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    BOOL alreadyRunning = NO, isActive = NO;
    NSArray *running = [[NSWorkspace sharedWorkspace] runningApplications];
    for (NSRunningApplication *app in running) {
        if ([[app bundleIdentifier] isEqualToString:@"com.myCompany.MyApp"]) {
            alreadyRunning = YES;
            isActive = [app isActive];
            break;
        }
    }

    if (!alreadyRunning || !isActive) {
        NSURL *bundleURL = [[NSBundle mainBundle] bundleURL];
        NSMutableArray *pathComponents = [[bundleURL pathComponents] mutableCopy];
        NSUInteger numberOfPathcomponents = [pathComponents count];
        [pathComponents removeObjectsInRange:NSMakeRange(numberOfPathcomponents - 3, 3)];
        [pathComponents addObject:@"MacOS"];
        [pathComponents addObject:@"MyApp"];
        NSURL *newURL = [NSURL fileURLWithPathComponents:pathComponents];
        NSDictionary *dict = @{NSWorkspaceLaunchConfigurationArguments: @[@"launchedAtLogin"]};
        [[NSWorkspace sharedWorkspace] launchApplicationAtURL:newURL
                                                      options:NSWorkspaceLaunchWithoutActivation
                                                configuration:dict
                                                        error:nil];
    }
    [NSApp terminate:nil];
}

基本上你不必从其他地方退出帮助应用程序。无论如何,帮助应用程序都应该自行退出。