现在的位置: 首页 > 综合 > 正文

OSX: 读书笔记-Plist偏好配置文件编程-附用Python访问

2013年12月27日 ⁄ 综合 ⁄ 共 3079字 ⁄ 字号 评论关闭


总之,根据希望存取的偏好作用域,选择正确的API函数,并指定作用域,以及存取偏好值对的值,最后根据需要进行同步操作。

一般概念:

Plist偏好配置文件的作用域,相关于三个方面的因素,App, Host, 和 User,这个列表给出一个完全的作用域列表:

1 Current User Current App Current Host
2 Current User Current App Any Host
3 Current User Any App Current Host
4 Current User Any App Any Host
5 Any User Current App Current Host
6 Any User Current App Any Host
7 Any User Any App Current Host
8 Any User Any App Any Host

比如,针对某个特定的软件作用于:

  • A) 当前主机中的当前用户 (Current host / Current user)
  • B) 针对特定主机的网络中的所有用户 (Specific host / Any users)
  • C) 任一主机中当前用户 (Any host / Current user)
  • D) 网络中任意主机的所有用户 (Any host / Any users)
默认的作用域是“C) 当前用户的任意主机(Current host / Current user)”

一般原则:
两套APIs,高层APIs和底层APIs.

对于默认作用域(=C),读取使用CFPreferencesCopyAppValue, 改变/设置使用CFPreferenceSetAppValue.
对于使用可管理的Plist网络中,管理员可以使用Worgroup Manager来强制用户偏好的实施,CFPreferencesCopyAppValue会服从这种强制措施并得到正确的值。要想确认一个值的状态,可以使用CFPreferencesAppValueIsForced来确认。

对于作用域B (特定主机的所用用户),需要使用底层APIs,比如:改变/设置CFPreferencesSetValue,使用CFPreferencesCopyValue来得到。

必要时,也就是在程序之外需要使偏好配置的改变应用到程序时,使用CFPreferencesSynchronize和CFPreferencesAppSynchronize,但是它们会造成系统的开销。

为了得到每个作用域的目录,应该使用NSSearchPathForDirectoriesInDomains的APIs得到,而不要在程序中硬编码设置。

应用程序标示(Application IDs):
每个程序都有各自的标识(App IDs),这个就其实就是Bundle ID, 类似Java的规范,根据规范它看上去类似:com.apple.Finder。程序的偏好配置文件名使用的就是程序ID,所以Finder的就是com.apple.Finder.plist。参见Bundle
Programming Guide
,为什么是Bundle?因为每个OS X 的App都是Bundle.

作用域标识:
当使用底层API(CFPreferencesSetValue/CFPreferencesCopyValue)时,可以制定每个作用域,作用域标识需要使用:
  • kCFPreferencesAnyApplicaion
  • kCFPreferencesAnyHost
  • kCFPreferencesAnyUser
  • kCFPreferencesCurrentApplication
  • kCFPreferencesCurrentHost
  • kCFPreferencesCurrentUser
当使用CFPreferencesSetAppValue / CFPreferencesCopyAppValue时,在制定程序标识时,只能使用kCFPreferencesCurrentApplication或者一程序标识(如:"com.apple.Finder")。

对于举例,可以参见后面的参考部分。
APIs列表:
所有的可用API都可以在Preferences
Utilities Reference
找到。


Plist文件编程:
Plist文件在OS X系统中被广泛应用,主要是程序配置文件、用户配置、或者系统配置。而上面所说的偏好配置,就是它的一个具体应用。
它支持的值类型有:CFString, CFNumber, CFBoolean, CFDate, CFData, CFArray, and CFDictionary
对于Plist文件的编程总揽:可参见:Property List Programming
Topics for Core Foundation

对于Plist文件的编程,可参见:Property List
Programming Guide

Python存取举例:

感谢Apple的PyObjC,以及它的内置CoreFoundation的支持,让我们可以无障碍地使用Python来对CoreFoundation编程,就如同使用Object-C一样地,使用上面所提到的各个API来达到相同的目的。

#!/usr/bin/python

import CoreFoundation

ManagedPlugInPolicies = {
"com.macromedia.Flash Player.plugin": {
"PlugInDisallowPromptBeforeUseDialog": True,
"PlugInFirstVisitPolicy": "PlugInPolicyAllowWithSecurityRestrictions",
},
}

CoreFoundation.CFPreferencesSetAppValue("ManagedPlugInPolicies", ManagedPlugInPolicies, "com.apple.Safari"
)
CoreFoundation.CFPreferencesAppSynchronize("com.apple.Safari") 

#!/usr/bin/env python
# --------------------------
# This script run like mcxquery to check if a preference key is MCX managed.
# How to use: thisApp App_IDs Keyname
# for example:
#./effective_defaults com.apple.screensaver askForPassword
#
# ---------------------------
import sys
import CoreFoundation
preferenceDomain = sys.argv[1]
keyName = sys.argv[2]
print CoreFoundation.CFPreferencesCopyAppValue(keyName, preferenceDomain)
if CoreFoundation.CFPreferencesAppValueIsForced(keyName, preferenceDomain):
    print "*** %s is managed always by MCX ***" % keyName

上面的代码来源于网络,仅供参考。


更多的脚本学习参考:MacEnterprise: System Framework Scripting,pyMacAdmin



抱歉!评论已关闭.