前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Windows】文件类型与链接类型的默认程序

【Windows】文件类型与链接类型的默认程序

原创
作者头像
lealc
修改2024-06-27 10:53:59
2010
修改2024-06-27 10:53:59

前言

从Vista系统开始,Windows逐渐开始重视权限的管理,并陆续回收了对于默认程序的设置权限,增强了用户的体验。相对于Win7,用户应用程序可以肆意设置自身应用作为文件类型的默认程序,Win10以后的应用程序仅能设置自身作为文件类型或者链接类型的推荐应用程序,仅用户自身主动点击设置才能作为默认程序。

默认程序

本节主要介绍以Win10以后的默认程序框架描述设置一个默认程序相关的知识,win7如何设置默认程序会在后面章节介绍。

注册

对于Windows系统,我们需要将自身的应用注册到系统上,供后续默认程序关联所能使用。

注册一个应用一般是应用程序安装时进行,也可以后续运行时补上,一般注册后的注册表如下

代码语言:shell
复制
HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER
   SOFTWARE
      Microsoft
         Windows
            CurrentVersion
               App Paths
                  file.exe
                     (Default)
                     DontUseDesktopChangeRouter
                     DropTarget
                     Path
                     UseUrl

注册表详细字段解释如下

注册表项

详细信息

(默认值)

应用程序的完全限定路径。 (Default) 条目中提供的应用程序名称可以使用或不使用其 .exe 扩展名进行说明。 如有必要, ShellExecuteEx 函数 会在搜索 应用路径 子项时添加扩展。 条目属于 REG_SZ 类型。

DontUseDesktopChangeRouter

调试程序应用程序在调试 Windows 资源管理器进程时必须避免文件对话框死锁。 但是,设置 DontUseDesktopChangeRouter 条目会稍微降低处理更改通知的效率。 条目属于 REG_DWORD 类型,值0x1。

DropTarget

CLSID (类标识符)。 DropTarget 条目包含对象的 CLSID, (通常是本地服务器,而不是实现 IDropTarget 的进程内服务器) 。 默认情况下,当放置目标是可执行文件,并且未提供 DropTarget 值时,Shell 会将放置的文件列表转换为命令行参数,并通过 lpParameters 将其传递给 ShellExecuteEx。

Path

提供一个字符串 (以分号分隔的目录列表的形式,) 通过调用 ShellExecuteEx 启动应用程序时追加到 PATH 环境变量。 它是 .exe 的完全限定路径。 这是 REG_SZ。 在 Windows 7 及更高版本中,类型可以 REG_EXPAND_SZ,并且通常 REG_EXPAND_SZ %ProgramFiles%。 注意: 除了 Shell 识别 (默认) 、路径和 DropTarget 条目外,应用程序还可以向其可执行文件的 “应用路径” 子项添加自定义值。 我们鼓励应用程序开发人员使用 “应用路径” 子项来提供特定于应用程序的路径,而不是向全局系统路径添加内容。

SupportedProtocols

创建一个字符串,其中包含给定密钥的 URL 协议方案。 这可以包含多个注册表值,以指示支持的方案。 此字符串遵循 scheme1:scheme2 的格式。 如果此列表不为空,则将 文件: 添加到字符串中。 定义 SupportedProtocols 时,隐式支持此协议。

UseUrl

指示应用程序可以接受 URL (而不是命令行上) 文件名。 可直接从 Internet 打开文档的应用程序(如 Web 浏览器和媒体播放器)应设置此项。 当 ShellExecuteEx 函数启动应用程序且未设置 UseUrl=1 值时, ShellExecuteExecuteEx 会将文档下载到本地文件,并在本地副本上调用处理程序。 例如,如果应用程序设置了此项,并且用户右键单击存储在 Web 服务器上的文件,则 Open 谓词将可用。 否则,用户必须下载文件并打开本地副本。 UseUrl 条目的类型 REG_DWORD ,值为0x1。 在 Windows Vista 及更早版本中,此项指示通过 ShellExecuteEx 调用时,应将 URL 连同本地文件名一起传递给应用程序。 在 Windows 7 中,它指示应用程序可以理解传递给它的任何 http 或 https URL,而无需提供缓存文件名。 此注册表项与 SupportedProtocols 项相关联。

一般情况下完成路径注册后,还需要将自身应用放到一个windows系统能够检索到的地方,就是计算机\HKEY_CLASSES_ROOT\Applications,但是这里写入注册表是需要管理员权限,比较讨厌。这里是windows操作系统故意设置,应用程序仅需将自身应用注册到计算机\HKEY_CURRENT_USER\Software\Classes\Applications即可,对于Classes中的注册表变更,会自动同步到HKEY_CLASSES_ROOT中。

对于计算机\HKEY_CURRENT_USER\Software\Classes\Applications中写入的*.exe项,有以下字段说明

注册表项

详细信息

shell\verb

提供用于从 OpenWith 调用应用程序的谓词方法。 如果未在此处指定谓词定义,系统将假定应用程序支持 CreateProcess,并在命令行上传递文件名。 此功能适用于所有谓词方法,包括 DropTarget、ExecuteCommand 和 Dynamic Data Exchange (DDE) 。

DefaultIcon

允许应用程序提供特定图标来表示应用程序,而不是 .exe 文件中存储的第一个图标。

FriendlyAppName

提供一种方法,用于获取要为应用程序显示的可本地化名称,而不仅仅是显示的版本信息(可能不可本地化)。 关联查询 ASSOCSTR 读取此注册表项值,并回退到版本信息中使用 FileDescription 名称。 如果缺少该名称,则关联查询默认为文件的显示名称。 应用程序应使用 ASSOCSTR_FRIENDLYAPPNAME 来检索此信息以获取正确的行为。

SupportedTypes

列出应用程序支持的文件类型。 这样做可使应用程序在“ 使用打开 ”对话框的级联菜单中列出。

NoOpenWith

指示未指定用于打开此文件类型的应用程序。 请注意,如果已按文件类型为应用程序设置了 OpenWithProgIDs 子项,并且 ProgID 子项本身也没有 NoOpenWith 条目,则即使它已指定 NoOpenWith 条目,该应用程序也会显示在推荐或可用应用程序列表中。

IsHostApp

指示进程是主机进程,例如 Rundll32.exe 或 Dllhost.exe,不应考虑将 “开始” 菜单固定或包含在“最常用的 (MFU) 列表中。 当使用包含非 null 参数列表的快捷方式或显式 应用程序用户模型 ID (AppUserModelIDs) 启动时,可以将进程固定 (作为该快捷方式) 。 此类快捷方式是包含在 MFU 列表中的候选项。

NoStartPage

指示应用程序可执行文件和快捷方式应从 “开始 ”菜单和固定或包含在 MFU 列表中排除。 此项通常用于排除系统工具、安装程序和卸载程序以及自述文件。

UseExecutableForTaskbarGroupIcon

如果此应用程序没有可固定的快捷方式,则会导致任务栏使用此可执行文件的默认图标,而不是第一次遇到窗口的图标。

TaskbarGroupIcon

指定用于替代任务栏图标的图标。 窗口图标通常用于任务栏。 设置 TaskbarGroupIcon 条目会导致系统改用应用程序 .exe 中的图标。

注意事项:

1、按照User进行注册即可,这样方便操作系统自动管理权限问题。

2、Shell 将命令行的长度限制为MAX_PATH * 2 个字符。 如果有许多文件列为注册表项,或者其路径很长,则列表中后面的文件名可能会在命令行被截断时丢失。

3、某些应用程序不接受命令行中的多个文件名。

4、接受多个文件名的某些应用程序无法识别 Shell 提供这些文件名的格式。 Shell 将参数列表作为带引号的字符串提供,但某些应用程序可能需要不带引号的字符串。

5、并非所有可以拖动的项都是文件系统的一部分:例如打印机。 这些项没有标准 Win32 路径,因此无法向 ShellExecuteEx 提供有意义的 lpParameters 值。

实战

这里官方推荐的完整注册流程分为3步

1、注册应用路径:计算机\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths

2、注册应用程序相关信息:计算机\HKEY_CLASSES_ROOT\ApplicationsYOUR_EXE_NAME\shell\open\command

3、注册ProgID:计算机\HKEY_CURRENT_USER\Classes独有的ProgID,刚才提到过,这里可以通过注册HKEY_CURRENT_USER下面来实现相同的效果

这里值得说明的两点:

1)ProgID是独有的,像微软弄了长字符串来规避重复,也可以进行版本控制

2)这个ProgID可以是任意值,方便针对不同的文件类型和链接类型来实现不同的命令行操作

代码语言:shell
复制
// 步骤1
regKey.Open(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths", KEY_WRITE)
regKey.CreateKey(L"MailToTest.exe", KEY_WRITE);
regKey.WriteValue(L"", 完整路径含exe);
regKey.WriteValue(L"Path", 完整路径不含exe);

// 步骤2
regKey.Open(HKEY_CURRENT_USER, L"Software\\Classes\\Applications", KEY_WRITE)
regKey.CreateKey(L"MailToTest.exe\\shell\\open\\command", KEY_WRITE)
std::wstring command = L"\"" + Util::GetProcessPathWithExe() + L"\" \"%1\"";
lRet = regKey.WriteValue(L"", command.c_str());

// 步骤3,这一步不是必须,如果后面还要推荐应用也可以在后面做
regKey.Open(HKEY_CURRENT_USER, L"Software\\Classes", KEY_WRITE)
regKey.CreateKey(L"MailToTest.exe\\shell\\open\\command", KEY_WRITE)
std::wstring command = L"\"" + Util::GetProcessPathWithExe() + L"\" \"%1\"";
lRet = regKey.WriteValue(L"", command.c_str());

注册成功后,自身应用已经可以被windows正确索引,打开某后缀名文件已经可以看到应用出现在更多选项中了

eml默认应用
eml默认应用

特别的,如果应用程序仅想针对特定的几种文件类型支持打开或设置默认应用,可以在Software\Classes\Applications下设置的时候,新建项SupportedTypes来展示自身支持的文件类型或链接类型。

声明默认应用

这里Win10系统后机制的改变,应用程序注册后仅需声明自身想要关联的默认程序即可出现在用户选择默认程序的推荐程序列表中,有点拗口,举个例子就是以下红框内容

建议的应用
建议的应用

那如何实现这个操作呢?windows系统推荐我们分三步进行

1、RegisteredApplications

这一步用来当windows搜索某种文件类型或链接类型时,将自身加入到这个搜索列表中,主要是用来映射真正的应用,具体路径是:计算机\HKEY_CURRENT_USER\SOFTWARE\RegisteredApplications

代码语言:shell
复制
std::wstring exe = L"Tencent.MailToTest";
std::wstring exePath = L"Software\\Tencent\\MailToTest\\Capabilities";

regKey.Open(HKEY_CURRENT_USER, L"Software\\RegisteredApplications", KEY_WRITE)
regKey.WriteValue(exe.c_str(), exePath.c_str())

2、设置自定义ProgID

这一步主要是用来分发不同协议类型或者文件类型时处理的程序,可以支持多种命令行的分发

注意一定要有CLSID字段

代码语言:shell
复制
regKey.Create(HKEY_CURRENT_USER, L"Software\\Classes\\MailToTest.exe", KEY_WRITE)
lRet = regKey.CreateKey(L"CLSID", KEY_WRITE);
lRet = regKey.WriteValue(L"", L"{9ACE45B5-1ADF-493F-936D-30B79628C3C5}");

regKey.CreateKey(L"shell\\open\\command", KEY_WRITE);
std::wstring command = L"\"" + Util::GetProcessPathWithExe() + L"\" \"%1\"";
lRet = regKey.WriteValue(L"", command.c_str());

3、完善应用关联信息

这一步完善并关联所有文件类型和映射类型,按需加上自己感兴趣的文件类型和链接类型即可

代码语言:shell
复制
std::wstring exePath = L"Software\\Tencent\\MailToTest\\Capabilities";
regKey.Create(HKEY_CURRENT_USER, exePath.c_str(), KEY_WRITE);
regKey.WriteValue(L"ApplicationDescription", L"Leal-eml默认程序")

// 这一步设置名字是必须的
regKey.WriteValue(L"ApplicationName", L"MailToTest程序")

// 文件类型处理
regKey.CreateKey(L"FileAssociations", KEY_WRITE)
regKey.WriteValue(L".eml", L"MailToTest.exe")
regKey.WriteValue(L".png", L"MailToTest.exe")

// 链接类型处理
regKey.CreateKey(L"URLAssociations", KEY_WRITE)
regKey.WriteValue(L"mailto", L"MailToTest.exe")

上面是设置em和png的默认关联ProgID都是一样,也可以设置不同,重复步骤2设置不同的ProgID可以进行分发不同的文件类型处理,同样可以针对mailto链接类型进行分发不同的ProgID。

效果图如下

eml默认程序
eml默认程序
mailto默认程序
mailto默认程序

Win7设置默认程序

win7下设置默认程序相对来说简单一些

注册

首先第一个步骤都是将自身应用注册成系统可识别应用,参考win10的注册过程即可,效果如下

更多应用
更多应用

文件类型

对于文件类型设置默认应用,以.eml为例,刚装完系统可能都没有.eml的文件类型被系统所识别,可以手动创建然后设置其默认应用

代码语言:shell
复制
regKey.Create(HKEY_CURRENT_USER, L"Software\\Classes\\.eml", KEY_WRITE)
regKey.WriteValue(L"", L"MailToTest.exe");

这里设置默认,即可将自身应用直接设置为.eml后缀名默认打开程序,其中HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.eml会自动同步更新OpenWithListOpenWithProgids两项

文件类型默认
文件类型默认

链接类型

对于链接类型,除了默认的http/https,也可以支持自定义的链接类型,例如mailto:mailto://www.baidu.com。

代码语言:shell
复制
regKey.Create(HKEY_CURRENT_USER, L"Software\\Classes\\mailto", KEY_WRITE)
regKey.WriteValue(L"URL Protocol", L"");

regKey.CreateKey(L"shell\\open\\command", KEY_WRITE);
std::wstring command = L"\"" + Util::GetProcessPathWithExe() + L"\" \"%1\"";
lRet = regKey.WriteValue(L"", command.c_str());

效果如下

链接类型默认程序
链接类型默认程序

参考

1、应用程序注册:https://learn.microsoft.com/zh-cn/windows/win32/shell/app-registration

2、文件类型和文件关联:https://learn.microsoft.com/zh-cn/windows/win32/shell/fa-intro

3、文件关联的最佳做法:https://learn.microsoft.com/zh-cn/windows/win32/shell/fa-best-practices

4、文件关联示例:https://learn.microsoft.com/zh-cn/windows/win32/shell/fa-sample-scenarios

5、默认程序:https://learn.microsoft.com/zh-cn/windows/win32/shell/default-programs

6、“打开方式”包含应用程序:https://learn.microsoft.com/zh-cn/windows/win32/shell/how-to-include-an-application-on-the-open-with-dialog-box

我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 默认程序
    • 注册
      • 实战
    • 声明默认应用
      • 1、RegisteredApplications
      • 2、设置自定义ProgID
      • 3、完善应用关联信息
  • Win7设置默认程序
    • 注册
      • 文件类型
        • 链接类型
        • 参考
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档