import Cocoa import SystemExtensions import OSLog @main struct MarkBaseInstallerApp { static func main() { let app = NSApplication.shared let delegate = AppDelegate() app.delegate = delegate app.run() } } class AppDelegate: NSObject, NSApplicationDelegate { let logger = Logger(subsystem: "com.momentry.markbase.installer", category: "AppDelegate") var window: NSWindow! var statusLabel: NSTextField! var installButton: NSButton! var activityIndicator: NSProgressIndicator! func applicationDidFinishLaunching(_ aNotification: Notification) { logger.info("MarkBase Installer started") createWindow() setupUI() window.makeKeyAndOrderFront(nil) } func createWindow() { window = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 500, height: 400), styleMask: [.titled, .closable, .miniaturizable], backing: .buffered, defer: false ) window.title = "MarkBase Installer" window.center() window.isReleasedWhenClosed = false } func setupUI() { let contentView = window.contentView! // Title let titleLabel = NSTextField(labelWithString: "MarkBase System Extension Installer") titleLabel.font = NSFont.systemFont(ofSize: 18, weight: .bold) titleLabel.alignment = .center contentView.addSubview(titleLabel) // Status Label statusLabel = NSTextField(wrappingLabelWithString: "Ready to install MarkBaseFS System Extension") statusLabel.font = NSFont.systemFont(ofSize: 14) statusLabel.alignment = .center statusLabel.textColor = NSColor.controlTextColor contentView.addSubview(statusLabel) // Install Button installButton = NSButton(title: "Install System Extension", target: self, action: #selector(installExtension(_:))) installButton.bezelStyle = .rounded installButton.font = NSFont.systemFont(ofSize: 13, weight: .medium) contentView.addSubview(installButton) // Activity Indicator activityIndicator = NSProgressIndicator() activityIndicator.style = .spinning activityIndicator.controlSize = .small activityIndicator.isHidden = true contentView.addSubview(activityIndicator) // Instructions let instructionsLabel = NSTextField(wrappingLabelWithString: "Instructions:\n1. Click Install button\n2. Approve in System Settings → Privacy & Security → System Extensions\n3. Wait for activation") instructionsLabel.font = NSFont.systemFont(ofSize: 12) instructionsLabel.alignment = .left instructionsLabel.textColor = NSColor.secondaryLabelColor contentView.addSubview(instructionsLabel) // Layout titleLabel.translatesAutoresizingMaskIntoConstraints = false statusLabel.translatesAutoresizingMaskIntoConstraints = false installButton.translatesAutoresizingMaskIntoConstraints = false activityIndicator.translatesAutoresizingMaskIntoConstraints = false instructionsLabel.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ // Title titleLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor), titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 40), // Status Label statusLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor), statusLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 30), statusLabel.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.8), // Install Button installButton.centerXAnchor.constraint(equalTo: contentView.centerXAnchor), installButton.topAnchor.constraint(equalTo: statusLabel.bottomAnchor, constant: 30), installButton.widthAnchor.constraint(equalToConstant: 200), installButton.heightAnchor.constraint(equalToConstant: 30), // Activity Indicator activityIndicator.centerXAnchor.constraint(equalTo: contentView.centerXAnchor), activityIndicator.topAnchor.constraint(equalTo: installButton.bottomAnchor, constant: 20), // Instructions instructionsLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 30), instructionsLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -30), instructionsLabel.topAnchor.constraint(equalTo: activityIndicator.bottomAnchor, constant: 30), instructionsLabel.bottomAnchor.constraint(lessThanOrEqualTo: contentView.bottomAnchor, constant: -30) ]) } @objc func installExtension(_ sender: NSButton) { logger.info("Install button clicked") let extensionID = "com.momentry.markbase.fskit" logger.info("Requesting activation for extension: \(extensionID)") updateStatus("Requesting installation...") installButton.isEnabled = false activityIndicator.isHidden = false activityIndicator.startAnimation(nil) let request = OSSystemExtensionRequest.activationRequest( forExtensionWithIdentifier: extensionID, queue: .main ) request.delegate = ExtensionDelegate( onSuccess: { self.logger.info("Extension activated successfully") self.updateStatus("✅ Installation successful!\nSystem Extension is now active.") self.activityIndicator.stopAnimation(nil) self.activityIndicator.isHidden = true self.installButton.isEnabled = true }, onError: { error in self.logger.error("Extension activation failed: \(error.localizedDescription)") self.updateStatus("❌ Installation failed: \(error.localizedDescription)") self.activityIndicator.stopAnimation(nil) self.activityIndicator.isHidden = true self.installButton.isEnabled = true }, onNeedsApproval: { self.logger.info("Extension needs user approval") self.updateStatus("⏳ Waiting for approval...\nOpen System Settings → Privacy & Security → System Extensions") self.activityIndicator.stopAnimation(nil) self.activityIndicator.isHidden = true } ) OSSystemExtensionManager.shared.submitRequest(request) } func updateStatus(_ message: String) { DispatchQueue.main.async { self.statusLabel.stringValue = message } } } class ExtensionDelegate: NSObject, OSSystemExtensionRequestDelegate { let onSuccess: () -> Void let onError: (Error) -> Void let onNeedsApproval: () -> Void init(onSuccess: @escaping () -> Void, onError: @escaping (Error) -> Void, onNeedsApproval: @escaping () -> Void) { self.onSuccess = onSuccess self.onError = onError self.onNeedsApproval = onNeedsApproval super.init() } func request(_ request: OSSystemExtensionRequest, didFinishWithResult result: OSSystemExtensionRequest.Result) { Logger(subsystem: "com.momentry.markbase.installer", category: "ExtensionDelegate") .info("Request finished with result: \(String(describing: result))") onSuccess() } func request(_ request: OSSystemExtensionRequest, didFailWithError error: Error) { Logger(subsystem: "com.momentry.markbase.installer", category: "ExtensionDelegate") .error("Request failed with error: \(error.localizedDescription)") onError(error) } func requestNeedsUserApproval(_ request: OSSystemExtensionRequest) { Logger(subsystem: "com.momentry.markbase.installer", category: "ExtensionDelegate") .info("Request needs user approval") onNeedsApproval() } func request(_ request: OSSystemExtensionRequest, actionForReplacingExtension existing: OSSystemExtensionProperties, withExtension ext: OSSystemExtensionProperties) -> OSSystemExtensionRequest.ReplacementAction { Logger(subsystem: "com.momentry.markbase.installer", category: "ExtensionDelegate") .info("Replacing extension \(existing.bundleIdentifier) with \(ext.bundleIdentifier)") return .replace } }