Mac OS X 如何运行应用程序包?
Posted
技术标签:
【中文标题】Mac OS X 如何运行应用程序包?【英文标题】:How does Mac OS X run app bundles? 【发布时间】:2013-06-16 19:30:08 【问题描述】:我正在使用py2app
捆绑一个 Mac 应用程序,并试图弄清楚它是如何工作的。根据阅读Bundle Programming Guide,CFBundleExecutable
似乎是必需的密钥,这是 OSX 用来确定要运行 MacOS
子文件夹中的哪个文件的密钥。但是,我将我的 Info.plist
文件剥离为以下内容,并且应用程序加载得很好:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PyMainFileNames</key>
<array>
<string>__boot__</string>
</array>
<key>PyRuntimeLocations</key>
<array>
<string>@executable_path/../Frameworks/Python.framework/Versions/2.7/Python</string>
</array>
</dict>
</plist>
怎么会这样?鉴于确切的plist
文件,OSX 如何加载我的应用程序?
【问题讨论】:
【参考方案1】:CFBundleExecutable
键是必需的,因为您确实应该拥有它,但 CoreFoundation 会尽力处理它的缺失。通过looking at the source of CFBundle,我们可以了解它是如何处理这个密钥的:
static CFStringRef _CFBundleCopyExecutableName(CFBundleRef bundle, CFURLRef url, CFDictionaryRef infoDict)
CFStringRef executableName = NULL;
// …
if (infoDict)
// Figure out the name of the executable.
// First try for the new key in the plist.
executableName = (CFStringRef)CFDictionaryGetValue(infoDict, kCFBundleExecutableKey);
// Second try for the old key in the plist.
if (!executableName) executableName = (CFStringRef)CFDictionaryGetValue(infoDict, _kCFBundleOldExecutableKey);
if (executableName && CFGetTypeID(executableName) == CFStringGetTypeID() && CFStringGetLength(executableName) > 0)
CFRetain(executableName);
else
executableName = NULL;
if (!executableName && url)
// Third, take the name of the bundle itself (with path extension stripped)
因此您可以看到他们按顺序查找以下内容:
-
CFBundleExecutable 键。
NSExecutable 键,一个早于 OS X 公共测试版的旧名称。
如果两者都不存在,则回退到使用已删除路径扩展名的包名称。
在确定了可执行文件名之后,找到它所在目录的方式同样充满了怪癖。我将把发现这些作为练习留给感兴趣的各方。
【讨论】:
哦,太棒了!不知道我可以去寻找源头。由于我的包被称为foo
,而可执行文件也被称为foo
,看来案例#3 是让它工作的原因。现在的问题是:如果我包含名称,为什么它不显示窗口,但如果我不包含它...以上是关于Mac OS X 如何运行应用程序包?的主要内容,如果未能解决你的问题,请参考以下文章
苹果电脑 MAC OS X 怎样解压 分卷压缩 文件 如何解压分段压缩文件