C# 如何生成CHM幫助文件


    前一段時間應公司要求,讓我開發一個數據庫字段信息CHM幫助文件生成軟件。結果當時我就二了,這個東西我只用過,不知道咋做啊。沒想到老大很隨意說一句:"沒事,這個軟件我之前有有源碼,只不過現在不能用了,你等會參考一下就可以了"。我當時還傻乎乎的謝天謝地,總算有源碼可以參考了。當源代碼發過來以后,我頓時石化了,我。。。。。,那玩意兒用c++builder開發的,硬着頭皮看了一遍,全是帶*指針變量、數組、集合、函數,更要命的是,一個類里面寫了四五千行沒注視的代碼,函數中五六百行代碼的有幾個。 我說這不是坑人嘛?結果看了一天后,我果斷放棄看了那個源碼了,最后還是的感謝網上活躍的一幫朋友,在一個源碼的幫助下(源碼我不知道怎么上傳,),終於完成了任務啊,

 吐槽到此為止,言歸正傳,首先如下:

生成事件

View Code
 1  /// <summary>
 2         /// 生成
 3         /// </summary>
 4         /// <param name="sender"></param>
 5         /// <param name="e"></param>
 6         private void button1_Click(object sender, EventArgs e)
 7         {
 8             try
 9             {
10                 if (!Directory.Exists("HTML"))  //判斷名為HTML文件夾是否存在,不存在的話就創建一個
11                 {
12                     Directory.CreateDirectory("HTML"); 
13                 }
14                 startPath = Application.StartupPath;//起始路徑
15                 OpenHhp(_defaultTopic);//打開hhp文件
16                 OpenHhc(_defaultTopic);//打開hhc文件
17                 OpenHhk();//打開hhk文件
18                 Compile();
19                 MessageBox.Show("生成成功!");
20             }
21             catch (Exception ex)
22             {
23                 MessageBox.Show("生成失敗!");
24                 throw;
25             }
26           
27         }

從方法中我可以看出,我們需要一個hhp文件,hhc文件,hhk文件,然后再執行compile方法就可以了

首先動態生一個hhp,代碼如下:

 

 1   /// <summary>
 2         /// 創建hhp文件
 3         /// </summary>
 4         /// <param name="htmFile">htm文件名</param>
 5         public void OpenHhp(string htmFile)
 6         {
 7             FileStream fs = new FileStream("test.hhp", FileMode.Create); //創建hhp文件
 8             streamWriter = new System.IO.StreamWriter(fs, System.Text.Encoding.GetEncoding("GB18030"));
 9             
10 
11             streamWriter.WriteLine("[OPTIONS]");
12             streamWriter.WriteLine("Compatibility=1.1 or later");
13             streamWriter.WriteLine("Compiled file=" + textBox1 .Text.Trim()+ ".chm");      //定義生成文件名稱
14             streamWriter.WriteLine("Contents file=test.hhc");
15             streamWriter.WriteLine("Default topic=HTML\\全部對象.htm");
16             streamWriter.WriteLine("Display compile progress=Yes");
17             streamWriter.WriteLine("Index file=DBO_HELP.hhk");
18             streamWriter.WriteLine("Language=0x804 中文(中國)");
19             streamWriter.WriteLine("Title=數據庫結構展示");
20             streamWriter.WriteLine("      ");
21             streamWriter.WriteLine("[FILES]");
22             streamWriter.WriteLine("全部對象.htm");
23             streamWriter.WriteLine("       ");
24             streamWriter.WriteLine("[INFOTYPES]");
25             streamWriter.WriteLine(htmFile);
26             streamWriter.WriteLine();
27             streamWriter.Close();
28         }

這樣在項目的根目錄上面就生成了一個hhp文件
現在就要生成hhc文件了,它主要就是生成chm文件左邊顯示樹形的內容,當點擊節點,可以超鏈接要顯示的頁面(其實CHM中的內容都是HTML,你可以直接連接靜態網頁,),當然是顯示在右邊,而我的項目中要顯示東西都是動態生成HTML文件,所以這個生成有些復雜,不過我這里會截取主要部分代碼講解:

  private void OpenHhc(string htmFile)
 {
     StringBuilder Modes = new StringBuilder();

   FileStream fs = new FileStream(GetContentsHtmlFilename(), FileMode.Create); //創建hhp文件
            streamWriter = new System.IO.StreamWriter(fs, System.Text.Encoding.GetEncoding("GB18030"));
            FileStream fs1 = new FileStream("HTML\\全部對象.htm", FileMode.Create); //
            str1 = new System.IO.StreamWriter(fs1, System.Text.Encoding.GetEncoding("GB18030"));
           
            streamWriter.WriteLine("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">");
            streamWriter.WriteLine("<HTML>");
            streamWriter.WriteLine("<HEAD>");
            streamWriter.WriteLine("<meta name=\"GENERATOR\" content=\"Microsoft&reg; HTML Help Workshop 4.1\">");
            streamWriter.WriteLine("<!-- Sitemap 1.0 -->");
            streamWriter.WriteLine("</HEAD>");
            streamWriter.WriteLine("<BODY>");
            streamWriter.WriteLine("<OBJECT type=\"text/site properties\">");
            streamWriter.WriteLine("<param name=\"Window Styles\" value=\"0x800025\">");
            streamWriter.WriteLine("</OBJECT>");
           

            string sql = "SELECT mId,mName FROM Models";
            DataTable dt = DBHelper.getDatatable(sql);

            for (int i = 0; i < dt.Rows.Count; i++)
            {
                #region
                if (i == 0)
                    {
                        streamWriter.WriteLine("    <UL>");
                        streamWriter.WriteLine("        <LI> <OBJECT type=\"text/sitemap\">");
                        streamWriter.WriteLine("            <param name=\"Name\" value=\"數據庫服務器\">");
                        streamWriter.WriteLine("            <param name=\"Local\" value=\"HTML\\全部對象.htm\">");
                        streamWriter.WriteLine("            <param name=\"ImageNumber\" value=\"13\">");
                        streamWriter.WriteLine("            </OBJECT>");
                        streamWriter.WriteLine("    <UL>");
                       

                        Modes.Append("<!doctype html public \"-//W3C//DTD HTML 4.0 Transitional//EN\"> \r");
                        Modes.Append("<html>  \r");
                        Modes.Append("      <head>  \r");
                        Modes.Append("       <title>所有模塊</title>    \r");
                        Modes.Append("     <meta name=\"Generator\" content=\"EditPlus\">  \r");
                        Modes.Append("       <meta name=\"Author\" content=\"\"> \r");
                        Modes.Append("       <meta name=\"Keywords\" content=\"\">   \r");
                        Modes.Append("       <meta name=\"Description\" content=\"\">  \r");
                        Modes.Append("        </head> \r");
                        Modes.Append("       <body>  \r");
                        Modes.Append("       <div align=\"Center\" style=\"font-size:20px;font-width:bold;;color:green\">全部模塊</div>\r");
                        Modes.Append(" <hr color = #FF0000>");
                        Modes.Append("       <div align=\"Center\"><A href=\""+dt.Rows[i]["mName"].ToString()+".htm\">"+dt.Rows[i]["mName"].ToString()+"</A></div>\r");

                      
                    }
                    if (i > 0)
                    {
                      Modes.Append("  <br/>");
                        Modes.Append("       <div align=\"Center\"><A href=\"" + dt.Rows[i]["mName"].ToString() + ".htm\">"+dt.Rows[i]["mName"].ToString()+"</A></div>\r");
                    }
                  
                    streamWriter.WriteLine("        <LI> <OBJECT type=\"text/sitemap\">");
                    streamWriter.WriteLine("            <param name=\"Name\" value=\"" + dt.Rows[i]["mName"].ToString() + "\">");
                    streamWriter.WriteLine("            <param name=\"Local\" value=\"HTML\\" + dt.Rows[i]["mName"].ToString() + ".htm\">");
                    streamWriter.WriteLine("            <param name=\"ImageNumber\" value=\"21\">");
                    //streamWriter.WriteLine("            <param name=\"ImageNumber\" value=\"1\">");
                    streamWriter.WriteLine("            </OBJECT>");
 streamWriter.WriteLine("</UL>");
                    Modes.Append(" </BODY>\r</HTML>");
                   
            }
            streamWriter.WriteLine("</UL>\r</UL>\r</BODY>\r</HTML>");


            streamWriter.WriteLine();
            streamWriter.Close();
            str1.WriteLine(Modes);
            str1.Close();
           

           
        }
}

這語法很像HTML,但同時也不是,<UL></UL>代表一級節點,其中中間的 " <LI> <OBJECT type=\"text/sitemap\"><param name=\"Name\" value=\"數據庫服務器\"><param name=\"Local\" value=\"HTML\\全部對象.htm\"><param name=\"ImageNumber\" value=\"13\"></OBJECT>"這段代碼負責節點內容、連接、圖片顯示功能,如果<UL>內容嵌套的話,則表示下一級節點。還有我定義的modes,它主要負責生成一個Htm文件(記住用文件流生成,文件后綴名不要用html,而要用htm,不然會有錯誤,具體我也不知道啥原因),這樣hhc文件生成在根目錄下

接下來,則要生成hhk文件了

它主要負責你索引部分要顯示的內容,這里生成也很簡單

 1 private void OpenHhk()
 2         {
 3             FileStream fs = new FileStream(startPath + @"\test.hhk", FileMode.Create); //創建hhp文件
 4             //streamWriter = new System.IO.StreamWriter(fs, System.Text.Encoding.GetEncoding("GB18030"));
 5             streamWriter = new System.IO.StreamWriter(fs, System.Text.Encoding.GetEncoding("UTF-8"));
 6             streamWriter.WriteLine("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">");
 7             streamWriter.WriteLine("<HTML>");
 8             streamWriter.WriteLine("<HEAD>");
 9             streamWriter.WriteLine("<meta name=\"GENERATOR\" content=\"Microsoft&reg; HTML Help Workshop 4.1\">");
10             streamWriter.WriteLine("<!-- Sitemap 1.0 -->");
11             streamWriter.WriteLine("</HEAD>");
12             streamWriter.WriteLine("<BODY>");
13             streamWriter.WriteLine("<UL>");
14             string sql = "SELECT dId,dName,status,dCreTime,dFieidNum,dChName,dFunctionDesc FROM Documents order by dName";
15             //string sqls = "";
16             DataTable dt1 = DBHelper.getDatatable(sql);
17             foreach (DataRow dr in dt1.Rows)
18             {
19                 streamWriter.WriteLine("    <LI> <OBJECT type=\"text/sitemap\">");
20                 streamWriter.WriteLine("        <param name=\"Name\" value=\"" + dr["dName"].ToString() + "\">");
21                 streamWriter.WriteLine("<param name=\"Local\" value=\"" + dr["dName"].ToString() + ".htm\">");
22                 streamWriter.WriteLine("</OBJECT>");
23             }
24             streamWriter.WriteLine("</UL>");
25             streamWriter.WriteLine("</BODY>");
26             streamWriter.WriteLine("</HTML>");
27             streamWriter.WriteLine();
28             streamWriter.Close();
29         }


執行以后就可以在根目錄下生成hhk文件了

到此為止,生成chm文件的必須的三大文件已經搞定了,下面就是compile方法了

 1  string hhcFile = @"C:\Program Files\HTML Help Workshop\hhc.exe";//hhc.exe文件位置,windows自帶的,一般是這個路徑
 2         public string _defaultTopic = "";//默認的頁面
 3  private bool Compile()
 4         {
 5             string _chmFile = startPath + @"\test.chm";//chm文件存儲路徑
 6             Process helpCompileProcess = new Process();  //創建新的進程,用Process啟動HHC.EXE來Compile一個CHM文件
 7             try
 8             {
 9                 //判斷文件是否存在並不被占用
10                 try
11                 {
12                     string path = _chmFile;  //chm生成路徑
13                     if (File.Exists(path))
14                     {
15                         File.Delete(path);
16                     }
17                 }
18                 catch(Exception e)
19                 {
20                     throw new Exception("文件被打開!");
21                 }
22 
23                 ProcessStartInfo processStartInfo = new ProcessStartInfo();
24                 processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
25                 processStartInfo.FileName = hhcFile;  //調入HHC.EXE文件 
26                 processStartInfo.Arguments = "\"" + GetPathToProjectFile() + "\"";//獲取空的HHP文件
27                 processStartInfo.UseShellExecute = false;
28                 helpCompileProcess.StartInfo = processStartInfo;
29                 helpCompileProcess.Start();
30                 helpCompileProcess.WaitForExit(); //組件無限期地等待關聯進程退出
31 
32                 if (helpCompileProcess.ExitCode == 0)
33                 {
34                     MessageBox.Show(new Exception().Message);
35                     return false;
36                 }
37             }
38             finally
39             {
40                 helpCompileProcess.Close();
41             }
42             return true;
43         }

滿足上面三個文件要求,再執行這個方法,一個CHM幫助文件就可以生成,

其實網上有很多生成chm文件的工具,但我從沒用過,還好目前我這個用着還可以湊合,而且顯示的樣式可以自己修改成自己喜歡的那種(考你樣式了,)秀秀我的作品(悲催啊,不知道咋吧程序上傳上來,希望有知道的告訴一下),寫起來感覺有點吃力,不好勿噴

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM