Files
pangolin/client/macos/login_helper/main.swift
T
wangjia cf19ca2d34 feat(client/macos): 开机自启用 SMAppService + LoginItem helper(学 Tailscale)
根因:launch_at_startup 0.5.1 在 macOS 无自带实现,需宿主接 MethodChannel,而我们 Runner
从没实现 → enable() 抛 MissingPluginException 被 try/catch 吞掉 → 登录项从未注册,自启失败。
学 Tailscale(LoginItemHelper-macsys + SMAppService):
- 新增无界面 LoginItem helper(macos/login_helper,LSBackgroundOnly),登录时带 --autostart
  拉起主 app(→隐藏到托盘);
- build_login_helper.sh 构建期编译+签名+嵌入 Contents/Library/LoginItems/(新 Run Script 阶段);
- MainFlutterWindow 接 launch_at_startup MethodChannel → SMAppService.loginItem 注册/注销。
构建通过:helper 嵌入+签名,主 app --deep --strict 校验过。Windows 自启(schtasks)不变。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 10:25:27 +08:00

28 lines
1.3 KiB
Swift

// PangolinLoginHelper helper( Tailscale LoginItemHelper)
//
// SMAppService.loginItem ;: --autostart app
// ( app , app main.dart / MainFlutterWindow),退
// app Contents/Library/LoginItems/PangolinLoginHelper.app( build_login_helper.sh)
import AppKit
// helper <MainApp>.app/Contents/Library/LoginItems/PangolinLoginHelper.app
// app = helper bundle 4 (LoginItems Library Contents <MainApp>.app)
let helperURL = Bundle.main.bundleURL
let mainAppURL = helperURL
.deletingLastPathComponent() // LoginItems
.deletingLastPathComponent() // Library
.deletingLastPathComponent() // Contents
.deletingLastPathComponent() // <MainApp>.app
let config = NSWorkspace.OpenConfiguration()
config.arguments = ["--autostart"] // app
config.activates = false //
config.addsToRecentItems = false
let done = DispatchSemaphore(value: 0)
NSWorkspace.shared.openApplication(at: mainAppURL, configuration: config) { _, _ in
done.signal()
}
// ( 10s)退, helper
_ = done.wait(timeout: .now() + 10)