【问题标题】:HTML Help Workshop returns error after successfully compiled .chm file成功编译 .chm 文件后 HTML Help Workshop 返回错误
【发布时间】:2016-12-25 01:14:14
【问题描述】:

在我使用 HTML Help Workshophhc.exe 成功编译了一个 .chm 文件后,我遇到了一个非常奇怪的失败。

我使用 Doxygen 创建了我的源代码文档。如果您在 doxygen 文件中启用 GENERATE_HTMLHELPDoxygen 会创建:

如果 GENERATE_HTMLHELP 标签设置为 YES 则 doxygen 生成三个
其他 HTML 索引文件:index.hhp、index.hhc 和 index.hhk。 index.hhp
是一个项目文件,可以在 Windows 上被 Microsoft 的 HTML Help Workshop(参见:
http://www.microsoft.com/en-us/download/details.aspx?id=21138)读取。

Doxygen 创建这些文件后,我想用HTML Help Workshop 创建 .chm 文件。出于这个原因,我在 CMD 中调用 hhc.exe。之后我可以打开 .chm 文件,一切似乎都很好。但是如果我向 CMD 询问当前的errorlevel,它会输出:

"C:\Program Files (x86)\HTML Help Workshop\hhc.exe" index.hhp
Microsoft HTML Help Compiler 4.74.8702

Compiling C:\... folder path ...\index.chm

Compile time: 0 minutes, 0 seconds
37      Topics
346     Local links
12      Internet links
0       Graphics

Created C:\... folder path ...\index.chm, 88,740 bytes
Compression decreased file by 194,682 bytes.

echo %errorlevel%
1

有没有人知道 h... 出了什么问题,以及如何避免编译成功但仍然返回错误的问题?我怎样才能找出问题所在而不是错误“1”?

问题是我的构建服务器(TFS2015)返回错误,构建失败。

【问题讨论】:

  • 这是一个经常出现的问题,它来自于 hhc.exe,它返回了一个非预期的返回值。您使用的是哪个版本的 doxygen,您是从 withing doxygen 中使用 hhc.exe 还是单独使用?
  • Doxygen 的版本:1.8.11,我单独运行它(构建脚本并在 CMD 中可重复)。两者的行为相同。
  • 如果你在 doxygen 中运行它会发生什么?或者这不可能。在后一种情况下,您会忽略构建脚本文件中的错误代码。
  • 如果我在 doxyfile 中运行它,它将是相同的行为。 .chm 将被创建,但我的构建将失败
  • 只是为了弄清楚“如果我在 doxyfile 中运行它,它将是相同的行为”部分,您尝试过还是这是一个猜测(公式看起来像最后一个)?跨度>

标签: cmd doxygen html-help-workshop


【解决方案1】:

HTML Help Workshop 安装了 2 个主要的可执行文件:

  1. hhc.exe 是 HTML 帮助编译器的控制台版本。
  2. hhw.exe 是 HTML 帮助编译器的 Windows GUI 版本。

但是 HTML 帮助项目 (hhp) 到 Compiled HTML (chm) 的编译并不是由这两个可执行文件直接完成的。

两者都用于编译 hha.dll - HTML 帮助作者库 - 通过调用导出的函数 HHA_CompileHHP

这个库的导出函数有:

  • EditHhCtrlObject
  • EditHhCtrlScript
  • FreeFilterDIB
  • HHA_CompileHHP
  • 加载过滤器图像
  • 加载Jpeg

据我所知,微软尚未发布任何文档或这些函数的函数声明。

假设通过对hhc.exe 的一些快速测试,函数HHA_CompileHHP 的返回类型为BOOL,即int 并在成功时返回TRUE,即值@ 987654330@,失败时FALSE,即值0。看起来hhc.exe 使用了这个返回值,而没有将值反转为退出/返回代码。

因此,errorlevel 在成功时为 1,在失败时为 0

我为验证我的假设所做的测试:

  1. 使用不存在的项目文件名运行 HTML 帮助编译器:

    hhc.exe index_1.hhp
    

    无法打开 index_1.hhp。

    退出码errorlevel分别为0。此错误信息由hhc.exe打印,因为该错误信息可以在hhc.exe中找到。

  2. 在已存在的输出文件index.chm 上设置只读文件属性并运行 HTML 帮助编译器:

    attrib +r index.chm & hhc.exe index.hhp & attrib -r index.chm
    

    HHC5010:错误:无法打开“C:... 文件夹路径 ...\index.chm”。编译停止。

    退出代码errorlevel分别为0。此错误消息由hha.dll打印,因为此错误消息只能在hha.dll中找到。

  3. 重命名在index.hhp 中明确指定的 *.htm 文件并运行 HTML 帮助编译器:

    ren "file.htm" "renamed file.htm" & hhc.exe index.hhp & ren "renamed file.htm" "file.htm"
    

    Microsoft HTML 帮助编译器 4.74.8702

    编译 C:... 文件夹路径 ...\index.chm

    HHC5003:错误:编译 file.htm 时编译失败。

    以下文件未编译:
    file.htm

    退出代码errorlevel 分别为0。此错误消息也由hha.dll 打印,因为此错误消息也只能在hha.dll 中找到。

所有错误消息都是为了处理 STDOUT 而不是像控制台应用程序那样典型地写入 STDERRerrorlevel 没有分配比 0 或 1 以外的其他值,这就是我认为函数 HHA_CompileHHP 返回一个简单布尔值的原因。

结论:

必须采取与往常相反的方式来评估 HTML 帮助编译的成功/失败,例如在批处理文件中使用:

"%ProgramFiles(x86)%\HTML Help Workshop\hhc.exe" index.hhp
if not errorlevel 1 exit /B 1

[OPTIONS] 部分的HTML 帮助项目文件(*.hhp 文件)中,可以使用Error log file=... 指定一个日志文件,HHA_CompileHHP 输出的所有消息都写入其中另外打印他们到STDOUT

但在这种情况下 Doxygen 生成 *.hhp 文件,将批处理文件中的 STDOUT 重定向到日志文件会更容易,尽管这也不是真的需要,因为 Team Foundation Server 很可能正在将消息捕获到日志中。 (我没有安装 Team Foundation Server。)

【讨论】:

  • 感谢 Mofi,感谢您的验证。我添加了一个命令,如果错误级别为 1,它将成功。
【解决方案2】:

HTML Workshop 是一个 GUI 程序。当交互式使用 CMD 时,它不会等待 GUI 程序退出。因此没有错误代码。

Echo %errorlevel% 也不会以交互方式显示错误代码。

这两种方式会

Dir && Echo Success || Echo Failure

Dir df:\ & Echo %errorlevel%

[查看我在Trouble with renaming folders and sub folders using Batch 的回答以了解其含义]

您必须阅读 HTML Workshop 的文档以查看它是否设置了错误级别。大多数 GUI 程序都不会打扰。

【讨论】:

  • 评论前先看看他的屏幕截图。
  • 我很困惑……在我看来他的 errorlevel=1。
  • 我的错误级别 = 1!正如你在我的截图中看到的那样