標籤:
CHM即“已編譯的協助檔案”,主要由.hhc(目錄檔案)、.hhk(索引檔案)以及相應的說明主題檔案(.html,.htm)這些內容編譯而成。
方法對比
在網頁中顯示CHM內容,大致有以下幾種辦法:
- 使用某些工具來反編譯,把CHM檔案還原成以上相關的檔案,並通過hhc檔案來列出目錄,內容連結到相應的html檔案
- 依然是反編譯這些檔案,把相關目錄及html檔案內容直接存到資料庫中
- 直接解析chm檔案
這些方法有優點也有缺點:
- 方法1的優點是方便快捷;缺點也很明顯,分散的html不便於管理也不利於搜尋
- 方法2的優點是直接存在資料庫,查詢方便;需要通過遍曆目錄把結構和內容插入到資料庫,以及重新組織圖片資源檔的位置,稍微有點繁瑣而已
- 方法3的優點是不需要反編譯,直接使用最方便;缺點是,解析chm難度太高
個人認為直接存入資料庫是相對較好的辦法,但這不是本文的目的,本文使用直接解析CHM檔案的方式。
使用開源類庫
本文主要使用Codeproject上的一個開源類庫:http://www.codeproject.com/KB/cs/htmlhelp.aspx,並針對web稍加改造。
這個htmlhelp類庫包括了幾乎hh.exe(即windows案頭版的chm查看器)所有功能,可以說是非常強大。
但它有一個問題,對於不標準的chm檔案,搜尋功能支援不太好,猜測可能也是編碼有關係。
我試了好多工具來產生CHM檔案,但都無法很好的使用它的搜尋功能;好在它解析CHM檔案的時候,同時也把所有的主題檔案(.htm,.html)都讀取出來了,所以可以通過這些內容以及標題來改造一下搜尋功能,以適應我的不標準的CHM檔案。
搜尋功能主要改造主要代碼如下:
public bool SearchTopics(string key, TreeView treeview){ return SearchTopics(key, treeview, true);}public bool SearchTopics(string key, TreeView treeview, bool filterHtml){ ArrayList result = new ArrayList(); SearchTopic(key, result, chmHelp.TableOfContents.TOC, filterHtml); bool hasData = result.Count > 0; if (hasData) { treeview.Nodes.Clear(); foreach (TOCItem item in result) { TreeNode node = new TreeNode(item.Name); node.NavigateUrl = urlPrefix + item.Local; treeview.Nodes.Add(node); } } return hasData;}static Regex reHtmlFilter = new Regex("<[^>]*>", RegexOptions.Compiled);private void SearchTopic(string topic, ArrayList result, ArrayList searchIn, bool filterHtml){ foreach (TOCItem curItem in searchIn) { if (curItem.Children.Count == 0) { string temp = curItem.FileContents; if (filterHtml && !string.IsNullOrEmpty(temp)) { temp = reHtmlFilter.Replace(temp, string.Empty); } if ((!string.IsNullOrEmpty(curItem.Name) && curItem.Name.Contains(topic)) || (!string.IsNullOrEmpty(temp) && temp.Contains(topic))) { result.Add(curItem); } } else { SearchTopic(topic, result, curItem.Children, filterHtml); } }}
對於擷取單個主題,htmlhelp只提供了通過標題搜尋,但考慮到標題可能不唯一,所以本文也增加了通過url來搜尋。
單獨建立一個頁面,通過接收url來擷取相應的主題,並顯示出來;在此也要注意,url可能存在一些特殊字元如“#”、“%20”等符號,導致參數不能正確傳遞的問題。
預覽:
代碼不多貼了,完整的例子:點擊下載
在網頁中顯示CHM (c# csharp .net asp.net winform)