Windows 文件关联机制剖析
Windows 文件关联机制剖析
東條・スペンサー・咲 发表于4个月前
Windows 文件关联机制剖析
  • 发表于 4个月前
  • 阅读 19
  • 收藏 0
  • 点赞 1
  • 评论 0

腾讯云 新注册用户 域名抢购1元起>>>   

最近要在Windows下实现文件关联,搜集了很多资料,但是质量太乱了。这里将其汇总一下。

Windows中的文件关联

Windows文件关联是以文件类型为分组,以后缀名为标志的。每种文件类型可以有一个类型描述,Windows中一般称为ProgId(Programmatic Identifiers)。ProgId指示了该类型文件在资源管理器中显示的图标,以及对应打开的程序路径。相同ProId的文件类型可以视为同一组,具有相关的显示图标和相同的打开方式。后缀名与软件的对应是通过ProgId(Programmatic Identifiers)进行的,一个后缀名只能对应一个ProgId,而对应同一个ProgId的后缀名可视为一组。或者说,一个后缀名只能对应一个软件,一个软件可以对应多个后缀。

Windows的文件关联由几部分组成,优先级从最高向下依次是:

  • 打开方式设置:用户通过右键菜单中的打开方式对话框指定的设置,
  • 用户设置:仅适用于一特定用户的设置,可由程序提供,
  • 本机设置(所有用户设置):适用于本机所有用户的设置。

文件关联的实现

Windows通过注册表项来关联特殊后缀的文件以及启动他们的程序。有几个地方会有关联信息:
1、HKEY_LOCAL_MACHINE\Software\Classes:该注册表项包括适用所有用户的默认文件关联设置
2、HKEY_CURRENT_USER\Software\Classes:该注册表项包含只适用当前用户的文件关联设置(它会覆盖HKEY_LOCAL_MACHINE项中的设置)
3、HKEY_CLASSES_ROOT:该注册表项目里面的设置是保证Windows浏览器能够选择正确的应用程序打开相应文件的关键所在。在Windows 2000之后,该注册表项目中的文件关联设置分别存在上面所说的两个注册表项中去了。而HKEY_CLASS_ROOT 注册表项则成为融合(注意,对于相关的文件类型,HKEY_CURRENT_USER下面的设置会覆盖HKEY_LOCAL_MACHINE下面的设置)上面两个注册表项内容的一个镜像。为了更新文件关联设置,你必须更新"HKEY_CURRENT_USER\Software\Classess"或者"HKEY_LOCAL_MACHINE\Software\Classess"下的注册表项,而不是直接更新HKEY_CLASS_ROOT下的注册表项

对于开启UAC的Windows Vista及其后面的版本来讲,还有一个区别是更改本机设置需要管理员权限,而更改当前用户的设置只需要普通权限。

以当前用户设置为例(HKEY_CURRENT_USER),本机设置(HKEY_LOCAL_MACHINE)与用户设置的结构完全一致:

HKEY_CURRENT_USER\Software\Classes
.ext
	(Default) = $YourProgID //任意字符串
	Content Type = $ContentType //可选,HTTP Content Type
	PerceivedType = $PreceivedType //可选,感知类型
	OpenWithProgIds
		(Default) = 空
		$YourProgID = 空
	PersistentHandler //可选
		(Default) = {xxx} //CLSID
$YourProgID //与上面的值对应
	(Default) = $Description //可选,对该文件类型的描述
	DefaultIcon
		(Default) = yourAppPath.exe,1 //可选,文件应当显示的图标
	shell
		open
			command
				(Default) = yourAppPath.exe %1 //打开该文件的命令行参数
		edit
			command
				(Default) = yourAppPath.exe %1 //编辑该文件的命令行参数
		preview
			command
				(Default) = yourAppPath.exe %1 //预览该文件的命令行参数
		printto
			command
				(Default) = yourAppPath.exe %1 //打印该文件的命令行参数

下面将对其中的几个键值进行说明

HTTP Content Type

这个在HTTP请求头里面非常常见,例如文本文件为text/plain,可以在OSC的在线工具查询(在此感谢OSC提供的速查列表,帮大忙了)。

感知类型(PerceivedType)

感知类型是能够让Windows识别的一组文件格式,例如图像类、音频类、文档类。这个键值允许Windows根据其感知类型进行不同的操作,例如一个文件夹的图标,当它是空的时候和当它含有文件的时候,预览的图标可以用两种形式进行显示。这个操作是通过感知类型键值来进行识别并且处理的。

默认的感知类型有以下几种:

  • Folder(文件夹)
  • Text(文本文件)
  • Image(图像文件)
  • Audio(音频文件)
  • Video(视频文件)
  • Compressed(压缩文件)
  • Document(文档文件)
  • System(系统文件)
  • Application(应用程序文件)
  • Gamemedia(游戏、媒体文件)
  • Contacts(联系人文件)

永久句柄(PersistentHandler)

这个键值我没有进行深入的研究,大部分软件用的非常少。在我这里的话,Visual Studio注册的部分使用了这个键值。按照官网的解释,应该是为过滤器准备的。但是在没有明确的功能描述。

如果有人愿意去研究一下的话,这里提供两个链接:一个是Persistent Handlers (Windows)、另一个是Registering Filter Handlers (Windows)

打开、编辑、预览、打印(Open、Edit、Preview、Printto)

打开,顾名思义,就是指当用户在资源管理器中双击、按下回车、或者右键打开时触发的选项。也就是我们通常意义上的文件关联。

编辑,这个选项也很常见。例如随意右键一个ini文件,一般情况下都能看到编辑按钮。这个选项可以让Windows具有使用浏览器和编辑器打开同一种文件的能力。比如对于音频文件来说,我希望使用播放器去播放,然而使用Audition去编辑它(播放器一般来说是不能编辑音频文件的,或者说,不应当由播放器去编辑),那么就需要把这里的默认键值设置为Audition在命令行打开音频文件时的命令。

预览,这个选项很少见到(或者说很少有人会去用吧)。Photoshop会设置此键值。设置后,右键菜单中的预览命令就是这个选项的关联项。

打印,右键菜单中的打印命令的关联项。

打开方式对话框设置

在Windows资源管理器中,用户可以通过右键选择“打开方式”改变默认的关联程序,这个设置的优先级在默认的后缀与ProgId关联的方式之上,保存位置则在HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\下。此位置下同样有许多后缀名,如.ext。在XP下,.ext项下面有Progid或Application子项,Windows 7下则是UserChoice或Application子项,子项的值就是关联的ProgId或者应用程序名称(不包括目录,如yourAppPath.exe)。

该设置注册表下的结构(以Windows 7为例):

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts
.ext
	(Default) = 空
	OpenWithList
		(Default) = 空
		a = xxx.exe //自定义的应用程序1
		b = xxx.exe //自定义的应用程序1
		...
		MRUList = ab //所有自定义程序的列表
	OpenWithProgids
		(Default) = 空
		xxxx.xxx (REG_NONE) //长度为0的二进制值
	UserChoice
		(Default) = 空
		Progid = $xxx //用户选择的应用程序,Application/xxx.exe或者一个Progid

需要注意的是,这个键不建议通过程序进行设置。而且有该键不被允许访问的报告出现。所以在写代码的时候,这部分键值的处理需要慎重考虑。

至此Windows文件关联机制就很清楚了。首先根据后缀名查找HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\,找不到时查找HKEY_CURRENT_USER\Software\Classes,最后才是HKEY_LOCAL_MACHINE\Software\Classes。因此检查一个文件是否与某个程序关联可以按照这个顺序检查。

清除文件关联

Windows 7下清除后缀名与某个程序的关联时要注意,程序只能删除自己拥有的HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ext\UserChoice,因此要清除用户设置的默认打开方式,需要设置一下权限。(这也就是为什么Foobar2000之类的软件会单独带一个设置文件关联的exe了)

在取消文件关联的时候,不需要保存之前的Progid。只需要交给系统处理即可。

杂项

在更改了文件关联以后,最好通知一下Windows设置已经改变,否则要下次登录才能看到变化。方法是使用SHChangeNotify函数并指定SHCNE_ASSOCCHANGED事件。

对于默认程序的设置,需要参照MSDN上的Default Programs这篇文章。

官方建议:总是在文件路径两侧使用双引号;避免硬编码的路径(比如Windows 2000下,没有C:\Windows只有C:\WINNT。官方建议是使用环境变量,例如上例应当是%SYSTEMROOT%);。

官方不建议:从现有的文件关联键复制再进行编辑;使用短的文件拓展名(然而QBasic里面只支持三个字母啊,笑)。

所有有关文件关联相关的文章,可以在MSDN的文件类型和文件关联部分找到。

参考文章

MSDN 的 Files Types:https://msdn.microsoft.com/en-us/library/windows/desktop/cc144148(v=vs.85).aspx
MSDN 的 Best Practices for File Associations:https://msdn.microsoft.com/en-us/library/windows/desktop/cc144156(v=vs.85).aspx
erikaIT 的 windows注册表文件关联机制:http://blog.csdn.net/erikaIT/article/details/71637167
三生石 的 学习笔记:Windows文件关联及有关注册表项:http://yuezhaoblog.blogspot.com.au/2012/07/windows.html

版权声明

本文基于WTFPL发布。

共有 人打赏支持
東條・スペンサー・咲
粉丝 34
博文 3
码字总数 5026
作品 1
×
東條・スペンサー・咲
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: