MacApp(使用 Swift)在终止时不会终止启动的子进程

MacApp (using Swift) does not terminate launched sub-process if terminated

我有一个非常简单的 MacOS Swift 应用程序,用作提供停靠栏图标的启动器。应用程序启动主脚本。但是,如果应用程序终止(例如,通过单击它并在上下文菜单中选择 "Close"),带有脚本的子进程将继续 运行.

如果应用程序被终止,如何更改此行为以终止子进程。使用 pgrep 我检查并在子进程中执行脚本:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        print("App started!\n");

        DispatchQueue.global(qos: .background).async {

            let process = Process()
            process.executableURL = URL(fileURLWithPath:"/usr/local/bin/node")
            process.arguments = ["./build/index.js"]
            process.currentDirectoryPath = "/Users/myaccount/basedir"
            process.terminationHandler = { (process) in
            print("didFinish")
            }
            do {
            try process.run()
            } catch {}

        }

    }

    func applicationWillTerminate(_ aNotification: Notification) {
        print("I'll never show up\n")
    }

}

到目前为止,我找到了两个可能的解决方案,也是在我的问题的评论的帮助下:

1.) "The proper way" - 使用应用程序退出回调

Process 对象可以在 global/instance 范围内在 applicationWillTerminate 回调中杀死它。但是我遇到了这个问题,这个函数从来没有被调用过。在这个forum question的帮助下,我发现你需要在Info.plist中将以下两个选项设置为"NO":

那就完美了。

2.) 让子进程监视父进程

可以很容易地获得父进程的 pid (ProcessInfo().processIdentifier) 在启动子进程时将其作为参数并让子进程查看父进程 id - 当它不再存在时,子进程可以杀死自己。可以通过 运行 kill -0 PID 查看一个进程,如果不存在进程将引发错误。