几年前我在新闻组中写了这篇文章。浏览了一下,发现不是我写过的最清晰的,但还算完整。对于它的价值,我在下面转载了它:
首先,您需要在其下创建一个子项,HKEY_CLASSES_ROOT
该子项将保存启动您的应用程序的命令。您应该将此键命名为半描述性的。您的文件扩展名[s] 将映射到此键。例如,TXT 文件映射到一个名为txtfile
, 默认。使用此设置的好处是,如果您的应用程序可以处理多个扩展程序,您可以将它们全部映射到此键。例如,许多图像编辑应用程序创建一个名为“imagefile”之类的子键,并将 .bmp、.jpg、.gif 等映射到该键。我们将把您的密钥称为“JoeBlowFile”。接下来,您需要将新的 JoeBlowFile 键的“默认”值设置为向用户描述他们拥有的文件类型的文本字符串。这是 Windows 资源管理器中“类型”下显示的内容。同样,以 TXT 文件为例,这里的一个好的字符串应该是“文本文件”或“文本文档”。(默认情况下是后者。)您的字符串可能是“Joe Blow Data”。
现在,在您的新密钥下,您可以创建另一个名为“DefaultIcon”的子密钥。顾名思义,这设置了与这种类型的文件一起使用的图标。您应该创建一个自定义图标,以图形方式表示您的程序处理的文档。您可以将此图标保存为应用程序目录中的 ICO 文件,但更好的是,您可以将其作为资源包含在您的 EXE 或 DLL 中。无论哪种方式,您都需要将子项的默认值设置为表示 ICO、EXE 或 DLL 的完整路径和文件名的字符串。如果文件中有多个图标(特别是如果您将其作为资源包含在 EXE 或 DLL 中),您还需要添加一个逗号,以及一个从零开始的正索引号,表示您使用的图标'd like to use,或者一个否定的资源ID,使用您在资源脚本中为图标分配的任何 ID 的负数。所以你的可能是,例如“C:\Program Files\JoeBlow\JoeBlow.exe, 2”。
上一段为 C# 开发人员提供的说明。不幸的是,C# 项目不能有资源脚本。通过将资源添加到项目并将它们指定为“嵌入式资源”而添加到 .NET 应用程序的资源包含在与以前的方法不兼容的新的 .NET 特定格式中。您可以在 VS.NET 上使用 C# 正确嵌入应用程序的唯一图标是应用程序图标,可从项目属性访问。如果您需要额外的图标(例如,一个图标来表示由您的应用程序处理的文档文件而不是表示应用程序本身),您需要包含 ICO 文件本身,使用嵌入图标的 C++ 编译 DLL,或者创建并编译资源脚本并将其从项目属性中包含在您的项目中。
无论您是否选择使用DefaultIcon
密钥,您现在都需要在您的密钥下创建一个名为“shell”的子JoeBlowFile
密钥。在下面shell
键,您将为您希望用户能够从上下文菜单(右键单击菜单)对您的文件类型执行的每个命令创建单独的键。这些项目被称为“动词”。为保持一致,其中之一应该是“open”——如果存在,该键将是默认键(即当用户双击您类型的文件时,将执行 open 命令)。相反,您可以将“shell”键的默认值设置为您希望默认执行的动词。您可以选择将每个动词键的默认值设置为您希望在用户右键单击您的类型的文件时出现在上下文菜单中的文本。在此文本中可以使用与号 (&) 来指定以下字符将加下划线,这意味着用户可以按下与该字符对应的键来从上下文菜单中选择该命令。例如,对于“open”键,您可以将“Open with &Joe Blow's app”作为默认值。然后,带有下划线 J 的文本将出现在该类型文件的上下文菜单中,用户可以按字母 J 启动 Joe Blow 的应用程序。
但是,使用“打开”(和后续)键,您唯一需要做的就是创建另一个键作为该键的子键,称为“命令”。命令键的默认值必须设置为一个字符串,该字符串仅表示执行该操作所需的命令。例如,“open”键下的命令键中的默认字符串可能是“C:\Program Files\JoeBlow\JoeBlow.exe”“%1”。请注意应用程序的路径\文件名和%1
. 如果路径或文件名中有任何空格,则它们仅在应用程序的路径\文件名周围是必需的,但%1
对于 32 位应用程序,它们绝对是必需的。%1
就像在旧的%1
MS-DOS 批处理 (.bat) 文件中一样。 %1
替换为命令行上的第一个参数,在这种情况下,它成为您的应用程序应该打开的文件的文件名。因为您事先不知道包含您应该打开的文件的路径或文件名是否包含空格,所以您必须将引号放在%1
.
还应包括您的应用程序所需的其他参数。例如,“命令”键中的默认值,在“打印”键下可能是“C:\Program Files\JoeBlow\JoeBlow.exe”“%1”/print”或“”C:\Program文件\JoeBlow\JoeBlow.exe”/打印“%1”。如何在应用程序中处理命令行参数取决于您。
上面提到的有关可替换参数(如“%1”)的说明。显然,“%1”参数/可以/被替换为要打开的短文件名。情况并非总是如此,而且我还没有弄清楚 Windows 使用什么标准来确定它会通过什么——短期还是长期。可能是,如果注册表中列出的可执行路径是长文件名,Windows 会将 %1 替换为长文件名来启动,但如果可执行路径是短文件名,或者可以解释为 1,Windows 将替换%1
为短文件名。如果您想确保始终获得长文件名,请改用“%L”。您可以使用大写 L(就像我所做的那样)或小写 L,但我更喜欢使用大写,因为小写“l”
更重要的是,如果您的程序知道如何处理 Shell 项 ID,则可以使用 "%i" 参数来获取它而不是长文件名。同样,大写或小写“i”同样适用,但我发现大写“I”更难与小写“l”和数字“1”区分开来。如果您不知道 Shell Item ID 是什么,没关系。你可能永远不需要使用一个。
你终于完成了JoeBlowFile
钥匙。剩下的就比较简单了。您只需在 HKEY_CLASSES_ROOT 下创建(如果尚不存在)另一个子项,并将其命名为与文档类型的扩展名相同。要使用 txtfile 示例,名称应为“.txt”(带点,但不带引号)。您的(Joe Blow 的)可能是“.jbf”(对于 Joe Blow 文件)。现在必须将此键的默认值设置为您创建的第一个键的名称,在我们使用的示例中是“JoeBlowFile”。
而已。你在注册表中完成了。请记住,您必须确保您的应用程序以与您在“shell”键下设置的命令一致的方式处理命令行。当您的应用程序启动时,Window 不会自动为您打开该文件......您必须这样做。
从图形上看,它看起来像这样:
HKEY_CLASSES_ROOT
| +--.jbf = JoeBlowFile
|
+--JoeBlowFile = 乔吹数据
|
+--DefaultIcon = C:\Program Files\JoeBlow\JoeBlow.exe, 2
|
+--壳牌
|
+--open = 使用 &Joe Blow 的应用打开
| |
| +--command = "C:\Program Files\JoeBlow\JoeBlow.exe" "%1"
|
+--打印
|
+--command = "C:\Program Files\JoeBlow\JoeBlow.exe" "%1" /print
如果您还不知道如何修改注册表,请在 MSDN 中查找所有以“Reg”开头的函数,包括 RegOpenKeyEx、RegCreateKeyEx 和 RegSetValueEx。您也可以通过创建“.reg”文件并简单地使用 ShellExecuteEx() 在其上调用“regedit.exe /s”来实现这一点。(/s
阻止 Regedit 弹出消息框,询问“您确定要将 [name of file.reg] 中的信息添加到注册表吗?”) REG 文件的格式简单明了。这是一个示例 REG 文件,用于从上面添加“JoeBlow”示例:
REGEDIT4
[HKEY_CLASSES_ROOT\.jbf]
@="JoeBlowFile"
[HKEY_CLASSES_ROOT\JoeBlowFile]
@="乔吹数据"
[HKEY_CLASSES_ROOT\JoeBlowFile\DefaultIcon]
@="C:\\Program Files\\JoeBlow\\JoeBlow.exe, 2"
[HKEY_CLASSES_ROOT\JoeBlowFile\Shell]
[HKEY_CLASSES_ROOT\JoeBlowFile\Shell\open]
@="使用 &Joe Blow 的应用打开"
[HKEY_CLASSES_ROOT\JoeBlowFile\Shell\open\command]
@="\"C:\\Program Files\\JoeBlow\\JoeBlow.exe\" \"%1\""
[HKEY_CLASSES_ROOT\JoeBlowFile\Shell\print]
@="&打印"
[HKEY_CLASSES_ROOT\JoeBlowFile\Shell\print\command]
@="\"C:\\Program Files\\JoeBlow\\JoeBlow.exe \"%1\" /print"
确保包含“REGEDIT4”作为文件的第一行,否则它将不起作用。还要确保在最后一行按回车键,否则不会读入该行。总而言之,以这种方式将程序添加到注册表并不像听起来那么方便,因为如果出现以下情况,您必须修改 REG 文件您的应用安装在除C:\Program Files\JoeBlow 之外的任何位置。
上述说明针对的是使用 C 或 C++ 直接对 Win32 API 进行编程的用户。对于 .NET 上的 C#,它要容易一些。查看 Registry 类,或者您甚至可以使用 VS.NET 中的部署项目以图形方式完成大部分工作。
要将本机可访问的资源添加到 .NET 程序集,您将需要一个资源脚本。资源脚本是纯文本文件,类似于代码文件。其实就是代码;由资源编译器 rc.exe 编译的声明性代码。示例资源脚本如下:
#include <windows.h>
#define IDI_APP 100
#define IDI_FILE 200
#define ID_VERSION 1
IDI_APP ICON "Resources\\Application.ico"
IDI_FILE ICON "Resources\\JowBlowFile.ico"
ID_VERSION VERSIONINFO
FILEVERSION 1, 0, 19, 186 // change this to your version
PRODUCTVERSION 1, 0, 19, 186 // change this to your version
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP {
BLOCK "StringFileInfo" {
BLOCK "040904B0" { // 0x409 = U.S. English, 0x04B0 = dec 1200 = Unicode
VALUE "CompanyName", "Joe Blow, Inc.\0"
VALUE "FileDescription", "Joe Blow's App\0"
VALUE "FileVersion", "1.0.19.186\0" // change this to your version
VALUE "InternalName", "JoeBlow\0"
VALUE "LegalCopyright", "Copyright © 2008-2009 Joe Blow Incorporated\0"
VALUE "OriginalFilename", "JoeBlow.exe\0"
VALUE "ProductName", "Joe Blow\0"
VALUE "ProductVersion", "1.0.19.189\0" // change this to your version
}
}
BLOCK "VarFileInfo" {
VALUE "Translation", 0x409 /*U.S. English*/, 1200 /*Unicode*/
}
}
这样做的最大缺点是您必须手动将版本信息添加到资源脚本中(除非您想完全放弃版本信息)。在我的应用程序中,我添加了一个自定义构建步骤,该步骤运行我编写的程序,该程序直接在可执行文件中更新版本信息,这样我就不必手动更新资源脚本中的版本号,但该程序不适合公开发布,否则超出本文的范围。
现在您需要调用资源编译器将此资源脚本构建为二进制资源文件。将此脚本另存为 JoeBlow.rc,然后启动 Visual Studio 命令提示符。它位于 Visual Studio 开始菜单文件夹中的工具下。如果您没有安装 Visual Studio,我相信您会将 rc.exe 作为 SDK 的一部分。微软似乎也在这里提供了最新版本。
一旦在 VS cmd 提示符下(或者路径中有 rc.exe),只需键入:
rc JoeBlow.rc
就那么简单。鉴于我包含的图标存在,上述资源脚本应该可以正确编译。这将在同一目录中创建一个名为 JoeBlow.res 的新文件。现在,假设您使用的是Visual Studio,您所要做的就是编辑项目属性以包含此资源文件。
这些方向适用于 Visual Studio 2005 或 2008。我不记得如何在旧版本中执行此操作,或者即使您可以,我还没有尝试过 2010,但它可能类似。在解决方案资源管理器中右键单击项目并选择属性(或从主菜单栏上的项目菜单中选择属性)。在 Application 选项卡上,这是您应该看到的第一个选项卡,底部是一个 Resources 组框。在这里,您有两个选项:“图标和清单”或“资源文件”。选择后一个选项。这将启用文本框,您可以在其中键入(或浏览到)新资源文件 JoeBlow.res。
最后,只需构建您的项目,并且在浏览与您的应用程序关联的文件时,您已经嵌入了原生 PE 格式的图标,shell 可以访问这些图标。现在,如果您将 的值设置HKEY_CLASSES_ROOT\JoeBlowFile\DefaultIcon
为C:\Program Files\JoeBlow\JoeBlow.exe,1
(使用从零开始的索引号)或C:\Program Files\JoeBlow\JoeBlow.exe,-200
(使用资源标识符的负数,上面的 #defined as IDI_FILE
),您的图标将显示在资源管理器中用于 .jbf 文件。
要在安装后立即显示新图标,您可能需要刷新 shell 的图标缓存。我在这里找到了有关如何执行此操作的说明。基本要点是将外壳图标大小(at HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics
)从其当前值更改为不同的值,然后再更改回来,WM_SETTINGCHANGE
每次更改后广播一条消息。
祝你好运。需要帮助请叫我。