2007年01月03日 16:00 来源:ChinaUnix文档频道 作者:HonestQiao 编辑:周荣茂

级别: 初级

 

赵 俊 (junzhao@cn.ibm.com), IBM中国软件开发中心,高级软件工程师

2007 年 1 月 04 日

本文讨论了 GNOME2 桌面系统中基于 MIME 类型的应用程序集成的两种方法。在 GNOME2.8 前,GNOME2 使用自己的 MIME 定义方法来集成应用程序;从 2.8 开始,GNOME2 采用了 XDG(X Desktop Group) 提出的 MIME 数据库规范来集成应用程序。在介绍这两种方法的同时,本文也针对这两种方法,介绍了开发实践中的经验与技巧。本文适用于 LINUX 应用程序的开发人员。

概述

当用户安装一个 GNOME 图形界面应用程序时,应用程序需要使自己集成到 GNOME桌面系统中。这种集成包括以下几个方面:

1.注册应用程序到 GNOME 桌面系统。新的应用程序注册到GNOME 程序菜单中,这样GNOME 用户可以通过 GNOME 菜单来启动这个应用程序或使用这个应用程序打开某种类型的文件。

2.注册新的 MIME 文件类型,这样 Nautilus 文件管理器就可以辨别文件的类型,在文件夹的视图中用适当的可读的字符串和图标来表示它。

3.建立应用程序和它处理的 MIME 类型的关联。Nautilus 能够在应用程序注册的文件类型的 Open With 菜单中,把这个应用程序作为打开这个文件的缺省程序。

这种应用程序与桌面系统的集成高度依赖桌面系统 MIEM 类型的定义和实现。在GNOME2.8 之前,GNOME 和 KDE 各自采用自己的方式来定义 MIME 类型,同时GNOME2 的每个版本的MIME类型的定义实现都稍有差异,这给GNOME2应用程序的集成带来很大的困难。从GNOME2.8开始,它采用了XDG制定了一系列MIME类型的规范,尽管XDG的有些标准本身还在制定当中,这已经给应用程序的集成带来很大的方便。

本文通过对GNOME2(GNOME2.8和2.8以前的版本)MIME类型的论述给GNOME2应用程序的开发者提供一种集成应用程序到GNOME2桌面系统的实践方法。

下面就从应用程序集成的三个方面分别对GNOME2.8和2.8以前的版本进行讨论。




 


GNOME2.8 之前的程序集成实现方法

注册应用程序到 GNOME 桌面系统

注册应用程序到 GNOME 桌面系统需要两步工作:第一,为应用程序创建一个 .desktop文件。第二,安装到合适的路径下。如果目标路径不存在,则需要创建目标路径,并且设置访问权限为 0700;如果目标路径已经存在,那么应用程序不要改变它的访问权限。同时,应用程序也应该处理由于没有写权限或其他原因导致的不能安装 .desktop 文件的情况,在这种情况下,应该提示用户,然后退出安装。GNOME 从 2.0 到 2.14 一直采用FreeDesktop.org 的 Desktop Entry 标准规定的 .desktop 文件格式。需要注意的是不同的 GNOME 版本对应不同版本的Desktop Entry标准,比如GNOME2.0对应的是Desktop Entry标准版本0.9.4。当前最新的Desktop Entry标准版本为0.9.8。下面的讨论是基于GNOME2.2来进行的。

.desktop文件是个数据文件用来提供应用程序作为一个在菜单中的菜单项的信息。下表列出应用程序的.desktop文件的基本结构。


表1 .desktop文件的基本结构[1]
表1  .desktop文件的基本结构[1] 

域Name、Comment和Icon的值都是和系统的区域设置相关的,它们都支持本地化。它的规则是域的名字加上后缀[区域设置],这里区域设置是区域类型的值。它们必须符合区域设置的标准格式,即语言_国家.编码@修正值(lang_COUNTRY.ENCODING@MODIFIER),这里国家、编码和修正值可以省略。需要注意的是,如果有支持本地化的域出现,那么相应的那个没有区域设置后缀的域也必须存在。

对于多用户安装,也就是用root用户安装,域Icon所指定的图标文件缺省存放目录是/user/share/pixmaps/,推荐的图标尺寸是48X48像素。对于单用户安装,图标文件缺省存放目录是~/.icons/。可以使用Windows图标文件,但必须使用绝对路径。

在Accessability方面,GNOME对有特殊视觉需要的用户提供了几种图标主题,它们包括低对比度图标,高对比度图标,反高对比度图标。这些图标的推荐尺寸也是48X48像素,如果可能的话,也可以同时设计16X16像素大小的图标。对于GNOME2.2,这些特殊主题设计的图标位于下面的目录下。


/usr/share/icons/hicolor/<size>/apps/
/usr/share/icons/HighContrast/<size>/apps/
/usr/share/icons/HighContrastInverse/<size>/apps/
/usr/share/icons/HighContrastLargePrint/<size>/apps/
/usr/share/icons/HighContrastLargePrintInverse/<size>/apps/
/usr/share/icons/LargePrint/<size>/apps/
/usr/share/locolor/<size>/apps/
/usr/share/Locolor/<size>/apps/
/usr/share/LowContrast/<size>/apps/
/usr/share/LowContrastLargePrint/<size>/apps/

最后,也是最重要的一点是把准备好的.desktop文件安装到正确的目录下。对于多用户安装,需要把它安装到/usr/share/applications/目录下;对于单用户,需要把它安装到~/.gnome2/vfolders/applications/目录下。

注册MIME文件类型

应用程序可以使用两种方法在 GNOME2 桌面系统注册 MIME 文件类型。

GNOME2 提供一个文件 /etc/gnome-vfs-mime-magic(GNOME2.2) 来存放不同文件类型的特征内容匹配模式。每个文件类型对应一个 MIME 文件类型的特殊匹配模式,GNOME通过搜索这些特殊模式来确定文件的 MIME 类型。下表列出了特征内容模式匹配的结构。


表2 文件特征内容模式匹配的基本结构[2]
表2  文件特征内容模式匹配的基本结构[2] 

下面是PDF文件格式的探测器,这个探测器将在文件头寻找字符串"%PDF-"的模式匹配。它没有模式掩码,相对应的MIME类型是" application/pdf"。


0	string	%PDF-			application/pdf

所以,应用程序可以通过添加新的文件内容探测器来注册新的MIME文件类型。

另一种方法是通过文件的后缀名来注册新的MIME文件类型。如果GNOME通过文件内容探测器不能判断文件的MIME类型,它就会查询一些 .mime 文件,通过搜索 .mime文件内容中特定的文件名后缀来确定文件的MIME类型。user.mime 的优先级要高于以其它名字,比如应用程序的名字命名的 .mime 文件。在 .mime 文件中,MIME 类型的定义格式如下:


MIME-type
ext: 这种MIME类型的后缀名列表
regex: 规则表达式来匹配文件名

需要注意的是,上面表达式中后缀名列表和规则表达式必须和前面的冒号之间有个空格,否则只有第一个MIME-type的定义生效,它后面的定义将不起作用。这里是file-roller注册的部分MIME类型的表达式例子。


Application/x-tar
Ext: tar
Application/x-compressed-tar
Regex,2: \.tar\.gz$
Regex,2: \.tar\.Z$
Ext: tgz taz

一般来讲可以创建新的.mime文件来注册新的MIME文件类型。同样,对于多用户安装,GNOME会去/usr/share/mime-info/目录下搜索;对于单用户安装,则需要把这些.mime文件安装到~/.gnome/mime-info/目录下。

利用这些.mime文件,在GNOME桌面系统注册新的MIME文件类型,GNOME就可以认识它们了。有了.mime文件后,GNOME需要另外一个.keys文件给这个MIME类型建立可读的名字和图标。对于多用户安装和单用户安装.keys文件都和相应的.mime文件在同一个目录下。同样User.keys的优先级要高于以其它名字命名的.keys文件。它的文件格式也和.mime文件相似。下面是file-roller的.keys文件对MIME类型tar和compressed的描述部分。


Application/x-tar
Icon_filename=gnome-compressed
Short_list_application_ids_for_novice_user_level=file-roller
Short_list_application_ids_for_intermediate_user_level=file-roller
Short_list_application_ids_for_advanced_user_level=file-roller
Application/x-compressed
Icon_filename=gnome-compressed
Short_list_application_ids_for_novice_user_level=file-roller
Short_list_application_ids_for_intermediate_user_level=file-roller
Short_list_application_ids_for_advanced_user_level=file-roller

File-roller的.keys文件的第一个条目定义了MIME类型Application/x-tar的MIME类型分类为Application,代表这种类型文件的图标文件为gnome-compressed,当在文件管理器中双击这个图标所代表的文件时所用的缺省应用为file-roller。

图标文件的缺省搜索路径为~/.icons/:/usr/share/pixmaps/。对于多用户安装,图标应该存放在/usr/share/pixmaps/目录下,推荐的大小是48X48。对于单用户安装,存放图标的目录是~/.icons/。[3]

Short_list_application条目所指定的应用程序必须是已经在GNOME桌面系统中注册过的,所以,还需要一个文件来注册应用程序。这就是下面要讨论的应用程序集成的第三步注册应用程序。

注册应用程序

注册应用程序建立了应用程序和它处理的MIME类型文件的关联。应用程序注册文件是.applications文件。对于多用户,应该把它安装到/usr/share/gnome/application-registry目录下;对于单用户,应该安装到~/.gnome/application-info/目录下。下面列出file-roller的.applications文件部分内容。


file-roller
         command=file-roller
         name=File Roller
         can_open_multiple_files=true
         expects_terminal=false
         mime_type=application/x-tar,application/x-compressed-tar…

第一行是应用程序在注册体系中的标识,它们对应.keys文件中那些Short_list_application条目所指定的应用程序的标识。"command"域指定了激活应用程序所需要的命令行,包括打开文件所需要的参数。"name"域是出现在Open With菜单中应用程序的名字。"expects_uris"域让Nautilus知道这个应用程序是否接受uris。例如Mozilla能够接受在命令行中用http:、 ftp: 等uris打开文件。如果这个域的值为真,则需要一个supported_uri_schemes条目来列出应用程序所支持的uri配置。一般来讲,域" expects_terminal"的值为假,因为大多数的应用程序不需要在终端中运行。"mime_types"列出所有这个应用程序所支持的MIME类型。

GNOME2.8前的程序集成实例

下面介绍在GNOME2.2上集成单用户安装IBM Lotus Notes的示例。与Notes相关联的文件类型为application/x-nsf和application/x-ntf两种。

1) 安装下面的notes.desktop文件到~/.gnome2/vfolders/applications/目录下。


[Desktop Entry]
Version=7.0
Encoding=UTF-8
Name=IBM Lotus Notes
Type=Application
Exec=/home/junzhao/IBM/Lotus/notes
Icon=~/.icons/notes.png
Terminal=false
Categories=Core

2) 安装 Lotus Notes 应用程序的图标文件 notes.png 到 ~/.icons 目录下。 完成这两步后,可以在 GNOME 应用程序面板上看到 IBM Lotus Notes(见图1)。


图1:应用程序面板上的 Notes 图标
图 1:应用程序面板上的 Notes 图标 

3) 安装下面的 notes.mime 文件到 ~/.gnome/mime-info/ 目录下。


application/x-nsf
	ext: nsf
application/x-ntf
	ext: ntf
	

4) 安装下面的 notes.keys 文件到 ~/.gnome/mime-info/ 目录下。


application/x-nsf
	description=IBM Lotus Notes NSF file
	icon_filename=notes
	default_action_type=application
	short_list_application_ids_for_novice_user_level=IBM Lotus Notes
application/x-ntf
	description=IBM Lotus Notes NTF file
	icon_filename=notes
	default_action_type=application
	short_list_application_ids_for_novice_user_level=IBM Lotus Notes
	

5)安装 .nsf/ntf 文件类型的图标文件到 ~/.icons 目录下 完成以上三步后,在文件夹中,能够显示.nsf/ntf文件的描述信息。重新登陆后就可以看到文件夹中,nsf/ntf 的图标更新为 IBM Lotus Notes 的图标(见图2)。

6) 安装 notes.applications 文件到 ~/.gnome/application-info/ 目录下。现在 Nautilus 可以在 .nsf/.ntf 的 Open With 菜单中指定 Lotus Notes 做为它的缺省应用程序(见图 2)。


	
IBM Lotus Notes
	command=/home/junzhao/ IBM/Lotus/notes
	Name=IBM Lotus Notes
	can_open_multiple_files=true
	expects_uris=false
	mime_types=application/x-nsf,application/x-ntf
	


图 2:文件夹视图中的 nsf/ntf 文件和 Open With 菜单
图 2:文件夹视图中的 nsf/ntf 文件和 Open With 菜单 



 


GNOME2.8 及之后的程序集成实现方法

从 GNOME2.8 开始,在MIME类型的实现方法上最大的变化是 GNOME 采用了 XDG 提出的两个规范,XDG 共享 MIME 信息规范(shared mime info specification)和 XDG 基本目录规范(base directory specification)。这两个规范很大程度上解决了以前版本的主要问题,即不同的版本要求相应的MIME文件的缺省路径不同,并且没有明确的文档说明,这给应用程序的集成实现带来很大的困难。同时,采用这些标准也统一了程序集成的实现方法,使之在GNOME的不同版本间,甚至是与KDE桌面系统兼容。

XDG 基本目录规范

XDG基本目录规范定义了五个重要的环境变量。这些环境变量统一了所有相关MIME文件的位置。

$XDG_DATA_HOME:定义了用户相关的数据文件的基路径。如果这个变量为空,或没有定义,缺省路径$HOME/.local/share将被使用。

$XDG_CONFIG_HOME:定义了用户相关的配置文件的基路径。如果这个变量为空,或没有定义,缺省路径为$HOME/.config。

$XDG_DATA_DIRS:定义了除了$XDG_DATA_HOME外数据文件的搜索路径。超过一个的搜索路径用冒号分隔。如果这个变量为空,或没有定义,缺省路径为/usr/local/share/:/usr/share/。

$XDG_CONFIG_DIRS:定义了除了$XDG_CONFIG_HOME外的配置文件的搜索路径。超过一个的搜索路径用冒号来分隔。如果这个变量为空,或没有定义,缺省路径为/etc/xdg/。

$XDG_CACHE_HOME:定义了用户相关的非必须的数据的搜索路径。如果这个变量为空,或没有定义,缺省路径为$HOME/.cache。[4]

XGD共享MIME信息规范

XGD共享MIME信息规范定义了MIME数据库的标准。MIME数据库由一系列文件组成,这些文件定义了以知的MIME类型、决定文件MIME类型的方法、关于MIME类型的信息,比如文件可读的描述及图标。希望更改或增加MIME数据库的MIME类型的应用程序应该在特定的路径下安装一个XML文件。这个路径为XDG_DATA_HOME:XDG_DATA_DIRS/mime/packages/。无论是安装、卸载还是更改这个文件,应用程序都应该运行update-mime-database命令来更新MIME数据库。update-mime-database的唯一参数是含有packages/*.xml文件的mime路径。例如,应用程序的XML文件安装在~/.local/share/mime/packages/example_app.xml,那么应该运行update-mime-database ~/.local/share/mime/。这个命令将扫描~/.local/share/mime/packages/下所有子目录的XML文件,然后生成一批文件,这些文件就是所谓的MIME数据库。当packages目录下存在多个XML文件,并且存在信息冲突时,以更深层次目录的XML文件为准,如果存在文件Override.xml,以它提供的信息为准。[5]

这个 XML 文件的文档元素名为 mime-info,namespaceURI 为 http://www.freedesktop.org/standards/shared-mime-info。文档元素可以含有零个或多个 mime-type 的子结点,每个子结点都描述了一种 MIME 类型。每个 mime-type 结点可以含有下列元素以任何顺序的任何组合。

glob 元素用来根据文件的后缀名来决定文件的 MIME 类型,它的属性是 pattern,如果文件的后缀名与这个 pattern 匹配,这个文件就属于这个结点定义的 MIME 类型。

magic 元素用来根据文件的内容来决定文件的 MIME 类型,它含有一些 match 元素和一个可选项属性 priority。这个属性对所有的 match 元素起作用。通用的类型使用较小的值;具体的子类型使用较大的值。缺省值为 50,最大值为 100。每个 match 元素有一些和前面讲过的文件特征内容模式匹配相似的属性,具体的属性在下表列出。


表3 magic元素的属性[6]
表3  magic元素的属性[6] 

alias元素表示除了属性type指定的类型名字,它还有其它的别名。

sub-class-of元素表明这个MIME类型的文件同时也是这个元素所指定的MIME类型。例如,所有的p_w_picpath/svg文件也都是text/xml,text/plain和application/octet-stream文件。有些文件类型的这种Sub-class-of关系是不言而喻的,比如所有的text/*类型都是text/plain类型。

comment元素定义了MIME类型的可读的文字描述。可以用属性xml:lang支持多语言。 root-XML元素有两个属性namespaceURI和localName。如果文件被识别为是XML文件,那么可以根据文件文档元素的namespce和localname来进一步判断它更具体的MIME类型。Localname是文档的根元素的名字。

下面是file-roller在GNOME2.12的XML文件的部分内容。可以到/usr/share/mime/packages/下阅读整个文件。


<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<!-- Most MIME types are already present in freedesktop.org.xml, but not all. -->
  <mime-type type="application/x-rar">
    <glob pattern="*.rar" />
  </mime-type>
  <mime-type type="application/x-gzip">
    <glob pattern="*.gz" />
  </mime-type>
</mime-info>

运行update-mime-database会产生下列MIME数据库文件:

XDG_DATA_HOME:XDG_DATA_DIRS/mime/globs:含有从名字到MIME类型的对应。

XDG_DATA_HOME:XDG_DATA_DIRS/mime/magic:含有从文件内容到MIME类型的对应。

XDG_DATA_HOME:XDG_DATA_DIRS/XMLnamespaces:含有XML项到MIME类型的对应。

XDG_DATA_HOME:XDG_DATA_DIRS/MEDIA/SUBTYPE.xml:MIME类型的具体信息。MEDIA指MIME类型的类别,一般为application,SUBTYPE一般为x-***。

基于MIME数据库的应用程序集成的实现

有了MIME数据库,就等于完成了前面提到的应用程序集成的第二和第三方面:注册MIME文件类型和建立应用程序和它处理的MIME类型的关联。为了完成应用程序集成只剩下一步:注册应用程序到GNOME桌面系统。首先创建.desktop文件,它的格式和在前面介绍的GNOME2.8之前的实现方法介绍的一样。创建.desktop文件后,根据XDG base directory specification,对多用户安装,需要安装到$XDG_DATA_DIRS/applications目录下,如果$XDG_DATA_DIRS值为空,使用缺省路径/usr/share/applications。对于单用户安装,需要安装到$XDG_DATA_HOME/applications目录下,如果$XDG_DATA_HOME值为空,使用缺省路径~/.local/share/applications。创建或修改.desktop文件后,需要运行update-desktop-database命令以生成mimeinfo.cache。[7]

最后,通过创建或修改defaults.list文件来指定这种MIME类型文件的缺省应用程序。defaults.list存在与$XDG_DATA_HOME/applications/或$XDG_DATA_DIRS/applications/。下面是一个defaults.list的例子。


[Default Applications]
application/pdf=evince.desktop
text/html=firefox.desktop
text/plain=gedit.desktop
p_w_picpath/jpeg=eog.desktop

GNOME2.8及之后的程序集成实例

下面介绍在GNOME2.12上集成单用户安装的Lotus Notes的示例。

1) 创建并安装notes.desktop文件到~/.local/share/applications。它的内容和前面的实例中的notes.desktop一样。

2) 安装Lotus Notes应用程序的图标文件到~/.icons/目录下。

3) 运行update-desktop-database命令生成mimeinfo.cache。

完成这三步后,可以在GNOME应用程序面板上看到IBM Lotus Notes(见图3)。


图3:GNOME2.12 应用程序面板上的IBM Lotus Notes应用
图3:GNOME2.12 应用程序面板上的IBM Lotus Notes应用 

4) 创建并安装下面notes.xml文件到~/.local/share/mime/packages/目录下。


<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="application/x-extension-nsf"><comment>nsf document</comment><glob pattern="*.nsf"/></mime-type>
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error:  The previous line is longer than the max of 90 characters ---------|
<mime-type type="application/x-extension-ntf"><comment>nsf document</comment><glob pattern="*.ntf"/></mime-type>
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error:  The previous line is longer than the max of 90 characters ---------|
</mime-info>

5) 运行update-mime-database ~/.local/share/mime/命令生成MIME数据库。

6) 创建并安装下面的defaults.list文件到~/.local/share/applications目录下。


[Default Applications]
application/x-nsf=notes.desktop
application/x-ntf=notes.desktop


图4:GNOME2.12文件夹视图中的nsf/ntf文件和Open With菜单
图4:GNOME2.12文件夹视图中的nsf/ntf文件和Open With菜单 



 


结论

由于GNOME2不同版本桌面系统的MIME类型定义实现方法有较大的变化,所以在开发GNOME2应用程序与桌面系统集成时要注意GNOME不同版本的兼容。通过本文的讨论,读者可以获得在GNOME2桌面系统中集成应用程序的全面参考,从而帮助读者减少应用程序与GNOME桌面系统集成的开发时间。