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

Swift5沙箱化macOS应用执行外部脚本路径不可访问问题

macOS沙箱应用中Process执行shell脚本报"launch path not accessible"错误

在启用沙箱的macOS应用中,通过Process()执行用户选择的shell脚本时遇到**"launch path not accessible"**错误。已在权限配置文件中开启com.apple.security.app-sandbox,并添加com.apple.security.files.user-selected.read-write权限,但问题依旧。关闭沙箱后脚本执行正常,由于App Store要求应用必须沙箱化,恳请提供解决思路。

相关Swift代码

import SwiftUI

struct ContentView: View {
  var body: some View {
    VStack {
      Button("grant access") {
        chooseFile()
      }
    }
  }
  
  func chooseFile() {
    print(">>>>>>>> choose file start")
    let dialog = NSOpenPanel()
    
    dialog.title = "grant access"
    dialog.canChooseFiles = true
    
    print(">>>>>>>> opening dialog")
    if dialog.runModal() == .OK {
      if let filePath = dialog.url {
        print(">>>>>>>> selected file: \(filePath.path)")
        grantAccess(url: filePath)
        exec(url: filePath)
      }
    }
  }
  
  func grantAccess(url: URL) {
    do {
      let data = try url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
      UserDefaults.standard.set(data, forKey: "bookmarkKey")
      print(">>>>>>>> grant access success")
    } catch {
      print(">>>>>>>> grant access failed: \(error)")
    }
  }
  
  func exec(url: URL) {
    
    if url.startAccessingSecurityScopedResource() {
      print(">>>>>>>> url.startAccessingSecurityScopedResource: true")
    } else {
      print(">>>>>>>> url.startAccessingSecurityScopedResource: false")
    }

    let task = Process()
    let pipe = Pipe()
    let launchPath = url.path()
    print(">>>>>>>> launchPath: \(launchPath)")
    
    task.standardOutput = pipe
    task.standardError = pipe
    task.launchPath = launchPath
    
    print(">>>>>>>> before task.launch()")
    task.launch()
    print(">>>>>>>> after task.launch()")
    
    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    if let output = String(data: data, encoding: .utf8) {
      print(output)
    }
    
    url.stopAccessingSecurityScopedResource()
  }
}

权限配置文件内容

<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>

沙箱开启时运行输出

2023-05-18 18:10:08.646588+0800 GrantAccess[79410:26642970] Metal API Validation Enabled
>>>>>>> choose file start
>>>>>>> opening dialog
2023-05-18 18:10:09.562084+0800 GrantAccess[79410:26642970] +[CATransaction synchronize] called within transaction
>>>>>>> selected file: /Users/archcst/Desktop/sh.sh
2023-05-18 18:10:10.946571+0800 GrantAccess[79410:26642970] [logging] open flag(s) 0x01000000 are reserved for VFS use and do not affect behaviour when passed to sqlite3_open_v2
2023-05-18 18:10:10.946685+0800 GrantAccess[79410:26642970] [logging-persist] cannot open file at line 46922 of [554764a6e7]
2023-05-18 18:10:10.946715+0800 GrantAccess[79410:26642970] [logging-persist] os_unix.c:46922: (0) open(/private/var/db/DetachedSignatures) - Undefined error: 0
>>>>>>> grant access success
>>>>>>> url.startAccessingSecurityScopedResource: true
>>>>>>> launchPath: /Users/archcst/Desktop/sh.sh
>>>>>>> before task.launch()
2023-05-18 18:10:10.953065+0800 GrantAccess[79410:26642970] [General] launch path not accessible
2023-05-18 18:10:10.956572+0800 GrantAccess[79410:26642970] [General] (
    0   CoreFoundation                      0x0000000190d4b19c __exceptionPreprocess + 176
    1   libobjc.A.dylib                     0x000000019086a4d4 objc_exception_throw + 60
    2   Foundation                          0x0000000191cb6294 -[NSConcreteTask launchWithDictionary:error:] + 4036
    3   GrantAccess                         0x00000001046d9c60 $s11GrantAccess11ContentViewV4exec3urly10Foundation3URLV_tF + 1584
    4   GrantAccess                         0x00000001046d8b70 $s11GrantAccess11ContentViewV10chooseFileyyF + 1908
    5   GrantAccess                         0x00000001046d83f4 $s11GrantAccess11ContentViewV4bodyQrvg7SwiftUI6ButtonVyAE4TextVGyXEfU_yycfU_ + 12
    6   SwiftUI                             0x00000001b9905dd8 block_destroy_helper + 1276
    7   SwiftUI                             0x00000001b990416c OUTLINED_FUNCTION_1 + 23992
    8   SwiftUI                             0x00000001b99041d0 OUTLINED_FUNCTION_1 + 24092
    9   AppKit                              0x0000000194097a50 -[NSApplication(NSResponder) sendAction:to:from:] + 440
    10  AppKit                              0x0000000194097868 -[NSControl sendAction:to:] + 72
    11  AppKit                              0x00000001940977ac __26-[NSCell _sendActionFrom:]_block_invoke + 100
    12  AppKit                              0x00000001940976d4 -[NSCell _sendActionFrom:] + 204
    13  AppKit                              0x00000001940975f8 -[NSButtonCell _sendActionFrom:] + 88
    14  AppKit                              0x0000000194094bfc NSControlTrackMouse + 1480
    15  AppKit                              0x0000000194094608 -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 144
    16  AppKit                              0x00000001940944c0 -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 488
    17  AppKit                              0x000000019409398c -[NSControl mouseDown:] + 448
    18  AppKit                              0x0000000194092474 -[NSWindow(NSEventRouting) _handleMouseDownEvent:isDelayedEvent:] + 3476
    19  AppKit                              0x000000019401d0dc -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 364
    20  AppKit                              0x000000019401cd9c -[NSWindow(NSEventRouting) sendEvent:] + 284
    21  AppKit                              0x000000019401c0e0 -[NSApplication(NSEvent) sendEvent:] + 1556
    22  AppKit                              0x000000019426c0f0 -[NSApplication _handleEvent:] + 60
    23  AppKit                              0x0000000193ee357c -[NSApplication run] + 500
    24  AppKit                              0x0000000193eba9a8 NSApplicationMain + 880
    25  SwiftUI                             0x00000001b8f1d974 OUTLINED_FUNCTION_8 + 8272
    26  SwiftUI                             0x00000001ba07cfa0 OUTLINED_FUNCTION_14 + 188
    27  SwiftUI                             0x00000001b98fe43c OUTLINED_FUNCTION_1 + 136
    28  GrantAccess                         0x00000001046dad5c $s11GrantAccess0aB3AppV5$mainyyFZ + 40
    29  GrantAccess                         0x00000001046dae08 main + 12
    30  dyld                                0x000000019089bf28 start + 2236
)

关闭沙箱后运行输出

2023-05-19 09:52:26.113632+0800 GrantAccess[93821:27259040] Metal API Validation Enabled
>>>>>>> choose file start
>>>>>>> opening dialog
2023-05-19 09:52:27.020965+0800 GrantAccess[93821:27259040] +[CATransaction synchronize] called within transaction
2023-05-19 09:52:28.211853+0800 GrantAccess[93821:27259040] +[CATransaction synchronize] called within transaction
2023-05-19 09:52:29.027746+0800 GrantAccess[93821:27259040] +[CATransaction synchronize] called within transaction
>>>>>>> selected file: /Users/archcst/Desktop/sh.sh
2023-05-19 09:52:30.820140+0800 GrantAccess[93821:27259040] [logging] open flag(s) 0x01000000 are reserved for VFS use and do not affect behaviour when passed to sqlite3_open_v2
2023-05-19 09:52:30.820273+0800 GrantAccess[93821:27259040] [logging-persist] cannot open file at line 46922 of [554764a6e7]
2023-05-19 09:52:30.820306+0800 GrantAccess[93821:27259040] [logging-persist] os_unix.c:46922: (0) open(/private/var/db/DetachedSignatures) - Undefined error: 0
>>>>>>> grant access success
>>>>>>> url.startAccessingSecurityScopedResource: true
>>>>>>> launchPath: /Users/archcst/Desktop/sh.sh
>>>>>>> before task.launch()
>>>>>>> after task.launch()
hello world

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 18:37:01