Macos 应用程序如何以静默方式判断它是否';他在沙箱里跑吗?
我正在写一个应用程序,可以运行沙盒与否 我喜欢让我的代码独立于我以后是否为沙箱进行代码设计,也就是说,我希望在我的代码中(或在构建环境中)有一个常量,我必须更改该常量才能知道它是否为沙箱构建 当然,在某些情况下,我需要在代码中使用不同的API,这取决于应用程序是否是沙盒Macos 应用程序如何以静默方式判断它是否';他在沙箱里跑吗?,macos,sandbox,Macos,Sandbox,我正在写一个应用程序,可以运行沙盒与否 我喜欢让我的代码独立于我以后是否为沙箱进行代码设计,也就是说,我希望在我的代码中(或在构建环境中)有一个常量,我必须更改该常量才能知道它是否为沙箱构建 当然,在某些情况下,我需要在代码中使用不同的API,这取决于应用程序是否是沙盒 所以,我喜欢在我的应用程序中有代码动态检测它是否在沙箱中运行。我喜欢这样做,而不会在控制台日志中收到消息。也就是说,尝试访问沙盒中不可访问的文件不是一个好的解决方案,因为这会导致日志条目,这反过来会激怒我的应用程序的用户,认为有
所以,我喜欢在我的应用程序中有代码动态检测它是否在沙箱中运行。我喜欢这样做,而不会在控制台日志中收到消息。也就是说,尝试访问沙盒中不可访问的文件不是一个好的解决方案,因为这会导致日志条目,这反过来会激怒我的应用程序的用户,认为有问题。正如您所提到的,沙盒中的应用程序是经过代码签名的。您可以通过对“codesign”的命令行调用来检查是否存在此问题 因此,如果您的程序可以使用以下命令调用命令行:-
codesign -d --entitlements :- <path to executable>
如果字符串存在,则运行的可执行文件将被沙盒化。在应用程序启动时,在初始化函数中执行此操作一次,并存储一个标志,以便稍后进行测试
-------编辑----------------
我自己并没有测试过它,但只是遇到了一些代码来检查应用程序是否是沙盒的。完整的代码可以在github上找到
----编辑2--------------
我终于检查了中的代码,并确认它按预期工作。我现在发现了一个更简单的技巧: 我得到了Preferences文件夹的路径。如果它看起来像这样,我就被沙盒包围了:
/Users/<user>/Library/Containers/<bundle_id>/Data/Library/Preferences
/Users//Library/Containers//Data/Library/Preferences
这足够满足我的需要了,我只是想避免看到控制台MSG。如果苹果改变了路径,而我的测试失败了,那么我将看到的最糟糕的消息就是一条关于拒绝操作的控制台消息。我可以接受。我用这个:
// Determine if an application is running in sandboxed mode
func IsSandboxed() -> Bool {
let dir = NSHomeDirectory()
let bundleName: String = NSBundle.mainBundle().bundleIdentifier as String!
if dir.containsString("Library/Containers/" + bundleName) {
return true
}
return false
}
当然,非沙盒代码也可能使用代码签名的可执行文件或库。另请参见。如何获取路径?
// Determine if an application is running in sandboxed mode
func IsSandboxed() -> Bool {
let dir = NSHomeDirectory()
let bundleName: String = NSBundle.mainBundle().bundleIdentifier as String!
if dir.containsString("Library/Containers/" + bundleName) {
return true
}
return false
}
import Foundation // For String/CFString bridging
import Security
if
let task = SecTaskCreateFromSelf(nil),
let value = SecTaskCopyValueForEntitlement(task, "com.apple.security.app-sandbox" as CFString, nil),
let isSandboxed = value as? Bool
{
print("sandbox: \(isSandboxed)")
}