我能做到
NSWorkspaceWillPowerOffNotification
和
applicationShouldTerminate:
NSApplicationActivationPolicyAccessory
并将运行循环替换为
[NSApp run]
. 如果您想继续监视所有注销(和/或关机尝试),它仍然不会很有用,因为它仅在用户已登录时启动进程时起作用,并且它只能检测当前UI登录会话的关机/注销通知和“应用程序应终止”委托。
[NSApp运行]
因此,如果你想继续监视用户的注销(或关机尝试),你需要一个非应用程序(没有
[NSApp运行]
)过程。
NSWorkspaceSessionDidBecomeActiveNotification
和
NSWorkspaceSessionDidResignActiveNotification
工作无需
如果您想监视用户是关闭还是重新打开。
或者,如果系统配置API适用于您的用例,您也可以尝试它。
“技术问答QA1133:确定控制台用户登录状态”
https://developer.apple.com/library/archive/qa/qa1133/_index.html
听起来像
com.apple.system.loginwindow.logoutNoReturn
无论你想做什么,这都是最好的选择。很高兴知道!
// cc powreoff-notification.m -o poweroff-notification -framework AppKit
#import <AppKit/AppKit.h>
@interface ShutDownHandler : NSObject <NSApplicationDelegate>
- (void)computerWillShutDownNotification:(NSNotification *)notification;
@end
int main(int argc, char* argv[]) {
@autoreleasepool {
NSLog(@"%s", __func__);
NSNotificationCenter* notCenter = [[NSWorkspace sharedWorkspace] notificationCenter];
ShutDownHandler* sdh = [ShutDownHandler new];
[NSApplication sharedApplication].delegate = sdh;
[notCenter addObserver:sdh
selector:@selector(computerWillShutDownNotification:)
name:NSWorkspaceWillPowerOffNotification
object:nil];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[[NSFileManager defaultManager] createFileAtPath:@"./output.txt" contents:nil attributes:nil];
});
// without NSApplicationActivationPolicyAccessory, the [NSApp run] process gets killed on
// poweroff/logout instead of getting the power off notification or applicationShouldTerminate:.
[NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
// without [NSApp run], you won't get the power off notification or applicationShouldTerminate:.
//[[NSRunLoop currentRunLoop] run];
[NSApp run];
// this process needs to be launched while the user has already logged in. otherwise,
// you won't get the power off notification or applicationShouldTerminate:.
}
return 0;
}
@implementation ShutDownHandler
- (void)computerWillShutDownNotification:(NSNotification *)notification {
NSLog(@"%s", __func__);
NSFileHandle* file = [NSFileHandle fileHandleForUpdatingAtPath: @"./output.txt"];
[file seekToEndOfFile];
NSDateFormatter* fmt = [NSDateFormatter new];
[fmt setDateFormat:@"yyyy-MM-dd HH:mm:ss\n"];
NSDate* current = [NSDate date];
NSString* dateStr = [fmt stringFromDate:current];
[dateStr writeToFile:@"./output.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];
}
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
NSLog(@"%s", __func__);
return NSTerminateCancel;
}
@end