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
查看一个进程,如果不存在进程将引发错误。
我有一个非常简单的 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
查看一个进程,如果不存在进程将引发错误。