
#region 版权信息
/* ==============================================================================
* 文 件 名: ChmHelp
* 功能描述:Chm编译封装类
* Copyright (c) 2013 武汉经纬视通科技有限公司
* 创 建 人: alone
* 创建时间: 2012/12/05 20:53:29
* 修 改 人: alone
* 修改时间: 2013/3/01 18:22:03
* 修改描述: 使用hha.dll接口方法
* 版 本: v1.0.0.0
* ==============================================================================*/
#endregion
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using Chen.Ext;
/* 变量含义 rootPath:待编译的文件夹 rootParent:rootPath的父目录
* 1.将rootPath目录下的文件编译成CHM。
* 2.将编译过程中产生的hhp、hhc、hhk文件均放在rootParent下。
* 3.基于rootParent,获取待编译文件的相对路径(相对rootParent)。
*/
namespace Chen.Common
{
/// <summary>
/// Chm辅助类
/// </summary>
public class ChmHelp
{
#region 成员定义
//Chm文件保存路径
public string ChmFileName { get; set; }
//Chm文件Titie
public string Title { get; set; }
//编译文件夹路径
public string RootPath
{
get { return rootPath; }
set
{
rootPath = Path.GetFullPath(value);
//获取上级目录的完整路径
//指定文件夹的父目录是作为关键字被文件的完整路径替换的,此时目录必须携带\\
DirectoryInfo di = new DirectoryInfo(rootPath);
rootParent = di.Parent.FullName + "\\";
}
}
//默认页面 相对编译文件夹的路径
public string DefaultPage
{
get//编译时路径是相对rootParent
{
var rootName = Path.GetFileName(rootPath);
return rootName + "\\" + defaluePage;
}
set //赋值时路径是相对rootPath。
{
defaluePage = value;
}
}
public int FileCount { get { return fileCount; } }
//私有变量
private string rootParent;
private string rootPath;
private string defaluePage;
private int fileCount = 0;
//CHM相关文件内容
private StringBuilder hhcBody = new StringBuilder();
private StringBuilder hhpBody = new StringBuilder();
private StringBuilder hhkBody = new StringBuilder();
private bool deleteTmp = true;
//日志信息
private StringBuilder sbMessage = new StringBuilder();
public event Action<string> logHandle;
#endregion
#region hha 方法引入
[DllImport("hha.dll")]
private extern static void HHA_CompileHHP(string hhpFile, CompileLog g1, CompileLog g2, int stack);
delegate bool CompileLog(string log);
//编译信息
private bool CompileLoging(string log)
{
if (logHandle != null) logHandle(log);
return true;
}
private bool CompileProcess(string log)
{
return true;
}
#endregion
#region 构造所需要的文件
private void Create(string path)
{
//获取文件
var strFileNames = Directory.GetFiles(path);
//获取子目录
var strDirectories = Directory.GetDirectories(path);
//给该目录添加UL标记
if (strFileNames.Length > 0 || strDirectories.Length > 0)
hhcBody.AppendLine(" <UL>");
//处理获取的文件
foreach (string filename in strFileNames)
{
var fileItem = new StringBuilder();
fileItem.AppendLine(" <LI> <OBJECT type=\"text/sitemap\">");
fileItem.AppendLine(" <param name=\"Name\" value=\"{0}\">".FormatString(Path.GetFileNameWithoutExtension(filename)));
fileItem.AppendLine(" <param name=\"Local\" value=\"{0}\">".FormatString(filename.Replace(rootParent, string.Empty)));
fileItem.AppendLine(" <param name=\"ImageNumber\" value=\"11\">");
fileItem.AppendLine(" </OBJECT>");
//添加文件列表到hhp
hhpBody.AppendLine(filename);
hhcBody.Append(fileItem.ToString());
hhkBody.Append(fileItem.ToString());
//记录待编译文件总数
fileCount++;
}
//遍历获取的目录
foreach (string dirname in strDirectories)
{
if (dirname.Contains("content") || dirname.Contains("image")) continue;
hhcBody.AppendLine(" <LI> <OBJECT type=\"text/sitemap\">");
hhcBody.AppendLine(" <param name=\"Name\" value=\"{0}\">".FormatString(Path.GetFileName(dirname)));
hhcBody.AppendLine(" <param name=\"ImageNumber\" value=\"1\">");
hhcBody.AppendLine(" </OBJECT>");
//递归遍历子文件夹
Create(dirname);
}
//给该目录添加/UL标记
if (strFileNames.Length > 0 || strDirectories.Length > 0)
{
hhcBody.AppendLine(" </UL>");
}
}
private void CreateHHC()
{
var code = new StringBuilder();
code.AppendLine("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">");
code.AppendLine("<HTML>");
code.AppendLine("<HEAD>");
code.AppendLine("<meta name=\"GENERATOR\" content=\"EasyCHM.exe www.zipghost.com\">");
code.AppendLine("<!-- Sitemap 1.0 -->");
code.AppendLine("</HEAD><BODY>");
code.AppendLine("<OBJECT type=\"text/site properties\">");
code.AppendLine(" <param name=\"ExWindow Styles\" value=\"0x200\">");
code.AppendLine(" <param name=\"Window Styles\" value=\"0x800025\">");
code.AppendLine(" <param name=\"Font\" value=\"MS Sans Serif,9,0\">");
code.AppendLine("</OBJECT>");
//遍历文件夹 构建hhc文件内容
code.Append(hhcBody.ToString());
code.AppendLine("</BODY></HTML>");
//File.WriteAllText(Path.Combine(SourcePath, "chm.hhc"), code.ToString(), Encoding.GetEncoding("gb2312"));
File.WriteAllText(".//chm.hhc", code.ToString(), Encoding.GetEncoding("gb2312"));
}
private void CreateHHP()
{
var code = new StringBuilder();
code.AppendLine("[OPTIONS]");
code.AppendLine("CITATION=Made by Chen");//制作人
code.AppendLine("Compatibility=1.1 or later");//版本
code.AppendLine(@"Compiled file=" + ChmFileName);//生成chm文件路径
code.AppendLine("Contents file=chm.HHC");//hhc文件路径
code.AppendLine("COPYRIGHT=www.jinwin.com");//版权所有
code.AppendLine(@"Default topic={1}");//CHM文件的首页
code.AppendLine("Default Window=Main");//目标文件窗体控制参数,这里跳转到Windows小节中,与其一致即可
code.AppendLine("Display compile notes=Yes");//显示编译信息
code.AppendLine("Display compile progress=Yes");//显示编译进度
//code.AppendLine("Error log file=error.Log");//错误日志文件
code.AppendLine("Full-text search=Yes");//是否支持全文检索信息
code.AppendLine("Index file=chm.HHK");//hhk文件路径
code.AppendLine("Title={0}");//CHM文件标题
//code.AppendLine("Flat=NO");//编译文件不包括文件夹
code.AppendLine("Enhanced decompilation=yes");//编译文件不包括文件夹
code.AppendLine();
code.AppendLine("[WINDOWS]");
//例子中使用的参数 0x20 表示只显示目录和索引
code.AppendLine("Main=\"{0}\",\"chm.hhc\",\"chm.hhk\",\"{1}\",\"{1}\",,,,,0x63520,180,0x104E, [0,0,745,509],0x0,0x0,,,,,0");
//Easy Chm使用的参数 0x63520 表示目录索引搜索收藏夹
//code.AppendLine("Main=\"{0}\",\"chm.HHC\",\"chm.HHK\",\"{1}\",\"{1}\",,,,,0x63520,271,0x304E,[0,0,745,509],,,,,,,0");
code.AppendLine();
code.AppendLine("[MERGE FILES]");
code.AppendLine();
code.AppendLine("[FILES]");
code.Append(hhpBody.ToString());
// File.WriteAllText(Path.Combine(SourcePath, "chm.hhp"), code.ToString().FormatString(Title, DefaultPage), Encoding.GetEncoding("gb2312"));
File.WriteAllText(".//chm.hhp", code.ToString().FormatString(Title, DefaultPage), Encoding.GetEncoding("gb2312"));
}
private void CreateHHK()
{
var code = new StringBuilder();
code.AppendLine("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">");
code.AppendLine("<HTML>");
code.AppendLine("<HEAD>");
code.AppendLine("<meta name=\"GENERATOR\" content=\"EasyCHM.exe www.zipghost.com\">");
code.AppendLine("<!-- Sitemap 1.0 -->");
code.AppendLine("</HEAD><BODY>");
code.AppendLine("<OBJECT type=\"text/site properties\">");
code.AppendLine(" <param name=\"ExWindow Styles\" value=\"0x200\">");
code.AppendLine(" <param name=\"Window Styles\" value=\"0x800025\">");
code.AppendLine(" <param name=\"Font\" value=\"MS Sans Serif,9,0\">");
code.AppendLine("</OBJECT>");
code.AppendLine("<UL>");
//遍历文件夹 构建hhc文件内容
code.Append(hhkBody.ToString());
code.AppendLine("</UL>");
code.AppendLine("</BODY></HTML>");
//File.WriteAllText(Path.Combine(SourcePath, "chm.hhk"), code.ToString(), Encoding.GetEncoding("gb2312"));
File.WriteAllText(".//chm.hhk", code.ToString(), Encoding.GetEncoding("gb2312"));
}
#endregion
/// <summary>
/// 编译
/// </summary>
/// <returns></returns>
public void Compile()
{
//准备hhp hhc hhk文件
Create(RootPath);
CreateHHC();
CreateHHK();
CreateHHP();
var path = ".//chm.hhp";
HHA_CompileHHP(path, CompileLoging, CompileProcess, 0);
DeleteTmpFile();
}
/// <summary>
/// 使用hhc.exe进行编译 暂时不使用该方式 局限性较大
/// </summary>
/// <param name="hhpPath"></param>
private void CompileByHHC(string hhpPath)
{
var hhcPath = string.Empty;
var program = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
if (File.Exists(".//hhc.exe"))
{
hhcPath = ".//hhc.exe";
}
else if (File.Exists(program + @"\HTML Help Workshop\hhc.exe"))
{
hhcPath = program + @"\HTML Help Workshop\hhc.exe";
}
else if (File.Exists(program + @" (x86)\HTML Help Workshop\hhc.exe"))
{
hhcPath = program + @" (x86)\HTML Help Workshop\hhc.exe";
}
else
{
throw new Exception("未找到编译核心文件hhc.exe");
}
var process = new Process();//创建新的进程,用Process启动HHC.EXE来Compile一个CHM文件
try
{
ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.WindowStyle = ProcessWindowStyle.Hidden;
processInfo.FileName = hhcPath; //调入HHC.EXE文件
processInfo.Arguments = hhpPath;
processInfo.UseShellExecute = false;
processInfo.CreateNoWindow = false;
process.StartInfo = processInfo;
process.Start();
process.WaitForExit(); //组件无限期地等待关联进程退出
if (process.ExitCode == 0)
{
throw new Exception("编译发生异常!");
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
process.Close();
}
}
/// <summary>
/// 反编译
/// </summary>
/// <returns></returns>
public bool DeCompile()
{
//反编译时,Path作为CHM文件路径
//得到chm文件的绝对路径
string ExtportPath = Path.GetDirectoryName(ChmFileName);
//命令参数含义
//Path:导出的文件保存的路径
//ChmPath:Chm文件所在的路径
string cmd = " -decompile " + ExtportPath + " " + ChmFileName;//反编译命令
Process p = Process.Start("hh.exe", cmd);//调用hh.exe进行反编译
p.WaitForExit();
return true;
}
//删除临时文件
private void DeleteTmpFile()
{
if (deleteTmp)
{
var arr = new string[] { ".//chm.hhc", ".//chm.hhp", ".//chm.hhk" };
foreach (var a in arr)
{
if (File.Exists(a))
{
File.Delete(a);
}
}
}
}
}
}
