以编程方式制作 mac 包/捆绑包

问题描述 投票:0回答:4

通过终端,您可以使用命令 -“SetFile -a B 文件名”

以编程方式我认为我应该通过设置其中一个属性 [[NSFileManager defaultManager] createDirectoryAtPath:dirPath withIntermediateDirectories:NO 属性:属性错误:nil];

但我找不到哪一个。

谢谢

objective-c cocoa macos filesystems
4个回答
12
投票

编辑:这个答案现在已经过时了。请参阅 @luna-razzaghipourthis 解决方案。

原答案:

能够以编程方式设置捆绑位仍然很有用,例如 iPhoto 这样做可以使 iPhoto Library 文件夹显示为单个文件。

您可以使用 Carbon 文件管理器 API 以编程方式设置捆绑位。您需要确保您的应用程序链接到 Carbon 框架并导入

<Carbon/Carbon.h>
标头。这些调用是 64 位安全的。

- (void)setBundleBitOfFile:(NSString*)path toBool:(BOOL)newValue
{
    const char* pathFSR = [path fileSystemRepresentation];
    FSRef ref;
    OSStatus err        = FSPathMakeRef((const UInt8*)pathFSR, &ref, /*isDirectory*/ NULL);

    if (err == noErr)
    {
        struct FSCatalogInfo catInfo;
        union FinderInfoTransmuter finderInfoPointers = { .bytes = catInfo.finderInfo };

        err = FSGetCatalogInfo(&ref,
                               kFSCatInfoFinderInfo,
                               &catInfo,
                               /*outName*/ NULL,
                               /*FSSpec*/ NULL,
                               /*parentRef*/ NULL);

        if (err == noErr)
        {
            if (newValue)
                finderInfoPointers.finderInfo->finderFlags |=  kHasBundle;
            else
                finderInfoPointers.finderInfo->finderFlags &= ~kHasBundle;

            FSSetCatalogInfo(&ref,
                             kFSCatInfoFinderInfo,
                             &catInfo);
        }
    }
}

- (BOOL)bundleBitOfFile:(NSString*)path
{
    BOOL value          = NO;

    const char* pathFSR = [path fileSystemRepresentation];
    FSRef ref;
    OSStatus err        = FSPathMakeRef((const UInt8*)pathFSR, &ref, /*isDirectory*/ NULL);

    if (err == noErr)
    {
        struct FSCatalogInfo catInfo;
        union FinderInfoTransmuter finderInfoPointers = { .bytes = catInfo.finderInfo };

        err = FSGetCatalogInfo(&ref,
                               kFSCatInfoFinderInfo,
                               &catInfo,
                               /*outName*/ NULL,
                               /*FSSpec*/ NULL,
                               /*parentRef*/ NULL);

        if (err == noErr)
        {
            value = (BOOL)(((finderInfoPointers.finderInfo->finderFlags) & kHasBundle) == kHasBundle);
        }
    }

    return value;
}

5
投票

你想做什么?

几乎所有 Mac OS X 捆绑包实际上都是文件夹,其中的文件/文件夹布局非常具体。 捆绑包很少只是一个文件——它们确实存在,但并不常见。

在大多数情况下,文件上的 Bundle 位完全不相关。

我想将文件夹设置为捆绑包。所以通过文件系统它看起来就像一个文件。后来想用我的应用程序打开该包。问题是如何通过cocoa设置文件夹bundle属性。

您确实不需要设置捆绑位。 只要您的文件夹有扩展名(它应该)并且您的应用程序正确配置为打开该扩展名的文件/文件夹,它就应该像文件一样出现在查找器中。

示例:

  1. 前往 Finder 中的 ~/桌面

  2. 在终端中,执行:

  3. cd ~/Desktop

  4. mkdir aafoo

  5. mv aafoo aafoo.rtfd

在 (4) 之后,您将看到“aafoo”作为文件夹显示在 Finder 中。

在(5)之后,'aafoo'将变成一个TextEdit文档。 不需要属性位。


好吧——很公平。 你真的很想设置那个位。

鉴于您有命令行来执行此操作,我建议简单地使用NSTask。 这可能比使用 API 更容易。


4
投票

您没有设置捆绑属性。 您可以在应用程序的 Info.plist 文件中定义文档类型,并在此处指定文档是包还是纯文件。

您可以在 Xcode 中通过在应用程序目标上选择“获取信息”来执行此操作;切换到“属性”选项卡,然后在“文档类型”下添加一个文档,为其命名,设置其文件扩展名,选择一个图标文件,然后选中“包”复选标记。


2
投票

谢谢大家的帮助。我将解决方案与 info.plist 文件一起使用。 这是 plist 文件的一部分。

<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeName</key>
        <string>Project</string>
        <key>LSHandlerRank</key>
        <string>Default</string>
        <key>LSTypeIsPackage</key>
        <true/>
        <key>CFBundleTypeExtensions</key>
        <array>
            <string>fbp</string>
        </array>
        <key>CFBundleTypeIconFile</key>
        <string>document</string>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
    </dict>
</array>
© www.soinside.com 2019 - 2024. All rights reserved.