当用户代理进程终止时如何运行代码?
我想要什么
我想要一个帮助应用程序用户代理(Info.plist 中的 LSUIElement 为 True)在终止时将其自身添加到登录项中。
问题
在帮助应用程序进程终止之前,我无法运行任何代码。 我的“添加到登录项目”代码运行良好。
背景
- 我有一个始终运行的辅助应用程序用户代理进程
- 首次启动时,它会将自身添加到登录项
- 如果应用程序被移动,下次登录时,辅助应用程序进程将无法运行被发现,所以没有启动
我尝试过
我想知道我是否应该子类化 NSApplication 并重写终止:或停止:并将我的代码放在那里,但这似乎有点过分了。当然有更好的方法吗?
我已经在 NSApp 委托中尝试了所有这些不同的事情:
-(void)applicationWillTerminate:(NSApplication *)sender {
[self addHelperAppToLoginItems]
}
-(void)applicationDidTerminate:(NSApplication *)sender {
[self addHelperAppToLoginItems]
}
-(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
[self addHelperAppToLoginItems]
}
-(void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
selector:@selector(addHelperAppToLoginItems)
name:NSWorkspaceDidTerminateApplicationNotification
object:nil];
}
-(void)addHelperAppToLoginItems {
// This code never gets called!
}
Why do the NSApplication delegatemethod not work with a user agent process?
我怎样才能让进程在终止时检查登录项?
我将非常感谢任何帮助。谢谢!
更新 1 6/2/11
经过进一步挖掘,问题更多是进程永远不会真正退出,它们更常见的是被操作系统杀死。
这意味着当您选择“退出”活动监视器中的进程或关闭计算机时,不会调用终止委托方法。
当运行以下 Applescript 时,委托方法会被调用:
tell application "System Events"
tell application "LapsusHelperApp"
quit
end tell
end tell
What I want
I want a helper app user agent (LSUIElement in Info.plist is True) to add itself to the login items on terminate.
The Problem
I can't get any code to run before the helper app process terminates.
My "add to login items" code runs fine.
Background
- I've got a helper app user agent process that runs all the time
- On first launch, it adds itself to login items
- If the app was moved, on next login, the helper app process can't be found and so isn't launched
What I've Tried
I wonder if I should subclass NSApplication and override terminate: or stop: and put my code in there, but that seems overkill. Surely there's a better way?
I've tried all these different things in the NSApp delegate:
-(void)applicationWillTerminate:(NSApplication *)sender {
[self addHelperAppToLoginItems]
}
-(void)applicationDidTerminate:(NSApplication *)sender {
[self addHelperAppToLoginItems]
}
-(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
[self addHelperAppToLoginItems]
}
-(void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
selector:@selector(addHelperAppToLoginItems)
name:NSWorkspaceDidTerminateApplicationNotification
object:nil];
}
-(void)addHelperAppToLoginItems {
// This code never gets called!
}
Why do the NSApplication delegate methods not work with a user agent process?
And how can I get the process to check the login items on terminate?
I'd be very grateful for any help. Thanks!
UPDATE 1 6/2/11
After some further digging, the problem is more that processes never really get quit, it's more common for them to get killed by the OS.
This means when you choose to "Quit" a process in Activity Monitor or you shut down the computer, the terminate delegate methods don't get called.
When the following Applescript is run, the delegate methods do get called:
tell application "System Events"
tell application "LapsusHelperApp"
quit
end tell
end tell
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是因为您为应用程序启用了突然终止。它是选择加入的,因此只需从 Info.plist 中删除该键值对,然后您就会开始收到
applicationWillTerminate:
消息。此外,Xcode 中的终止按钮(至少在 3.x 中)始终以与突然终止相同的方式工作,因此当从 Xcode 终止应用程序时,您永远不会收到
applicationWillTerminate:
消息。顺便说一句:
applicationWillTerminate:
是一个通知消息,因此它的参数是一个 NSNotification 对象,而不是 NSApplication 对象。applicationDidTerminate:
。稍加思考就会明白原因。 ☺This is because you have sudden termination enabled for your application. It's opt-in, so simply remove that key-value pair from your Info.plist and you will then start getting
applicationWillTerminate:
messages.Also, the Terminate button in Xcode (at least in 3.x) always works the same way sudden termination does, so you will never get a
applicationWillTerminate:
message when terminating your app from Xcode.By the way:
applicationWillTerminate:
is a notification message, so its argument is an NSNotification object, not an NSApplication object.applicationDidTerminate:
. A moment's reflection will reveal why. ☺