zoukankan      html  css  js  c++  java
  • Dig into Windows 7 视频文件缩略图显示问题

    装好 Windows 7 之后,相信有很多人跟笔者一样,会陆陆续续再装一些影音文件播放器,例如 KMPlayer、QQ影音、千千静听、暴风影音等等。久而久之,突然某一天,您可能发现在资源管理器中,一些诸如 avi、wmv、mpeg 、asf等格式的视频文件的缩略图不再显示,只能显示一个大大的图标,就像下面这样:

    当然,上面的内容只是一个引子,由于时间久远,笔者发现不及时,已经无从评估究竟是哪一款软件引发的问题。据网友反映,很多人在卸载暴风影音后,视频缩略图恢复正常,不过,笔者并未使用过此软件。但笔者认为,一般是这样的第三方的媒体播放器或解码软件软件造成了该问题。

    下面,我们一起来深入研究这个问题的背后的根层原因是什么。

    我们使用 Sysinternals 的利器 ProcessMonitor 对打开视频文件夹时的 Windows 资源管理器进程 explorer.exe 进行一个监控,结果如下:

    我们可以发现,它除了在最后操作文件以外,之前都是访问一系列的注册表项目。因此,我们可以锁定该错误的诱因是位于系统注册表的。

    进一步观察我们可以发现,就关于这个.asf格式的注册表项,既有 HKCU 的部分,也有 HKCR 的部分。由于笔者新建了一个用户账户进行测试,仍不能正常显示视频文件缩略图,故可以排除 HKCU 的可能,问题的原因就应该在 HKCR 部分的文件类型注册项目。

    这里必须有个说明,就是本文所讨论的这个不显示视频文件缩略图的现象是一个系统软件环境错误,而不是 Windows 的功能选项效果。也就是说,您必须确保您的"文件夹选项"里面被正确配置为显示文件缩略图(但缩略图却偏偏显示不出来):

    如上图所示,您必须确保高亮部分——"始终显示图标,从不显示缩略图"一项前的复选框处于清空状态。

    好了,我们接下来定位至注册表 HKEY_CLASSES_ROOT 区域下面的 .asf 部分,看到如图所示的情景:

    通过比对虚拟机中的 Windows 7 以及比对能够显示缩略图的注册文件类型,我才发现这里 ShellEx 下两个 GUID 项目下的"默认"键值被莫名地清空了,什么也没有。于是,我们就找到了问题的所在。其实, Windows 资源管理器不能显示视频缩略图的根本原因就是 ShellEx 下面的两个 GUID 项目值缺失导致的。这里,我们以文本形式展示一下问题注册表和虚机中正常注册表关于 .asf 项目的对比:

    出现问题的注册表 .asf 项

    正常 / 默认的注册表 .asf 项

    [HKEY_CLASSES_ROOT\.asf]

    @="KMPlayer.asf"

    "PerceivedType"="video"

    "Content Type"="video/x-ms-asf"

    "KMPBackup.bak"="WMP11.AssocFile.ASF"

    [HKEY_CLASSES_ROOT\.asf\OpenWithProgIds]

    "WindowsLive.PhotoGallery.video.15.3"=""

    "WindowsLive.MovieMaker.asset"=hex:

    [HKEY_CLASSES_ROOT\.asf\ShellEx]

    [HKEY_CLASSES_ROOT\.asf\ShellEx\{BB2E617C-0920-11D1-9A0B-00C04FC2D6C1}]

    @=""

    [HKEY_CLASSES_ROOT\.asf\ShellEx\{e357fccd-a995-4576-b01f-234630154e96}]

    @=""

    [HKEY_CLASSES_ROOT\.asf]

    @="WMP11.AssocFile.ASF"

    "PerceivedType"="video"

    "Content Type"="video/x-ms-asf"

    [HKEY_CLASSES_ROOT\.asf\OpenWithProgIds]

    "WMP11.AssocFile.ASF"=hex(0):

    [HKEY_CLASSES_ROOT\.asf\PersistentHandler]

    @="{098f2470-bae0-11cd-b579-08002b30bfeb}"

    [HKEY_CLASSES_ROOT\.asf\ShellEx]

    [HKEY_CLASSES_ROOT\.asf\ShellEx\{BB2E617C-0920-11D1-9A0B-00C04FC2D6C1}]

    @="{9DBD2C50-62AD-11D0-B806-00C04FD706EC}"

    [HKEY_CLASSES_ROOT\.asf\ShellEx\{e357fccd-a995-4576-b01f-234630154e96}]

    @="{9DBD2C50-62AD-11D0-B806-00C04FD706EC}"

    这里呢,我们解释几个重要的概念。@ 后面的键值就是注册表中"默认"处的键值。在上面的表格中我们可以看出,默认的 asf 文件格式是关联到 KMPlayer 的。但是笔者的 KMPlayer 已经卸载了,为什么这个键值没有被替换还原或者删除呢?查阅 MSDN 发现,这个是正常的,该键值仅用于标识安装默认关联该文件类型的程序之后,这样的关联是否发生了更改。现在笔者卸载了 KMPlayer,那么当我双击 asf 文件时,虽然存有这个键值但是默认却用 Windows Media Player 打开,原因是这个默认关联键值是要配合 OpenWithProgIds 里面的程序列表使用的,这里面已经没有 KMPlayer 了,所以 @ 也就不起作用了。当然,程序的文件类型关联键值不止这里的一处,还有类似于 WMP11.AssocFile.ASF 这样的注册表项目决定,这已经超出本文讨论范围,就不在本文赘述了。而 PerceivedType 是用来标识这个文件类是属于什么类型的文件的,例如,标识一个自定义扩展名究竟是属于文本还是属于声音、视频等等。在 Windows Vista 及其之后版本的 Windows 中,该键值才真正起作用,因为现在,Windows 用它来识别一个文件夹中有些什么类型的文件,从而决定自动将文件夹应用何种最佳的视图。Windows 默认的 PerceivedType 共有11中,这里也不再赘述,有兴趣的朋友们可以查看这篇 MSDN 文章—— http://msdn.microsoft.com/en-us/library/cc144150(v=VS.85).aspx 。在 Vista 之前的 Windows 中,这个键值仅用来决定文件属性对话框提供的属性字段以及这种文件类型可选的默认设置(如文件图标)。Content Type 用来标识该文件类型对应的 MIME 内容类型。OpenWithList (如果存有)和 OpenWithProgIds 都是用来辅助决定文件打开方式对话框中显示的程序列表的。不同之处在于,OpenWithList 子键下面存放的是应用程序子键,而 OpenWithProgIds 下面存放的是用于这种文件类型的可选 ProgID,对应于这些 ProgID 的程序也会显示在打开方式对话框中,而且,如果有程序取得了这种文件类型的所有权,即修改了默认键值 @,它就必须被添加进这个 OpenWithProgIds 子键。因此,在笔者卸载 KMPlayer 之前,它对应的 ProgID 一定出现在这个子键下面。当然,细心的你会发现,这里的项目会少于打开方式对话框中的程序列表。原因是,这个不是决定打开方式程序列表显示什么程序的唯一因素,由于超出本文范围不再延伸讨论。更多关于文件类型注册的细节,有兴趣的你可以阅读这篇 MSDN 文章—— http://msdn.microsoft.com/en-us/library/cc144148(VS.85).aspx

    既然是 digging into,我就要继续为大家介绍 PersistentHandler 了。Persistent handlers 是与搜索文件具体内容相关的,如果某种文件类型下面有 PersistentHandler,那么它将告诉 Windows "请搜索此种类型文件所包含的具体内容"或者"请不要搜索此种类型文件所包含的具体内容"。我们知道,对于一些二进制文件,我们就应该不让 Windows 搜索其具体内容,这些二进制文件包括媒体文件或者加密的文档等等,因为如果搜索,那么搜索结果可能包含一些不相关的或者您不可读的内容。很简单,当视频文件以文本的形式展现在您面前的时候,没人知道这是个什么视频,我们必须使用播放器去解析它来观看。而我们这些媒体文件大多数会要求 Windows 不要搜索内容,因此,默认地会定义 null persistent handlers。就像本例中,我们观察上面的表格发现,asf 文件在正常情况下,其 PersistentHandler 子键下面是有一个键值为 {098f2470-bae0-11cd-b579-08002b30bfeb}默认键(@)的,这个 GUID 对应的就是 null persistent handler。(上下文中的 GUID 都是可以在注册表 HKEY_CLASSES_ROOT\CLSID 区域找到对应关系的)

    接下来还要介绍一个 ShellEx。对于这些 Windows 默认支持的媒体文件,此键下面一般还有两个子键,分别是 {BB2E617C-0920-11D1-9A0B-00C04FC2D6C1} {e357fccd-a995-4576-b01f-234630154e96}。这里的两个 GUID 是系统提供的文件属性 handler,在 HKEY_CLASSES_ROOT\CLSID 区域不可查。系统会为程序员提供一些默认的常见文件格式对应的 property handlers。ShellEx 下面保存的都是 shell extension handlers,它们是一些与 Shell扩展功能相关的属性的具体描述。这两个以 GUID 命名的子键,其前者使用的是 OLEDoc 文件的 property handler GUID,OLEDOC 文件会在文件属性对话框的详细信息选项卡中提供一些诸如标题、备注、版权之类的字段(这里只是举个例子,其实它的作用还有很多,例如与 Windows Search 有关);后者使用的是 thumbnail handler Shell extension GUID,也就是缩略图处理程序外壳扩展GUID,它自身的缺失以及其下默认键键值的缺失才是真正与缩略图不显示有关的根本原因!我们还可以发现,在正常情形下,这两个以 GUID 命名的 ShellEx 子键下面都还有一个默认键,键值为 {9DBD2C50-62AD-11D0-B806-00C04FD706EC},通过搜索注册表 HKEY_CLASSES_ROOT\CLSID 区域我们发现这是一个 Property Thumbnail Handler。

    如果您是一个程序员或是一位对上述提到的各种 Handlers 的实现原理感兴趣的 IT 专业人士,相信您会对以下四篇 MSDN 文章感兴趣:

    Property System - http://msdn.microsoft.com/en-us/library/bb776859(v=VS.85).aspx

    Property Handlers - http://msdn.microsoft.com/en-us/library/bb776861(v=VS.85).aspx

    Thumbnail Handlers - http://msdn.microsoft.com/en-us/library/cc144118(VS.85).aspx

    Creating Shell Extension Handlers - http://msdn.microsoft.com/en-us/library/cc144067(VS.85).aspx

    通过以上说明,相信您已经理解,对于本案例我们所要修复的直接内容只有一个——添加 HKEY_CLASSES_ROOT\<媒体文件扩展名|如.asf > \ShellEx\{e357fccd-a995-4576-b01f-234630154e96} 键,并将其下的默认键值设为 {9DBD2C50-62AD-11D0-B806-00C04FD706EC} 即可。添加之后,我们只需结束 explorer 进程,然后重新启动 explorer 进程即可看见效果——视频文件的缩略图都回来啦:

    考虑到您可能没有时间在注册表编辑器内一项项地去添加,笔者为您提供了快速修复方案—— .reg 文件,您只需下载并双击导入即可。

    笔者为您提供的文件共有两个,一个叫 WMP_MediaFiles_Thumbnails_Solution.reg,它用来单纯地修复这个案例中所阐述的视频文件缩略图不显示的问题,但需要提醒您注意的是,在这个文件中,我没有使用严格意义的最小修复原则,我将 ShellEx 下的两个以 GUID 命名的子键都添加进去了,除了修复缩略图问题,也可以顺便修复 OLEDoc 文件的 property handler 设置,因为在笔者自己遇到的问题中,发现这个设置也是空缺的(详见上文中的比对表格);另一个提供的文件,则是装好 Windows 7 后,一切默认媒体文件在注册表中的扩展名项目默认设置,叫做 WMP_FileTypes_Defaults.reg,它包含了音频、视频文件的默认设置,因此当然包含能够显示缩略图的视频文件的一些设置。这些设置包括以媒体文件扩展名(如 .wmv)命名的注册表项目及其下面的一切子键。建议使用第三方媒体播放器关联一些常见媒体文件类型的用户不要使用这个文件导入修复,而是使用第一个文件修复,因为使用这第二种文件修复时,必将覆盖您的文件类型默认所有权设置(上文提到过),例如 @="KMPlayer.asf" 就会被覆盖为 @=" WMP11.AssocFile.ASF "。当然,还有一点值得说明的是,不论是哪个文件,都只修复 Windows 默认支持的媒体文件类型,例如 Windows Media Player 和 Windows Media Center 原生能够播放的文件类型;而且,文件 WMP_MediaFiles_Thumbnails_Solution.reg 只修复一些本应能够显示缩略图的视频文件,而 WMP_FileTypes_Defaults.reg 则相当于重置一切默认支持的音频和视频文件的设置(但不会删除一些第三方播放器留下的冗余键值)。

    这两个文件的下载地址为:http://cid-3222d068881c5251.office.live.com/embedicon.aspx/.Public/Windows%207%20%e8%a7%86%e9%a2%91%e6%96%87%e4%bb%b6%e7%bc%a9%e7%95%a5%e5%9b%be%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88

    如果您觉得上述文件存有不完美的地方,例如您希望使用 WMP_MediaFiles_Thumbnails_Solution.reg 实现真正的最小修复,请用记事本编辑它,删除每个文件扩展名设置下面的这两行(以 .3g2 文件为例):

    [HKEY_CLASSES_ROOT\.3g2\shellex\{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}]

    @="{9DBD2C50-62AD-11D0-B806-00C04FD706EC}"

    删除前后的对比应该是这样(同样以 .3g2 这个格式的设置为例):

    说明

    代码

    删除前的代码

    [HKEY_CLASSES_ROOT\.3g2]

    [HKEY_CLASSES_ROOT\.3g2\shellex]

    [HKEY_CLASSES_ROOT\.3g2\shellex\{BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}]

    @="{9DBD2C50-62AD-11D0-B806-00C04FD706EC}"

    [HKEY_CLASSES_ROOT\.3g2\shellex\{E357FCCD-A995-4576-B01F-234630154E96}]

    @="{9DBD2C50-62AD-11D0-B806-00C04FD706EC}"

    删除后的代码

    [HKEY_CLASSES_ROOT\.3g2]

    [HKEY_CLASSES_ROOT\.3g2\shellex]

    [HKEY_CLASSES_ROOT\.3g2\shellex\{E357FCCD-A995-4576-B01F-234630154E96}]

    @="{9DBD2C50-62AD-11D0-B806-00C04FD706EC}"

    等效最简代码(同删除后效果一致)

    [HKEY_CLASSES_ROOT\.3g2\ShellEx\{e357fccd-a995-4576-b01f-234630154e96}]

    @="{9DBD2C50-62AD-11D0-B806-00C04FD706EC}"

    如果您希望使用 WMP_FileTypes_Defaults.reg 完全恢复默认设置,包括删除第三方播放器留下的冗余设置和由于 Windows 的使用而产生的设置变更,请用记事本编辑它,在每个文件扩展名设置的首行前面添加下面的这行(以 .3gp文件为例):

    [-HKEY_CLASSES_ROOT\.3gp]

    添加前后的对比应该是这样(同样以 .3gp 这个格式的设置为例):

    说明

    代码

    添加前的代码

    [HKEY_CLASSES_ROOT\.3gp]

    @="WMP11.AssocFile.3GP"

    "PerceivedType"="video"

    "Content Type"="video/3gpp"

    [HKEY_CLASSES_ROOT\.3gp\OpenWithProgIds]

    "WMP11.AssocFile.3GP"=hex(0):

    [HKEY_CLASSES_ROOT\.3gp\ShellEx]

    [HKEY_CLASSES_ROOT\.3gp\ShellEx\{BB2E617C-0920-11D1-9A0B-00C04FC2D6C1}]

    @="{9DBD2C50-62AD-11D0-B806-00C04FD706EC}"

    [HKEY_CLASSES_ROOT\.3gp\ShellEx\{e357fccd-a995-4576-b01f-234630154e96}]

    @="{9DBD2C50-62AD-11D0-B806-00C04FD706EC}"

    添加后的代码

    [-HKEY_CLASSES_ROOT\.3gp]

    [HKEY_CLASSES_ROOT\.3gp]

    @="WMP11.AssocFile.3GP"

    "PerceivedType"="video"

    "Content Type"="video/3gpp"

    [HKEY_CLASSES_ROOT\.3gp\OpenWithProgIds]

    "WMP11.AssocFile.3GP"=hex(0):

    [HKEY_CLASSES_ROOT\.3gp\ShellEx]

    [HKEY_CLASSES_ROOT\.3gp\ShellEx\{BB2E617C-0920-11D1-9A0B-00C04FC2D6C1}]

    @="{9DBD2C50-62AD-11D0-B806-00C04FD706EC}"

    [HKEY_CLASSES_ROOT\.3gp\ShellEx\{e357fccd-a995-4576-b01f-234630154e96}]

    @="{9DBD2C50-62AD-11D0-B806-00C04FD706EC}"

    (为了防止 SkyDrive 网络因素造成的不能下载,我本想将我制作的这两个文件的源代码贴在本文的最后,但是发布后发现实在是太过于冗长,篇幅受不了。因此,还望见谅! J

  • 相关阅读:
    安装 Panda3D 并使用原有的Python
    Jupyter Notebook PDF输出的中文支持
    lua的文件管理
    elasticsearch-hadoop.jar, 适用于spark3,hadoop3
    shell中递归遍历指定文件夹下的文件
    JDBC的ResultSet游标转spark的DataFrame,数据类型的映射以TeraData数据库为例
    Pandas一些小技巧
    用c++后缀自动机实现最大公共字符串算法,并封装成Python库
    后缀自动机的python实现
    PYTHON调用C接口(基于Ctypes)实现stein算法最大公约数的计算
  • 原文地址:https://www.cnblogs.com/mvperic/p/1779843.html
Copyright © 2011-2022 走看看