65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 文件夹元数据编辑器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (28投票s)

2021年1月3日

CPOL

6分钟阅读

viewsIcon

40115

downloadIcon

1277

使用 desktop.ini 功能编辑文件夹元数据

引言

当我想管理一堆文件夹而无需将其组织到子目录中时,出现了对文件夹元数据编辑器的需求。在网上搜索时,我发现 *desktop.ini*(以及 Windows 资源管理器)支持我正在寻找的功能——只是 Microsoft 没有提供用户界面。所以这就是文件夹元数据编辑器发挥作用的地方。它提供了一种编辑这些元数据的简单方法。

背景

*Desktop.ini* 支持文件夹的元数据,如果它包含以下内容

[{F29F85E0-4FF9-1068-AB91-08002B27B3D9}]
Prop2=31,Title
Prop3=31,Subject
Prop4=31,Author
Prop5=31,Tag
Prop6=31,Comment

为了读写,使用了 API 函数 `GetPrivateProfileString` 和 `WritePrivateProfileString`。

文件夹元数据编辑器还支持简单的参数解析和本地化。

Using the Code

代码分为以下子命名空间

  • 配置
    • 参数解析
    • 本地化
    • 注册
  • 对话框
    • 对话框表单
    • 扩展的 `ListBox` 控件
    • 表单帮助类和从资源中提取图标
  • 扩展
    • `string` 和 `StringCollection` 类的扩展
  • Generic
    • 加载/写入 *desktop.ini*
    • 通用帮助类

配置

参数解析

参数解析由 `ArgParser` 类完成,该类使用 `ParameterNames` 类。

*ParameterNames.cs* 文件包含 `ParameterNames` 类和 `ParamConstants` 枚举。

`ParameterNames` 类的 `ParseParamConstants` 函数将诸如 */dir* 等命令行参数转换为适当的 `ParamConstants` 值 `ParamConstants.Dir`。

实际的参数解析是在 `ArgParser` 类中完成的。由于这是一个 `Windows.Forms` 应用程序,我们的 `main` 函数中没有 `string[] args` 参数。因此,`ArgParser` 类有一个无参数构造函数,并通过 `using System.Environment.GetCommandLineArgs()` 检索命令行参数。

注册

由于该应用程序应与文件夹一起使用,因此我们需要在 Windows 注册表的 *HKEY_CLASSES_ROOT\Folder\shell* 下注册它。为此,我们创建一个新的注册表项 `FolderMetaData`。此项的默认值表示快捷菜单中的文本(当在 Windows 资源管理器中右键单击文件夹时)。在此注册表项下,我们创建另一个注册表项 `command`。`command` 项的默认值然后包含应用程序的完整路径以及文件夹的路径,例如,*C:\Program Files\FolderMetadata\FolderMetadata.exe /dir "%1"*"。

为了允许在右键单击文件夹背景时使用应用程序,我们在 *HKEY_CLASSES_ROOT\Directory\Background\shell* 下创建另一个注册表项。过程与之前相同。唯一的区别是这里我们不使用 `%1` 作为参数,而是使用 `%V`。

取消注册时,通过检查 `command` 注册表项的默认值来识别注册表项。这允许即使使用不同语言创建了注册表项,也可以将其删除。

注册和取消注册由 `Registrator` 类完成。您需要管理权限才能成功执行这些操作。

在命令行上,使用以下命令注册或取消注册

  • FolderMetadata.exe /register
  • FolderMetadata.exe /unregister

本地化

本地化由 `LanguageConfigurator` 类处理。在大多数情况下,它只会使用其运行环境的语言。但是,您也可以通过指定 */lang* 命令行参数(例如,对于日语,`/lang ja`)或通过指定命令行参数 `/lang select` 来选择它来更改语言。为了让语言选择对话框显示所有支持的语言列表,`SupportedLanguages` 类的 `GetSupportedLanguages` 函数必须包含它。

如果您处理字母语言,`Windows.Forms` 应用程序的本地化非常简单。当处理非字母语言(例如中文和日语)时,这会变得更具挑战性。

  1. 速记符支持(按钮的键盘快捷键,例如 `&Save`)将不存在
  2. 处理简体和繁体中文本地化

由于我想保持本地化过程简单,我将大部分工作留给了 .NET Framework。因此,我将 `FolderMetadata` 项目的 `Neutral language` 属性设置为“`English (United States)`”。并创建了一个单独的资源文件 *Strings.resx*。此文件包含所有翻译 + 值 `ForceMnemonics`,它表示一个 `bool` 值,并且 **必须** 是 `true` 或 `false`。解析结果可在 `LanguageConfigurator` 类的 `ForceShowMnemonics` 属性中访问。

对于中文本地化,我创建了两个资源文件

  • Strings.zh.resx
  • Strings.zh-TW.resx

这意味着所有用户(除了那些使用台湾 Windows 设置的用户)都会看到简体中文字符。但是,这不适用于来自香港和澳门的用户。所以我添加了函数 `GetLanguageZH`,它检查语言设置是否需要显示繁体中文。如果需要,它会将语言设置更改为 `zh-TW`。现在用户也可以看到繁体中文字符了。

对话框

翻译对话框

当表单复杂时,设置表单的 `Localizable` 和 `Language` 属性可能是一个好方法。这允许例如为每种语言重新排列控件。但是,如果您有许多语言,这会使编辑对话框变得更加困难。这就是我决定不采用这种方法并采用更实用的方法的原因:使用 `TableLayoutPanel` 和支持类 `ButtonAdjustor` 使按钮具有相同的宽度。

每个表单都有一个 `WndProc` 重写。在这个重写函数中,我们检查 `LanguageConfigurator` 类的 `ForceShowMnemonics` 属性是否为 `true`。如果是,它将调用 `WndProcOverrides` 类的 `ShowMnemonics` 方法,该方法确保助记符可见。

帮助

表单 `FrmHelp` 包含 HTML 格式的帮助。它也被翻译成各种语言,并在用户执行以下操作之一时打开

  • 不指定任何支持的参数启动应用程序(例如,在 Windows 资源管理器中双击)
  • 指定 `/?` 命令行参数

控件

`ListBoxEx 控件` 继承自 `Windows.Forms` 的 `ListBox`。它提供了一些用于加载值(在 `FrmMain` 表单上使用)和移动选定项(在 `FrmManage` 表单上使用)的函数。

扩展

如果您之前没有使用过扩展,那么您错过了一个非常有用的 .NET 功能。扩展允许您将自己的函数添加到类中。只有一个缺点:您只能添加实例函数,而不能添加 `static` 函数,例如 `string.IsNullOrEmpty`。

定义

public static class String
{
    public static bool IsEmpty(this string s)
    {
        return (s.Length == 0);
    }
}

用法

using HKS.FolderMetadata.Extensions; //Add this on top of your class file,
                                     //preceding the name space definition.

//In your method, use something like this:

string s = "Hello";

if (s.IsEmpty())
{
  //Do something
}

Generic

读写 Desktop.ini

读写 *desktop.ini* 的功能在 `Metadata` 类中。由于此程序旨在用于 Windows 平台,我们可以使用 API 函数 `GetPrivateProfileString` 和 `WritePrivateProfileString` 进行读写。

在 *desktop.ini* 中,所有元数据属性都是单行文本。由于可能不止一个人是作者(例如,披头士的歌曲总是由约翰·列侬和保罗·麦卡特尼创作),或者您想设置多个标签,我们必须将单行转换为列表,反之亦然。

`Metadata` 类的构造函数期望要编辑元数据的目录的完整路径。然后它将组装 *desktop.ini* 的完整路径。该类具有由 `Load` 方法填充并通过 `Save` 方法写入文件的属性。

历史

  • 2021年1月3日
    • 首次发布
  • 2021年7月15日
    • 版本 1.0.1
      • 修复了内存异常
  • 2024年2月24日
    • 版本 2.0.0
      • 允许右键单击文件夹背景以启动应用程序
      • 为快捷菜单添加了图标
© . All rights reserved.