2

我正在编写一个可以运行沙盒或不运行的应用程序。

我喜欢让我的代码独立于我以后是否为沙箱进行代码设计,即我希望在我的代码(或构建环境)中有一个常量,我必须更改我的代码才能知道它是否会是否为沙箱构建。

当然,在某些情况下,我需要在我的代码中使用不同的 API,具体取决于应用程序是否被沙盒化。

所以,我喜欢在我的应用程序中使用代码来动态检测它是否在沙箱中运行。而且我喜欢这样做而不在控制台日志中收到消息。即,尝试访问在沙箱中无法访问的文件不是一个好的解决方案,因为这会导致日志条目,进而会激怒我的应用程序的用户,认为有问题。

4

4 回答 4

1

正如您所提到的,沙盒化的应用程序是代码签名的。您可以通过命令行调用“codedesign”来检查它是否存在。

因此,如果您的程序可以通过以下方式调用命令行: -

codesign -d --entitlements :- <path to executable>

检索命令的输出并搜索字符串:-

com.apple.security.app-sandbox

如果字符串存在,则正在运行的可执行文件被沙盒化。在应用程序开始时的初始化函数中执行一次,并存储一个标志,然后您可以稍后进行测试。

--------已编辑----

我自己没有测试过,只是偶然发现了这篇文章,其中包含检查应用程序是否被沙盒化的代码。完整的代码可以在 github 上找到

---- 编辑 2 --------------

我终于检查了上述文章中的代码,可以确认它按预期工作。

于 2013-07-01T09:13:11.377 回答
1

我现在发现了一个更简单的技巧:

我得到了 Preferences 文件夹的路径。如果它看起来像这样,我被沙盒化了:

/Users/<user>/Library/Containers/<bundle_id>/Data/Library/Preferences

这足以满足我的需求,我只想避免看到控制台消息。如果 Apple 改变了路径并且我的测试失败了,那么我将看到的最糟糕的情况是控制台消息关于被拒绝的操作。我可以忍受这一点。

于 2013-07-03T08:51:07.770 回答
1
    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)")
    }
于 2020-02-20T19:17:36.653 回答
0

我用这个:

// 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
}
于 2016-01-05T11:18:39.023 回答