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

检查帮助链接工具

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.97/5 (11投票s)

2004 年 8 月 16 日

CPOL

6分钟阅读

viewsIcon

89462

downloadIcon

17289

用于检查合并帮助 (CHM) 文件中链接的工具。

注意:如果您只安装了 .NET 可再发行程序包,但没有安装 SDK(或 VS),则需要 MSHTML 库。

Application image

引言

本文介绍了一个用于检查帮助 (CHM) 文件(包括合并文件)中链接的工具。该应用程序会检查索引、目录和主题文件本身中的链接,并将结果显示在一个简单的树状视图中。

背景

我有一个使用 XML 注释记录的库。我使用 NDoc[^] 来为库参考帮助生成 CHM 文件,但我还有一个手动编写的“主”CHM 文件,其中包含更高级别的帮助。我合并了这两个帮助文件,它们都包含指向对方的链接。我找不到一个可以检查这些链接的工具,于是我写了一个 :)

实际上,这个工具写起来相当容易,因为它本质上是 Klaus Weisser[^] 的 HtmlHelp 库和示例查看器[^] 的一个前端。读取 CHM 文件的所有细节都由该库处理,这意味着我只需要编写用户界面和检查算法。

基本上,如果您需要此工具,它将非常有价值;如果您不需要,那么,感谢您的浏览。

使用应用程序

该应用程序非常易于使用——至少我是这样尝试让它变得易于使用的。

首先要做的是打开一个 CHM 文件。这将把文件和任何合并的文件加载到库中,并开始填充结果树。您可以随时刷新文件以返回到此状态。此时,索引、目录和主题文件都已存在,但主题文件中的链接尚未加载。

事实证明,获取 HTML 文件中的链接并非易事。我找到的关于此主题的唯一文章是在 MSDN 上:Walkthrough: Accessing the DHTML DOM from C#[^]。这篇文章基本上说要打开一个 IE 窗口,加载文件,然后从 DOM 中获取链接。这很。如果您的 CHM 文件有数千页,这会非常慢。但是,这是最准确的方法,因此是默认方法。

通过在工具栏上选择“快速解析”选项,您可以将速度提高几个数量级。这使用正则表达式来搜索原始 HTML。这对于简单的 HTML 有效,但不完美,尽管它现在会排除注释块。它可用作初步检查,但我建议在发布帮助文件之前使用较慢的方法进行检查。

现在您已经选择了解析方法,可以通过单击“工作”工具栏按钮或按 Ctrl+W 来开始检查。此过程会加载和解析所有主题文件,并检查找到的所有链接。此过程在树视图中选定的子树上进行。默认情况下,会选择根节点,因此会检查整个帮助集合,但如果您只对某个分支感兴趣,则可以选择树的一部分。结果通过设置每个树视图项的图标来显示。

结果中的每个项都有一个状态,可以是“未知”、“良好”、“http”、“script”或“损坏”。父项的状态根据其子项的状态设置。因此,只有当其所有子项均标记为良好时,父项才会被标记为良好。这样可以快速了解链接的正确性,并且详细的度量标准会显示在每个项后面的括号中。

然后,您可以使用包括正则表达式在内的全面查找功能来导航结果

Find dialog image

您还可以将结果导出到 CSV 文件。这将生成一个总体摘要文件,以及每个 CHM 文件的详细信息文件。

所有这些都可以通过命令行选项进行自动化。它们是:

  • -f / -fast: 选择快速模式
  • -s / -slow: 选择慢速模式
  • -o / -open: 打开最近使用的 CHM
  • -o:"C:\path\xxx.chm": 打开指定的 CHM
  • -w / -work: 检查文件
  • -x / -export: 将报告导出到默认文件夹
  • -x:"C:\path\folder": 导出到指定文件夹
  • -c / -close: 关闭应用程序

例如:CheckHelpLinks.exe -f -o:"C:\test\test.chm" -w -x -c

如果没有任何错误,应用程序的退出代码为零;如果存在损坏的链接,则为非零。

就这些。去修复您损坏的链接,然后再次检查!

关注点

反射魔法

我需要访问库中声明为 internal 的属性。显然,这通常在库外部是不可用的,但您可以使用反射来访问它。这是一种非常强大的做法,但并非理想:库作者在未来的版本中更改其内部实现是完全正确的,这可能会破坏客户端代码。因此,请自行承担风险!

此代码来自 ClassesIndex.cs 文件中的 IndexItem.Load 方法。

我想写的是这个

    CHMFile chmFile = indexItem.ChmFile;

我实际写的是这个

    Type t = indexItem.GetType();
    PropertyInfo p = t.GetProperty( "ChmFile",
        BindingFlags.Instance | BindingFlags.NonPublic );
    CHMFile chmFile = ( CHMFile ) p.GetValue( indexItem, null );

访问 DHTML DOM

我找到的唯一访问 DOM 的方法是打开一个 Web 浏览器控件,加载 HTML,然后从控件的 Document 属性获取一个 IHTMLDocument2 对象。除了速度慢之外,这有点棘手,因为加载过程是异步的。我通过在开始导航之前设置一个标志,并等待直到 DocumentComplete 事件处理程序清除该标志来解决这个问题。在等待期间,我调用 Application.DoEvents 来保持 UI 的刷新。我不知道这效果如何,因为这一切都发生在一个对话框中;我真正想要的是运行对话框的消息循环,但我找不到这样做的方法 :(.如果您想查看,代码在 DlgBrowser.cs 文件中。

正则表达式

这些是快速模式下使用的 RegEx。对于锚点和链接,有两个 RegEx,它们分别查找带有引号和不带引号的元素。

  • 注释:^(?<before>.*)(?<comment><!--.*?-->)(?<after>.*)$
  • 锚点 1:<\s*A\s[^>]*name\s*=\s*(?<anchor>[^'"].*?)[\s>]
  • 锚点 2:<\s*A\s[^>]*name\s*=\s*(?<quote>['"])(?<anchor>.*?)\k<quote>
  • 链接 1:<\s*(?:A|AREA)\s[^>]*href\s*=\s*(?<url>[^'"].*?)[\s>]
  • 链接 2:<\s*(?:A|AREA)\s[^>]*href\s*=\s*(?<quote>['"])(?<url>.*?)\k<quote>

参考文献

致谢

特别感谢 Klaus Weisser[^] 提供的出色库和在编写此文过程中提供的帮助。

此外,感谢 **Ryan Pollack** 在 v2 版本中的帮助。

再次感谢 Karen Story[^] 和 Dmitri Posudin[^] 在 v3 版本中的帮助。

历史

  • 版本 3:2005 年 9 月 30 日
    • 高级查找功能
    • 现已处理锚点(书签)
    • 快速模式下的 RegEx 已改进
    • 在快速模式下剥离注释块
    • 结果导出到 CSV 文件
    • 直接查看任何链接的源代码
    • JavaScript 链接单独处理
    • 已添加命令行选项
    • 现在能正确处理更多格式的链接
    • 新图标
  • 版本 2:2005 年 8 月 20 日
    • 现已处理指向没有 'ms-its' 前缀的 CHM 文件的链接
    • 现已处理指向外部(未合并)CHM 文件的链接
    • CHM 文件中的 HTTP 链接单独计数
    • 几个 bug 修复
  • 版本 1:2004 年 8 月 16 日
    • 首次发布
© . All rights reserved.