You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取MacOS应用启动与退出事件以统计运行情况?

在macOS中监听应用启动与退出事件的方案

macOS原生提供了应用启动和退出的系统级事件,以下是两种主流实现方式:

1. 原生开发(Swift/Objective-C/Cocoa)

这是最可靠、高效的事件驱动方案,利用NSWorkspace提供的两个核心通知:

  • NSWorkspaceDidLaunchApplicationNotification:应用启动时触发
  • NSWorkspaceDidTerminateApplicationNotification:应用退出时触发

你可以注册这两个通知,获取启动/退出应用的详细信息(名称、Bundle ID、路径等)。以下是Swift示例代码:

import Cocoa

class AppMonitor: NSObject {
    override init() {
        super.init()
        let workspace = NSWorkspace.shared
        workspace.notificationCenter.addObserver(
            self,
            selector: #selector(appLaunched(_:)),
            name: NSWorkspace.didLaunchApplicationNotification,
            object: nil
        )
        workspace.notificationCenter.addObserver(
            self,
            selector: #selector(appTerminated(_:)),
            name: NSWorkspace.didTerminateApplicationNotification,
            object: nil
        )
    }

    @objc private func appLaunched(_ notification: Notification) {
        guard let app = notification.userInfo?[NSWorkspace.applicationUserInfoKey] as? NSRunningApplication else { return }
        print("应用启动:\(app.localizedName ?? "未知应用") | Bundle ID:\(app.bundleIdentifier ?? "无")")
    }

    @objc private func appTerminated(_ notification: Notification) {
        guard let app = notification.userInfo?[NSWorkspace.applicationUserInfoKey] as? NSRunningApplication else { return }
        print("应用退出:\(app.localizedName ?? "未知应用") | Bundle ID:\(app.bundleIdentifier ?? "无")")
    }
}

// 初始化监听并保持程序运行
let monitor = AppMonitor()
RunLoop.main.run()

2. 脚本/命令行方案(轮询方式)

如果不需要原生开发的性能,也可以用AppleScript或Shell脚本通过轮询实现,虽为被动检查,但能快速实现基础统计:

AppleScript示例

property previousApps : {}

on run
    repeat
        tell application "System Events"
            set currentApps to name of every application process
        end tell
        
        -- 检测新增应用(启动)
        set launchedApps to currentApps whose it is not in previousApps
        if launchedApps is not {} then
            repeat with appName in launchedApps
                log "应用启动:" & appName
            end repeat
        end if
        
        -- 检测退出应用
        set terminatedApps to previousApps whose it is not in currentApps
        if terminatedApps is not {} then
            repeat with appName in terminatedApps
                log "应用退出:" & appName
            end repeat
        end if
        
        set previousApps to currentApps
        delay 1 -- 每秒检查一次
    end repeat
end run

内容的提问来源于stack exchange,提问作者Andrew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 22:55:48