遇到doxygen生成的chm文档目录如果有中文是乱码?

原因不在于doxygen,它没有问题,问题出在微软的HTML Help Workshop的hhc.exe不支持utf8.所以要解决这个问题,需要做两个额外的步骤:

1.将html/index.hhp中的Language=0x409 English (United States)换成Language=0x804 中文 (中国),并将文本存成UTF8格式。

2.将html/index.hhc整个文件从UTF8编码换成gb2312,再次手动调用hhc.exe去处理这个hhp文件即可生成不是乱码的中文chm帮助文档。

我自己用C#写了个小工具来处理这个过程,源代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Diagnostics;

namespace Generator
{
    class Program
    {
        
        static void Main(string[] args)
        {
            if(args.Length <=0)
            {
                Console.WriteLine("Error:缺少目标配置文件");
                return;
            }

            string path = args[0];

            if(!File.Exists(path))
            {
                Console.WriteLine(string.Format("{0}不存在", path));
                return;
            }

            using(ChmGenerator generator = new ChmGenerator(path))
            {
                generator.Generate();
            }            
        }
    }

    public class ChmGenerator : IDisposable
    {
        static readonly string HHC_CONFIG_LOCATION = "HHC_LOCATION           = \"C:/Program Files (x86)/HTML Help Workshop/hhc.exe\"";

        string WorkDirectory;
        string InputFile;
        string ConfigText;
        string NewHHCConfig;
        string NewConfigText;
        string NewConfigPath;

        string HHCLocation;
        string DoxygenPath;

        string IntermediatePath;
        string IntermediateHHP;
        string IntermediateHHC;

        public ChmGenerator(string inputFile)
        {
            InputFile = inputFile;

            string Directory = Path.GetDirectoryName(InputFile);
            WorkDirectory = Directory;

            System.IO.Directory.SetCurrentDirectory(WorkDirectory);

            HHCLocation = Path.Combine(Directory, "hhc.exe");
            DoxygenPath = Path.Combine(Directory, "doxygen.exe");
            IntermediatePath = Path.Combine(Directory, "Intermediate");
            IntermediateHHP = Path.Combine(IntermediatePath, @"html/index.hhp");
            IntermediateHHC = Path.Combine(IntermediatePath, @"html/index.hhc");
            NewHHCConfig = string.Format("HHC_LOCATION           = \"{0}\"", HHCLocation);
        }

        public void Dispose()
        {
            try
            {
                if (!string.IsNullOrEmpty(NewConfigPath) && File.Exists(NewConfigPath))
                {
                    File.Delete(NewConfigPath);
                }
            }
            finally
            {

            }
        }

        public void Generate()
        {
            ConfigText = File.ReadAllText(InputFile, Encoding.UTF8);

            NewConfigPath = Path.Combine(WorkDirectory, Guid.NewGuid().ToString() + ".doxygenProj");
            NewConfigText = ConfigText.Replace(HHC_CONFIG_LOCATION, NewHHCConfig);

            File.WriteAllText(NewConfigPath, NewConfigText, Encoding.UTF8);

            // 调用doxygen来生成
            StartProc(DoxygenPath, string.Format(" {0}", NewConfigPath));

            if(!PrepareInputFiles())
            {
                Console.WriteLine("无法正确生成chm");
                return;
            }

            // 调用hhc生成chm
            StartProc(HHCLocation, string.Format(" {0}", IntermediateHHP));
            
        }

        private bool PrepareInputFiles()
        {
            // 替换Language
            if (File.Exists(IntermediateHHP))
            {
                ReplaceFileText(IntermediateHHP, "Language=0x409 English (United States)", "Language=0x804 中文 (中国)", Encoding.UTF8);

                if (File.Exists(IntermediateHHC))
                {
                    ChangeFileToAnsi(IntermediateHHC, Encoding.UTF8, Encoding.GetEncoding("gb2312"));

                    return true;
                }
                else
                {
                    Console.WriteLine(string.Format("Error:{0}不存在", IntermediateHHC));
                }
            }
            else
            {
                Console.WriteLine(string.Format("Error:{0}不存在", IntermediateHHP));
            }

            return false;
        }

        private void ChangeFileToAnsi(string inputPath, Encoding sourceEncoding, Encoding destEncoding)
        {
            var text = File.ReadAllText(inputPath, sourceEncoding);
            byte[] bytes = sourceEncoding.GetBytes(text);

            // convert to win bytes
            var destBytes = Encoding.Convert(
                sourceEncoding, destEncoding, bytes);

            File.WriteAllBytes(inputPath, destBytes);
        }

        private void ReplaceFileText(string inputPath, string sourceText, string destText, Encoding encoding)
        {
            var text = File.ReadAllText(inputPath, Encoding.UTF8);
            text = text.Replace(sourceText, destText);
            File.WriteAllText(inputPath, text, encoding);
        }


        static void StartProc(string application, string command)
        {
            Debug.Assert(File.Exists(application));

            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = application,
                    Arguments = " " + command,
                    RedirectStandardOutput = true,
                    UseShellExecute = false,
                    WindowStyle = ProcessWindowStyle.Hidden,
                    CreateNoWindow = true,
                    StandardOutputEncoding = Encoding.UTF8
                }
            };

            process.Start();

            while (!process.StandardOutput.EndOfStream)
            {
                string line = process.StandardOutput.ReadLine();

                Console.WriteLine(line);
               // Debug.WriteLine(line);
            }

            process.WaitForExit();
        }
    }
}

另外为了确保目标机器没有安装doxygen或者hhc都不影响我生成文档,因此我将这些执行档都复制了一份放到了doxygen项目下,代码中的一些额外步骤就是强行将原始project文件中的hhc路径改成当前目录下的hhc。

目录结构如下:

posted @ 2020-01-10 15:09  bodong  阅读(289)  评论(0编辑  收藏