到目前为止,我知道 Windows 根据文件扩展名而不是文件类型显示上下文菜单。我刚刚使用 winamp 对带有 mp3 扩展名的空文本文件进行了测试,结果如下:
我以相同的方式测试带有扩展名 exe 的空文件,Windows 为我提供了“以管理员身份运行”等上下文菜单。
但是,如果我创建具有相同 exe 扩展名的 sfx 档案,Windows 如何为我提供不同的图标,而 WinRAR 如何为我提供特殊的上下文菜单,如“在此处提取”,如下图所示?
我的问题是 Windows 读取文件头并显示相关数据,还是 WinRAR 有任何特殊的文件检测方案?我怀疑第二个,因为在创建上下文菜单期间 WinRAR 没有调用。
另一个问题是,是否因为 Windows 读取标题的行为(例如它为图片或视频创建缩略图),现在扩展不再那么重要了?它们对上下文菜单没有任何影响吗?
答案1
Windows 上下文菜单处理程序可以同时静止的也动态的。如果你有兴趣进一步深入研究,我建议你阅读快捷(上下文)菜单和快捷菜单处理程序文章,尤其是选择静态或动态快捷菜单方法和使用动态动词自定义快捷菜单。
动态上下文菜单
静态上下文菜单是有限的,因为它们对于给定类型的每个文件对象都是相同的。此外,通过静态菜单可以处理的文件数量受用于执行命令的程序的限制。如果您需要处理 20 个文件怎么办?如果您需要根据文件本身的状态使用不同的处理选项怎么办?还有些情况下,您可能需要一个上下文菜单用于一组文件,另一个上下文菜单用于单个文件。这就是动态上下文菜单发挥作用的地方。
...
您可能希望根据所选文件是一个或多个而显示不同的菜单项。由于所选文件的数量可以在 IShellExtInit::Initialize 中确定,因此这变得很简单。您还可以根据文件本身来创建菜单项。除了选定的文件数量之外,您还应该知道相关文件名。这意味着您可以打开文件、检索信息并根据实际数据创建菜单项。或者您可以检查文件的其他属性(例如其创建日期、大小或只读状态)并根据该信息创建菜单项。
最后,如果你想要证明该文件确实被 WinRAR 的 shell 扩展 DLL 读取(因为你似乎对此表示怀疑),这里有各种读文件呼叫注册进程监控只需右键单击 WinRAR SFX:
(进程名称显示为 explorer.exe 而不是 rarext.dll,因为上下文菜单处理程序是一个“进程内” COM 对象,shell 将其直接加载到 explorer.exe 的内存空间中执行。)
如你所见,它读取前 7 个字节来确认它是一个 EXE:
在读取更多数据后(毫无疑问是为了获取和解析标头),它从偏移量 101,376 读取 7 个字节,以确认它是 WinRAR SFX,而不仅仅是任何旧的 EXE:
这会提示它添加各种上下文菜单项,例如使用 WinRAR 打开、使用 WinRAR 提取等等,而“普通”EXE 不会添加这些项。
此外,在 WinRAR 的设置对话框中,有一个名为在哪里检查 SFX 档案:
以下是帮助文件对此的说明:
“在哪里检查 SFX 档案”选项控制上下文菜单中 SFX 档案的处理。检查可执行文件的内容并检测它是否为自解压 (SFX) 存档会在右键单击每个“.exe”文件时引入一些延迟,因为 WinRAR 需要读取和分析文件数据以确定它是否是 SFX。虽然对于快速的本地硬盘来说,这种延迟可以忽略不计,但在网络磁盘速度较慢的情况下,这种延迟可能会很明显。这组选项允许分别启用或禁用本地硬盘、网络磁盘和其他磁盘(如 CD-ROM 和 USB)的 SFX 处理。如果关闭这些选项,则在右键单击 SFX 存档时,您将看不到所有与 SFX 相关的上下文菜单项。因此,只有当您在右键单击“.exe”文件时确实遇到延迟时,才禁用这些选项。
希望这能打消你的疑虑。:) 至于你的第二个问题,即扩展现在是否“不那么重要”并且“对上下文菜单没有任何影响”,我不明白你的意思。甚至图像/视频缩略图也是由外壳扩展处理程序 (DLL) 生成的。可以找到不同处理程序的列表这里。如您所见,可以为所有内容自定义 shell 扩展处理程序,包括快捷菜单、拖放操作、图标、图标叠加、属性表、缩略图、信息提示、元数据、资源管理器列、复制/移动/删除/重命名对话框、搜索……
答案2
Windows 资源管理器不读取标题。
任何扩展的最初形成的菜单基于注册表项,它们可以被视为 Windows 资源管理器的启动键:
HKLM\SOFTWARE\Classes\Protocols\Filter
HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks
HKLM\Software\Classes\*\ShellEx\ContextMenuHandlers
HKLM\Software\Classes\Directory\ShellEx\ContextMenuHandlers
HKLM\Software\Classes\Directory\Shellex\DragDropHandlers
HKLM\Software\Wow6432Node\Classes\Directory\Shellex\DragDropHandlers
HKLM\Software\Classes\Directory\Shellex\CopyHookHandlers
HKLM\Software\Classes\Directory\Background\ShellEx\ContextMenuHandlers
HKLM\Software\Classes\Folder\Shellex\ColumnHandlers
HKLM\Software\Wow6432Node\Classes\Folder\Shellex\ColumnHandlers
HKLM\Software\Classes\Folder\ShellEx\ContextMenuHandlers
HKLM\Software\Classes\Folder\ShellEx\DragDropHandlers
HKLM\Software\Classes\Folder\ShellEx\PropertySheetHandlers
HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers
HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers
HKCU\Software\Classes\*\ShellEx\ContextMenuHandlers
HKCU\Software\Classes\Directory\Background\ShellEx\ContextMenuHandlers
HKEY_LOCAL_MACHINE\Software\Classes
在和中按文件扩展名进行搜索HKEY_CURRENT_USER\Software\Classes
,如果找到文件扩展名,则运行指定的文件处理程序。