简体   繁体   English

使用 Python 识别 Mac OS X 中的包目录

[英]Identify directories that are packages in Mac OS X with Python

The Mac OS X Finder uses the concept of "packages" to make the contents of certain folders opaque to the user. Mac OS X Finder 使用“包”的概念来使某些文件夹的内容对用户不透明。 I'm using os.walk() to enumerate a directory tree and I want to skip enumeration on packages such as application bundles.我正在使用os.walk()来枚举目录树,我想跳过对应用程序包等包的枚举。

The mdls commandline utility can be used to check whether com.apple.package is in the kMDItemContentTypeTree attribute. mdls命令行实用程序可用于检查com.apple.package是否在kMDItemContentTypeTree属性中。 Is the only/best way to detect whether a folder is a package to drop into os.system and use mdls after detecting that the OS is indeed darwin?在检测到操作系统确实是达尔文之后,检测文件夹是否是放入os.system并使用mdls的包的唯一/最佳方法是什么?

As an aside, this solution seems to depend on Spotlight metadata which I understand is populated from the files/directories themselves.顺便说一句,这个解决方案似乎依赖于 Spotlight 元数据,我理解它是文件/目录本身填充的。 This makes me wonder whether there is a method to check whether a directory is a package outside of mdls .这让我想知道是否有一种方法可以检查目录是否是mdls之外的mdls Perhaps I'm missing something.也许我错过了一些东西。

OS X packages (and bundles) are usually defined by their extension. OS X 包(和包)通常由它们的扩展名定义。 Simply create a directory with an .app extension to see it be presented as a (broken) application in the Finder.只需创建一个带有.app扩展名的目录,即可看到它在 Finder 中显示为(损坏的)应用程序。

The official documentation lists the following ways to define bundles: 官方文档列出了以下几种定义bundle的方式:

The Finder considers a directory to be a package if any of the following conditions are true:如果满足以下任一条件,则 Finder 会将目录视为包:

  • The directory has a known filename extension: .app, .bundle, .framework, .plugin, .kext, and so on.该目录具有已知的文件扩展名:.app、.bundle、.framework、.plugin、.kext 等。
  • The directory has an extension that some other application claims represents a package type;该目录有一个扩展名,其他一些应用程序声称该扩展名代表了一种包类型; see “Document Packages.”请参阅“文档包”。
  • The directory has its package bit set.该目录设置了它的包位。

The preferred way to specify a package is to give the package directory a known filename extension.指定包的首选方法是为包目录指定一个已知的文件扩展名。 For the most part, Xcode takes care of this for you by providing templates that apply the correct extension.在大多数情况下,Xcode 会通过提供应用正确扩展名的模板来为您处理这个问题。 All you have to do is create an Xcode project of the appropriate type.您所要做的就是创建一个适当类型的 Xcode 项目。

The simplest way to detect packages then is to detect those extensions.检测包的最简单方法是检测这些扩展。 The quick and dirty way is to simply look for a hard-coded list of extensions, using the above documentation as your guide.快速而肮脏的方法是简单地查找硬编码的扩展列表,使用上述文档作为您的指南。

The next step up is to query the OS if a given extension has been registered as a Document Package.下一步是查询操作系统是否已将给定扩展注册为文档包。 See How to check whether directories with a given extension are shown by the Finder as a package?请参阅如何检查 Finder 是否将具有给定扩展名的目录显示为包?

To detect the package bit on directories, you'll have to use the xattr library to retrieve the u'com.apple.FinderInfo' key and then use the Finder.h header info to decode the binary data returned;要检测目录上的包位,您必须使用xattr来检索u'com.apple.FinderInfo'键,然后使用Finder.h头信息解码返回的二进制数据; the kHasBundle flag is 0x2000: kHasBundle标志是 0x2000:

attrs = xattr.getxattr('/path/to/dir', u'com.apple.FinderInfo')
ispackage = bool(ord(attrs[8]) & 0x20)  # I *think* this is correct; works for hidden dirs and & 0x40

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM