日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#生成CHM文件(中级篇)

發布時間:2023/12/20 C# 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#生成CHM文件(中级篇) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在上篇《C#生成CHM文件(入門篇)》中,我們利用微軟自帶的hhc.exe以編程的方式創建一個CHM文件,而且調用的是一個靜態的HMTL文件。
?
在中篇中,實現以下幾個目標
?1.將在線的網頁保存為CHM文件
?2.我們將對我們進行編譯的CHM文件進行反編譯,使用的還是微軟自帶的一個exe(hh.exe)。
?3.以編程的方式將CHM文件轉換為Word

?

在中篇中,把界面稍微調整了下,如下圖

?

?

一、將在線的網頁保存為CHM文件


?曾嘗試直接使用網址來編譯html文件,結果一直報錯,于是就放棄了。現在實現的方法的思想是這樣的:先將輸入的url地址的網頁保存到本地,然后利用上一篇中的方法生成CHM文件。不過經測試,這樣的效率還是比較低的,主要的花費在將htm文件下載到本地,如果帶寬不夠的話,將會很慢,不過總歸是種方法,大家如果有更好的解決方案,希望能告訴我。

HttpWebRequest?myReq?=?(HttpWebRequest)WebRequest.Create(url);
HttpWebResponse?myResp?=?(HttpWebResponse)myReq.GetResponse();
?StreamReader?respStream?=?new?StreamReader(myResp.GetResponseStream(),?Encoding.Default);
string?respStr?=?respStream.ReadToEnd();
respStream.Close();
FileStream?fs?=?new?FileStream(startPath+@"\test.htm",?FileMode.Create,?FileAccess.Write);
StreamWriter?sw?=?new?StreamWriter(fs,?Encoding.Default);
sw.Write(respStr);
sw.Close(); 思路是將網頁保存在本地的,startPath為項目所在路徑。 大家可以以http://www.baidu.com/index.htm為例(注意要以htm或html為結尾),測試下,看看能不能正常將百度的首頁保存到CHM文件中。 效果圖是這樣的: ?

?

?

二、反編譯CHM


反編譯CHM的方法同初篇中的利用Process類來進行。

?

代碼 ///?<summary>
????????
///?反編譯CHM文件
????????
///?</summary>
????????
///?<param?name="CHMFile">CHM文件名</param>
????????
///?<returns>返回hhc文件名</returns>
????????
///?<remarks>uses?the?<see?cref="DecompileChm"></see></remarks>
????????public?string?DecompileChm(string?CHMFile)
????????{
????????????
string?pathDir?=?Path.GetDirectoryName(CHMFile);//得到chm文件的絕對路徑
????????????pathDir?=?Path.Combine(pathDir,?Path.GetFileNameWithoutExtension(CHMFile));
????????????
return?DecompileChm(CHMFile,?ref?pathDir);
????????}
????????
///?<summary>
????????
///?反編譯CHM文件
????????
///?</summary>
????????
///?<param?name="CHMFile">CHM文件名</param>
????????
///?<param?name="FolderToPut">反編譯后的文件存放路徑</param>
????????
///?<returns>返回反編譯后的hhc文件名</returns>
????????
///?<remarks>使用hh.exe反編譯</remarks>
????????public?string?DecompileChm(string?CHMFile,?ref?string?FolderToPut)
????????{
????????????
if?((!System.IO.File.Exists(CHMFile)))
????????????{
????????????????
throw?new?ArgumentException(CHMFile+"文件不存在");
????????????}
????????????
if?((!Directory.Exists(FolderToPut)))
????????????{
????????????????FolderToPut?
=?FolderToPut.Replace("?",?"_");
????????????????Directory.CreateDirectory(FolderToPut);
????????????}
????????????DirectoryInfo?di?
=?new?DirectoryInfo(FolderToPut);
????????????
if?((di.Name.Contains("?")))
????????????{
????????????????
throw?new?ArgumentException("反編譯的文件夾名不能包含空格");
????????????}
????????????
string?strD?=?null;
????????????strD?
=?"?-decompile?"?+?di.FullName?+?"?"?+?CHMFile;//反編譯命令
????????????Console.WriteLine(strD);
????????????Process?p?
=?Process.Start("hh.exe",?strD);//調用hh.exe進行反編譯

????????????p.WaitForExit();
????????????
return?Directory.GetFiles(FolderToPut,?"*.HHC")[0];
????????}

?

?

三、CHM文件轉換為Word


接下來,我們來延伸下,利用反編譯的文件,將CHM轉換成Word文件。思路是這樣的:利用反編譯,得到hhc文件(hhc文件中包含htm或html文件的文件名)和一大堆web頁面(如果一開始編譯進去的是一大堆的話,呵呵),創建一個word文件,將html文件插入到word中,下面以實例的方式來實現。
為了方便代碼管理,我創建了一個類庫項目,命名為CHM2Word,里面主要實現將CHM文件反編譯并將反編譯的文件整合為Word。在CreateCHM項目中調用代碼即可,另需要你的機器安裝Office2003(對應,添加引用 ->COM->Microsoft Word 11.0 Object Library)或2007(對應,添加引用->COM->Microsoft Word 12.0 Object Library)。

?

代碼 ?///?<summary>
????????
///?添加到word中
????????
///?</summary>
????????
///?<param?name="pathFileHHC"></param>
????????
///?<param?name="saveAs"></param>
????????public?void?AddToWord(string?pathFileHHC,?string?saveAs)
????????{
????????????
if?(File.Exists(saveAs))
????????????{
????????????????
throw?new?Exception("word文件已經存在!");
????????????}
????????????Object?Nothing?
=?System.Reflection.Missing.Value;
????????????Microsoft.Office.Interop.Word.Application?wApp?
=?(Microsoft.Office.Interop.Word.Application)this.Word();
????????????Document?wDoc?
=?wApp.Documents.Add(ref??Nothing,?ref??Nothing,?ref??Nothing,?ref??Nothing);

????????????
if?(wApp?==?null)
????????????{
????????????????
throw?new?Exception("轉換失敗");
????????????}

????????????
try
????????????{
????????????????
string?dirfile?=?"";//目錄位置
????????????????dirfile?=?Path.GetDirectoryName(pathFileHHC);//目錄的絕對路徑
????????????????string[]?lines?=?File.ReadAllLines(pathFileHHC);//讀取hhc所有的行,這是為了找出里面的htm或html文件

????????????????
string?quote?=?""?+?(char)34;
????????????????
long?filenumber?=?0;

????????????????
//遍歷每一行
????????????????foreach?(string?TextLine?in?lines)
????????????????{
????????????????????
string?htmFile?=?null;

????????????????????
if?(TextLine.IndexOf(".html",?0)?>?0?||?TextLine.IndexOf(".htm",?0)?>?0)//如果這一行里面有.htm或者html.的字符串
????????????????????{

????????????????????????
#region?以下代碼是獲取htm或者html文件名

????????????????????????
int?endQuote?=?0;
????????????????????????
if?(TextLine.IndexOf(".html",?0)?>?0)
????????????????????????{
????????????????????????????endQuote?
=?TextLine.IndexOf(quote,?TextLine.IndexOf(".html",?0));
????????????????????????}
????????????????????????
else
????????????????????????{
????????????????????????????endQuote?
=?TextLine.IndexOf(quote,?TextLine.IndexOf(".htm",?0));
????????????????????????}
????????????????????????
int?quoteLoop?=?0;
????????????????????????quoteLoop?
=?endQuote?-?1;
????????????????????????
while?(TextLine.Substring(quoteLoop,?1)?!=?quote)
????????????????????????{
????????????????????????????quoteLoop?
=?quoteLoop?-?1;
????????????????????????}
????????????????????????htmFile?
=?TextLine.Substring(quoteLoop?+?1,?endQuote?-?quoteLoop?-?1);//獲取html文件的名字

????????????????????????
#endregion
????????????????????????
????????????????????????
????????????????????????htmFile?
=?dirfile?+?"\\"?+?htmFile;

????????????????????????
bool?b?=?false;//是否存在html文件
????????????????????????try
????????????????????????{
????????????????????????????b?
=?File.Exists(htmFile);
????????????????????????}
????????????????????????
catch?(Exception?ex)
????????????????????????{
????????????????????????}
????????????????????????
if?((!b))
????????????????????????{
????????????????????????????
continue;
????????????????????????}
????????????????????????
//將文件插入到word中
????????????????????????wApp.Selection.InsertParagraphAfter();
????????????????????????filenumber?
+=?1;
????????????????????????
if?(ProcessFile?!=?null)
????????????????????????{
????????????????????????????ProcessFile(
this,?new?ProcessFileEventArgs(htmFile,?filenumber));
????????????????????????}
????????????????????????
//InsertFile參數說明
????????????????????????
//文件名:?必選的?String.?要被插入的文件名和路徑。如果沒有指定路徑,Word默認為當前文件夾
????????????????????????
//Range:?可選的?Object.?如果指定的文件時word,?參數為bookmark(書簽).?如果文件為其他類型(如Excel工作表),?參數為指定的一個單元或區域,如?R1C1:R3C4
????????????????????????
//確定是否轉換?可選?Object.如果值為?True,則?word?應用程序將在插入非“?Word?文檔”格式的文檔時提示對轉換進行確認。.
????????????????????????
//鏈接:??可選?Object.?如果值為?True,則可用?INCLUDETEXT?域插入該文檔。
????????????????????????
//附件:?可選?Object.?為?True?時將該文件作為附件插入電子郵件消息中。
????????????????????????wApp.Selection.InsertFile(htmFile,?ref?Nothing,?ref?Nothing,?ref?Nothing,?ref?Nothing);
????????????????????????
if?((filenumber?%?10?==?0))
????????????????????????????wDoc.Save();
????????????????????}
????????????????}
????????????????wDoc.Save();
//保存word
????????????????wDoc.Close(ref?Nothing,?ref?Nothing,?ref?Nothing);//關閉
????????????????wApp.Quit(ref?Nothing,?ref?Nothing,?ref?Nothing);//釋放

????????????}
????????????
catch?(Exception?ex)
????????????{
????????????}
????????????
finally//釋放對象
????????????{
????????????????
if?((wDoc?!=?null))
????????????????{
????????????????????Marshal.ReleaseComObject(wDoc);
????????????????????wDoc?
=?null;
????????????????}

????????????????Marshal.ReleaseComObject(wApp);
????????????????wApp?
=?null;
????????????}
????????}

?

創建word對象

?

代碼 ///?<summary>
????????
///?創建word對象
????????
///?</summary>
????????
///?<returns></returns>
????????public?object?Word()
????????{
????????????Microsoft.Office.Interop.Word.Application?WordApp;
????????????
try
????????????{
????????????????
????????????????
//WordApp?=?new?Microsoft.Office.Interop.Word.ApplicationClass();//如果是office2003和office2007用這樣方法
????????????????WordApp?=?new?Microsoft.Office.Interop.Word.Application();//如果是office2010,使用這個方法
????????????}
????????????
catch?(Exception?e)
????????????{
????????????????WordApp?
=?null;
????????????}
????????????
return?WordApp;
????????}

?

?

反編譯導出類主要方法

?

代碼 ///?<summary>
????????
///?feedback?about?processing?
????????
///?</summary>
????????public?event?EventHandler<ProcessFileEventArgs>?ProcessFileIntoWord;//定義一個事件屬性
????????private?WordClass?withEventsField_w?=?new?WordClass();
????????
///?<summary>
????????
///?通過這個類,我們可以轉換為word,并且把事件傳給調用者
????????
///?</summary>????
????????public?WordClass?w
????????{
????????????
get?{?return?withEventsField_w;?}
????????????
set
????????????{
????????????????
if?(withEventsField_w?!=?null)//如果不為null,撤銷事件
????????????????{
????????????????????withEventsField_w.ProcessFile?
-=?w_ProcessFile;
????????????????}
????????????????withEventsField_w?
=?value;
????????????????
if?(withEventsField_w?!=?null)//如果不為null,注冊
????????????????{
????????????????????withEventsField_w.ProcessFile?
+=?w_ProcessFile;
????????????????}
????????????}
????????}
????????
///?<summary>
????????
///?主要函數:反編譯、導出
????????
///?</summary>
????????
///?<param?name="ChmFile">待反編譯的CHM文件</param>
????????
///?<param?name="DocFile">word文件名</param>
????????
///?<remarks>word文件一定不存在</remarks>
????????public?void?DecompileAndExport(string?ChmFile,?string?DocFile)
????????{
????????????
try
????????????{
????????????????Decompile?d?
=?new?Decompile();//實例化一個反編譯類
????????????????string?strHHC?=?d.DecompileChm(ChmFile);//獲取hhc文件
????????????????w.AddToWord(strHHC,?DocFile);//調用word類的添加到word中方法
????????????}
????????????
catch?(System.Runtime.InteropServices.COMException?ex)
????????????{
????????????????
//throw?new?clsError("Com?exception:"?+?ex.Message,?ErrorsOcurred.ComError);
????????????}

????????}

?

?

?

我利用剛剛生成的baidu的CHM導出的word如圖:

效果還是不錯的,呵呵。如果你的CHM文件大的話,導出的時間可能會比較長一些。

?

PS:
1.如果你使用的是office2003或者office2007,需要修改類庫項目下的WordClass類下Word方法,因為office2010的
Microsoft.Office.Interop.Word.ApplicationClass不再提供構造方法,而是提供Microsoft.Office.Interop.Word.Application()接口


2.如果在轉換的工程中,始終沒有反應,可以調試下,如果出現這樣的錯誤,“因為沒有打開的文檔,所以這一命令無效”。

調試中不會彈出異常,但是將鼠標放到wApp對象中,查看的會發現那樣的錯誤,原因是因為權限不夠,可以采用如下方法解決:

運行dcomcnfg打開組件服務,依次展開"組件服務"->"計算機"->"我的電腦"->"DCOM配置"

找到"Microsoft Word應用程序",右鍵打開屬性對話框,
點擊"標識"選項卡,點擊"標識"標簽,選擇"交互式用戶"(此設置可能對計算機安全存在威脅,如不設置可以解決問題就不設置,點"下列用戶",把管理員的用戶administrator密碼....正確填寫進去也行)
點擊"安全"選項卡,依次把"啟動和激活權限","訪問權限","配置權限",都選擇為自定義,然后依次點擊它們的編輯,把everyone添加進去,并加入所有的權限...
OK,解決此問題!
如果你的office是2010或者你的系統版本較高的話,很有可能遇到這樣的問題。我的電腦是windows7+office2010,就遇到了這樣的問題。

3.在反編譯和在線生成CHM的時候會生成一些臨時文件,如果不及時刪掉的話,會造成空間的浪費。我們自己可以寫一個簡單的刪除程序,這個應該很簡單,如果不會的,可以參考我以前項目中的代碼,http://www.cnblogs.com/alexis/archive/2010/07/03/1770409.html

?

PS:汗...(2010-09-30 12:40),忘了附源代碼了 C#生成CHM(中級篇)

?

在下篇(應用篇)中,我將說說如何將這些技術運用到實際中。

總結

以上是生活随笔為你收集整理的C#生成CHM文件(中级篇)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。