# MarkBaseFS System Extension Installer 实施方案 **日期:** 2026-05-24 **状态:** 阶段9暂停,待重新规划 **问题:** App Bundle结构不完整导致启动失败(错误163) --- ## 实施进度总结 ### 已完成 ✅ 1. **xcode-select配置** - 配置成功: `/Applications/Xcode.app/Contents/Developer`(Xcode 26.5) - 更新时间: 2026-05-24(已从Volume 1的Xcode 16.2更新) 2. **App Store Connect API Key创建** - Key ID: `94FCMLS254` - Issuer ID: `69a6de72-d392-47e3-e053-5b8c7c11a4d1` - Private Key: `~/.appstoreconnect/AuthKey_94FCMLS254.p8` 3. **Notarization流程验证** - Submission ID: `155b81b3-6f37-43c8-bcb7-75e3dd3ef3d2` - 状态: Accepted ✅ - 验证: `source=Notarized Developer ID` 4. **Staple公证结果** - 执行成功: `xcrun stapler staple` - 验证通过: Gatekeeper accepted --- ### 失败项 ❌ 1. **App启动失败(错误163)** - 原因: App Bundle缺少必要的资源文件 - Resources目录为空(缺少Assets.xcassets等) 2. **使用VPN模板编译失败** - getlantern/systemextensiondemo是VPN项目(不适用) - 缺少provisioning profile和XCFramework --- ## 关键发现 ### Notarization完整流程(已验证成功) ```bash # 1. 创建API Key(App Store Connect网页操作) # 2. 配置API Key文件 mkdir -p ~/.appstoreconnect mv ~/Downloads/AuthKey_*.p8 ~/.appstoreconnect/ # 3. 创建配置文件 cat > ~/.appstoreconnect/api_key.json << 'EOF' { "key_id": "94FCMLS254", "issuer_id": "69a6de72-d392-47e3-e053-5b8c7c11a4d1", "key_filepath": "~/.appstoreconnect/AuthKey_94FCMLS254.p8" } EOF # 4. 打包App zip -r MarkBaseInstaller.zip MarkBaseInstaller.app # 5. 提交Notarization xcrun notarytool submit MarkBaseInstaller.zip \ --key-id 94FCMLS254 \ --issuer 69a6de72-d392-47e3-e053-5b8c7c11a4d1 \ --key ~/.appstoreconnect/AuthKey_94FCMLS254.p8 \ --wait # 6. Staple公证结果 xcrun stapler staple MarkBaseInstaller.app # 7. 验证 spctl -a -t exec -vv MarkBaseInstaller.app ``` ### 错误163根本原因 **结论:** App Bundle结构不完整 **缺失文件:** - Assets.xcassets(App图标等资源) - MainMenu.xib或Storyboard(GUI配置) - 正确的NSApplication初始化代码 --- ## 解决方案对比 ### 方案A: 使用Xcode GUI创建项目(推荐) **优势:** - ✅ 业界标准流程 - ✅ 自动生成完整App Bundle结构 - ✅ 自动处理签名和entitlements - ✅ 内置System Extension capability - ✅ 可直接Archive → Notarize → Staple **步骤:** #### 1. 创建Xcode项目(5分钟) ``` 打开Xcode → File → New → Project → macOS → App → 配置: - Product Name: MarkBaseInstaller - Team: K3TDMD9Y6B - Organization Identifier: com.momentry.markbase - Bundle ID: com.momentry.markbase.installer(自动生成) - Language: Swift - Interface: SwiftUI(推荐)或Storyboard ``` #### 2. 配置System Extension Capability(2分钟) ``` Target → Signing & Capabilities → + Capability → System Extension → 自动添加entitlements: - com.apple.developer.system-extension.install = true ``` #### 3. 修改Bundle ID(可选,若需要) ``` Target → General → Bundle Identifier: com.momentry.markbase.installer ``` #### 4. 复制Swift代码(3分钟) **AppDelegate.swift(若使用Storyboard):** ```swift import Cocoa import SystemExtensions class AppDelegate: NSObject, NSApplicationDelegate { var window: NSWindow! var statusLabel: NSTextField! var installButton: NSButton! func applicationDidFinishLaunching(_ aNotification: Notification) { createWindow() setupUI() } func createWindow() { window = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 480, height: 300), styleMask: [.titled, .closable, .miniaturizable], backing: .buffered, defer: false ) window.title = "MarkBase Installer" window.center() window.makeKeyAndOrderFront(nil) } func setupUI() { let contentView = window.contentView! statusLabel = NSTextField(labelWithString: "Ready to install MarkBaseFS System Extension") statusLabel.alignment = .center contentView.addSubview(statusLabel) installButton = NSButton(title: "Install System Extension", target: self, action: #selector(installExtension(_:))) contentView.addSubview(installButton) // Layout constraints... } @objc func installExtension(_ sender: NSButton) { let request = OSSystemExtensionRequest.activationRequest( forExtensionWithIdentifier: "com.momentry.markbase.fskit", queue: .main ) request.delegate = self OSSystemExtensionManager.shared.submitRequest(request) } } extension AppDelegate: OSSystemExtensionRequestDelegate { func request(_ request: OSSystemExtensionRequest, didFinishWithResult result: OSSystemExtensionRequest.Result) { // 处理成功 } func request(_ request: OSSystemExtensionRequest, didFailWithError error: Error) { // 处理失败 } func requestNeedsUserApproval(_ request: OSSystemExtensionRequest) { // 提示用户批准 } func request(_ request: OSSystemExtensionRequest, actionForReplacingExtension existing: OSSystemExtensionProperties, withExtension ext: OSSystemExtensionProperties) -> OSSystemExtensionReplacementAction { return .replace } } ``` **ContentView.swift(若使用SwiftUI):** ```swift import SwiftUI import SystemExtensions struct ContentView: View { @State private var statusMessage = "Ready to install MarkBaseFS System Extension" @State private var isInstalling = false var body: some View { VStack(spacing: 20) { Text(statusMessage) .font(.headline) .multilineTextAlignment(.center) Button(action: installExtension) { if isInstalling { ProgressView() .scaleEffect(0.8) } else { Text("Install System Extension") } } .disabled(isInstalling) .buttonStyle(.borderedProminent) } .padding() .frame(width: 480, height: 300) } func installExtension() { isInstalling = true statusMessage = "Requesting installation..." let request = OSSystemExtensionRequest.activationRequest( forExtensionWithIdentifier: "com.momentry.markbase.fskit", queue: .main ) // Delegate implementation... } } ``` #### 5. Build → Archive → Notarize(10分钟) ```bash # Build xcodebuild -project MarkBaseInstaller.xcodeproj \ -scheme MarkBaseInstaller \ -configuration Release \ clean build # Archive xcodebuild -project MarkBaseInstaller.xcodeproj \ -scheme MarkBaseInstaller \ -archivePath build/MarkBaseInstaller.xcarchive \ archive # Export xcodebuild -exportArchive \ -archivePath build/MarkBaseInstaller.xcarchive \ -exportPath build/export \ -exportOptionsPlist ExportOptions.plist # ExportOptions.plist内容: method developer-id teamID K3TDMD9Y6B # Notarize xcrun notarytool submit build/export/MarkBaseInstaller.zip \ --key-id 94FCMLS254 \ --issuer 69a6de72-d392-47e3-e053-5b8c7c11a4d1 \ --key ~/.appstoreconnect/AuthKey_94FCMLS254.p8 \ --wait # Staple xcrun stapler staple build/export/MarkBaseInstaller.app # 验证 spctl -a -t exec -vv build/export/MarkBaseInstaller.app ``` #### 6. 测试安装(2分钟) ```bash # 启动App open build/export/MarkBaseInstaller.app # 点击Install按钮 → 用户批准 # 验证安装 systemextensionsctl list # 预期输出: # com.momentry.markbase.fskit (version 1.0) [activated] ``` **预估总时间:** 20-25分钟 --- ### 方案B: 修复现有MarkBaseInstaller.app(困难) **需要手动添加:** 1. **Assets.xcassets** - 创建App图标资源 - 配置AppIcon.appiconset 2. **MainMenu.xib或Storyboard** - 创建GUI界面 - 配置NSApplication初始化 3. **修复Info.plist** - 添加NSMainNibFile配置 **预估时间:** 30-40分钟 **风险:** 高(可能仍遇到其他结构性问题) --- ### 方案C: 使用命令行创建最小App Bundle(实验性) **步骤:** ```bash # 1. 创建目录结构 mkdir -p MarkBaseInstaller_New.app/Contents/{MacOS,Resources} # 2. 编译Swift代码 swiftc -o MarkBaseInstaller_New.app/Contents/MacOS/MarkBaseInstaller \ -target arm64-apple-macos14 \ -framework Cocoa \ -framework SystemExtensions \ AppDelegate.swift # 3. 创建Info.plist cat > MarkBaseInstaller_New.app/Contents/Info.plist << 'EOF' CFBundleIdentifier com.momentry.markbase.installer CFBundleName MarkBase Installer CFBundleExecutable MarkBaseInstaller CFBundlePackageType APPL LSMinimumSystemVersion 14.0 NSPrincipalClass NSApplication EOF # 4. 创建PkgInfo echo -n "APPL????" > MarkBaseInstaller_New.app/Contents/PkgInfo # 5. 签名 codesign --force --sign "Developer ID Application: Accusys,Inc (K3TDMD9Y6B)" \ --entitlements entitlements.plist \ --deep --options runtime \ MarkBaseInstaller_New.app # 6. Notarize + Staple(流程同上) ``` **预估时间:** 15-20分钟 **风险:** 中(可能仍缺少GUI资源) --- ## 推荐选择 **推荐: 方案A(使用Xcode GUI)** **理由:** 1. 最可靠(业界标准流程) 2. 最快速(自动处理所有配置) 3. 最安全(避免结构性问题) 4. 可维护(未来修改方便) --- ## API Key配置信息(已创建,可复用) **Key ID:** `94FCMLS254` **Issuer ID:** `69a6de72-d392-47e3-e053-5b8c7c11a4d1` **Private Key路径:** `~/.appstoreconnect/AuthKey_94FCMLS254.p8` **配置文件路径:** `~/.appstoreconnect/api_key.json` --- ## 开发者证书信息 **证书:** `Developer ID Application: Accusys,Inc (K3TDMD9Y6B)` **Team ID:** `K3TDMD9Y6B` **证书ID:** `EC458E4414308FDFE98616D2C0D90B684B5BD973` --- ## Xcode配置信息(已更新) **Xcode路径:** `/Applications/Xcode.app`(主系统盘) **Xcode版本:** 26.5 (Build 17F42) **xcode-select:** 已配置到Xcode 26.5 **xcrun版本:** 72 **Swift版本:** 6.3.2 **Clang版本:** 21.0.0 **Target平台:** arm64-apple-macosx26.0 **更新说明:** - 从Volume 1的Xcode 16.2更新到主系统盘的Xcode 26.5 - 与macOS 26.5完美匹配 - 内置最新FSKit支持和System Extension模板 --- ## 磁盘配置信息 | 卷宗名称 | 挂载点 | 设备 | 类型 | 大小 | |----------|--------|------|------|------| | **KX_macOS_2T** | `/` | disk6s1s1 | 启动盘(外部2TB NVMe) | 1.9TB | | **Volume 1** | `/Volumes/Volume 1` | disk2s3 | 内部SSD分区 | 122GB | | **Volume 2** | `/Volumes/Volume 2` | disk3s3 | 内部SSD分区 | 122GB | --- ## 下次实施建议 ### 开始步骤: 1. **打开Xcode GUI**(方案A) 2. **创建新项目** 3. **配置System Extension Capability** 4. **复制Swift代码** 5. **Build → Archive → Notarize → Staple** 6. **测试安装** ### 预估总时间: - 方案A: 20-25分钟 - 方案B: 30-40分钟 - 方案C: 15-20分钟 --- ## 注意事项 ### ⚠️ API Key已创建,无需重新创建 **重要:** - API Key配置已完成(Key ID + Issuer ID + Private Key) - Private Key只能下载一次,已保存 - 下次实施时直接使用现有配置 ### ⚠️ Notarization流程已验证成功 **重要:** - Notarization流程正确(Submission ID已记录) - Staple流程正确(验证通过) - 下次实施时无需重新验证流程 ### ⚠️ 错误163根本原因已明确 **重要:** - 问题不是Notarization(公证成功) - 问题不是签名(签名正确) - **问题: App Bundle结构不完整** --- ## 参考文档 ### Apple官方文档: - System Extensions: https://developer.apple.com/documentation/systemextensions - Notarization: https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution ### 开源参考: - getlantern/systemextensiondemo(VPN项目,流程参考) - knightsc/USBApp(DriverKit项目,结构参考) --- ## 实施记录详情 ### Notarization提交记录 **Submission ID:** `155b81b3-6f37-43c8-bcb7-75e3dd3ef3d2` **提交时间:** 2026-05-24 00:17 **处理状态:** Accepted ✅ **处理时间:** 约1分钟 **输出日志:** ``` Conducting pre-submission checks for MarkBaseInstaller.zip... Initiating connection to the Apple notary service... Successfully uploaded package id: 155b81b3-6f37-43c8-bcb7-75e3dd3ef3d2 path: /Users/accusys/markbase/build/MarkBaseInstaller.zip Waiting for processing to complete... Current status: In Progress....Current status: In Progress....Current status: Accepted.....Processing complete! id: 155b81b3-6f37-43c8-bcb7-75e3dd3ef3d2 status: Accepted ``` --- ### 错误163详细记录 **错误代码:** POSIX error 163 **错误描述:** "Unknown error: 163" / "Launchd job spawn failed" **触发场景:** 执行 `open MarkBaseInstaller.app` **诊断过程:** 1. **检查二进制文件:** `otool -L` - 结果: 链接正确(SystemExtensions.framework存在) 2. **检查main函数:** `nm | grep main` - 结果: `_main`存在 3. **检查签名:** `codesign -dv` - 结果: 签名正确(Developer ID Application) 4. **检查公证:** `spctl -a -t exec -vv` - 结果: 公证正确(Notarized Developer ID) 5. **检查Resources目录:** `ls Contents/Resources/` - 结果: **空目录** ❌ **根本原因:** App Bundle缺少必要的资源文件和GUI初始化配置 --- ## 文件路径记录 | 文件类型 | 路径 | |----------|------| | **API Key配置** | `~/.appstoreconnect/api_key.json` | | **Private Key** | `~/.appstoreconnect/AuthKey_94FCMLS254.p8` | | **打包文件** | `/Users/accusys/markbase/build/MarkBaseInstaller.zip` | | **App Bundle** | `/Users/accusys/markbase/tools/MarkBaseInstaller.app` | | **模板项目** | `/Users/accusys/markbase/tools/systemextensiondemo/` | | **Xcode路径** | `/Applications/Xcode.app`(Xcode 26.5)| | **本实施方案** | `/Users/accusys/markbase/docs/IMPLEMENTATION_PLAN.md` | --- --- ## xcode-select配置记录(更新) **配置时间:** 2026-05-24 **之前配置:** `/Volumes/Volume 1/Applications/Xcode_16.2.app`(Xcode 16.2) **当前配置:** `/Applications/Xcode.app`(Xcode 26.5) **配置命令:** ```bash sudo xcode-select --switch /Applications/Xcode.app ``` **验证结果:** ``` xcode-select -p /Applications/Xcode.app/Contents/Developer xcodebuild -version Xcode 26.5 Build version 17F42 xcrun --version xcrun version 72 swift --version swift-driver version: 1.148.6 Apple Swift version 6.3.2 Target: arm64-apple-macosx26.0 ``` **关键变化:** | 项目 | 之前 | 现在 | |------|------|------| | Xcode版本 | 16.2 | **26.5** ✅ | | xcrun版本 | 70 | **72** ✅ | | Swift版本 | - | **6.3.2** ✅ | | Target | - | **macOS 26.0** ✅ | --- **文档生成时间:** 2026-05-24 00:30 **状态:** 已更新xcode-select配置,待明天继续实施