如果应用程序在沙箱中运行,应用程序如何静默告诉?

时间:2013-06-28 17:34:42

标签: macos sandbox

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

我喜欢保持我的代码独立于我是否稍后将其编码为沙盒,即我希望在我的代码(或构建环境)中有一个常量,我必须更改代码以了解是否它是否会为沙箱而建。

当然,我需要在我的代码中使用不同的API,具体取决于应用程序是否为沙盒。

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

4 个答案:

答案 0 :(得分:1)

正如您所提到的,沙盒化的应用程序是代码签名的。您可以通过对'codesign'的命令行调用来检查是否存在此问题。

因此,如果您的程序可以使用以下命令调用命令行: -

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

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

com.apple.security.app-sandbox

如果字符串存在,则运行的可执行文件将被沙箱化。在应用程序启动时的初始化函数中执行此操作一次,并存储一个标记,然后可以测试该标记。

------- EDITED ----------------

我自己没有对它进行过测试,但只是遇到了this article,其中包含检查应用是否为沙盒的代码。完整代码可以在github上找到here

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

我终于检查了aforementioned article中的代码,并确认它按预期工作。

答案 1 :(得分:1)

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

我获得了Preferences文件夹的路径。如果它看起来像这样,我就是沙箱:

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

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

答案 2 :(得分: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)")
    }

答案 3 :(得分: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
}