C#反編譯微軟MSDN2003的幫助文檔,並將反編譯結果保存到一個SQLSERVER數據庫中 - 中國WEB開發者網絡 (http://www.webasp.net) -- 技術教程 (http://www.webasp.net/article/) --- C#反編譯微軟MSDN2003的幫助文檔,並將反編譯結果保存到一個SQLSERVER數據庫中 (http://www.webasp.net/article/18/17848.htm) |
| -- 作者:未知 -- 發佈日期: 2005-04-22 |
| using System;
using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; namespace MSDNOUT { /// <summary> /// 反編譯微軟MSDN2003文檔並保存到數據庫的程序主窗體 /// </summary> public class dlgMSDNOut : System.Windows.Forms.Form { /****************************************************************************************** 聲明:本程序只是研究性的程序,沒有損害微軟對MSDN的版權的意圖,並承認 微軟對 MSDN , Microsoft Help 2.0 SDK , HXS文件格式,MSDE 等版權所有權 本程序能反編譯微軟MSDN2003的幫助文檔,並將反編譯結果保存到一個SQLSERVER數據庫中 本文件為一個獨立的C#代碼文件,不需要依賴任何其他文件,使用VS.NET建立一個 C#的默認名稱空間為MSDNOUT的Windows應用程序後將該文件內容覆蓋掉系統自動生成 的Form1.cs文件內容即可編譯通過並執行,本程序在微軟.NET框架1.1簡體中文版的 Windows2000Server環境下測試通過, MDAC版本2.7,數據庫服務器為MSDE,版本8.00.760(SP3) 本程序假定你將MSDN2003安裝在 C:\Program Files\MSDN\2003FEB\2052 還假定安裝了 Microsoft Help 2.0 SDK , 並假定安裝在目錄 "C:\Program Files\Microsoft Help 2.0 SDK" , 該SDK安裝文件可在微軟網站下載 本程序長時間頻繁的讀寫臨時文件,因此可以使用一個虛擬硬盤工具在 物理內存中虛擬一個磁盤,這樣可以大大加快程序的運行速度 可在 http://down1.tech.sina.com.cn/cgi-bin/download/download.cgi?s_id=3761&num=1 下載一個虛擬硬盤工具 程序使用的數據庫為MSSQLSERVER,在此使用了MSDE,由於MSDE的單個數據庫 大小限制在2GB內,而MSDN文件總共超過了2GB,因此程序運行時還根據需要 切換數據庫,本程序使用的數據庫文件保存在 f:\db 下面 使用前請執行以下SQL語句來初始化數據庫 CREATE DATABASE MSDN1 ON (NAME = MSDN1, FILENAME = f:\db\MSDN1.mdf )"; CREATE TABLE [MSDNFileList] ( [MFileID] [int] NOT NULL , [MFileName] [varchar] (200) COLLATE Chinese_PRC_CI_AS NOT NULL , [MDBName] [varchar] (10) COLLATE Chinese_PRC_CI_AS NULL , [MFileLength] [int] NULL , CONSTRAINT [PK_MSDNFileList] PRIMARY KEY CLUSTERED ( [MFileName] ) ON [PRIMARY] ) ON [PRIMARY] GO CREATE TABLE [MSDNFile] ( [MFileID] [int] NOT NULL , [MFileContent] [image] NULL , CONSTRAINT [PK_MSDNFile] PRIMARY KEY CLUSTERED ( [MFileID] ) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] *****************************************************************************************/ /// <summary> /// 取消操作標記 /// </summary> private bool bolCancel = false ; /// <summary> /// 暫停操作標記 /// </summary> private bool bolPause = false ; /// <summary> /// 主數據庫連接字符串 /// </summary> private System.Data.SqlClient.SqlConnection MainConn = null; /// <summary> /// 文檔數據庫連接字符串 /// </summary> private System.Data.SqlClient.SqlConnection DataConn = null; /// <summary> /// 插入文檔列表的命令對像 /// </summary> private System.Data.SqlClient.SqlCommand InsertNameCmd = null; /// <summary> /// 查詢文檔內容的命令對像 /// </summary> private System.Data.SqlClient.SqlCommand InsertCmd = null; /// <summary> /// 保存文檔數據的數據庫名稱 /// </summary> private string CurrentDBName = "MSDN1" ; /// <summary> /// 進行數據處理的線程對像 /// </summary> private System.Threading.Thread myThread = null; /// <summary> /// 初始化數據庫連接 /// </summary> private void InitDB() { if( MainConn != null) { MainConn.Dispose(); DataConn.Dispose(); InsertNameCmd.Dispose(); } // 打開數據庫連接 MainConn = new System.Data.SqlClient.SqlConnection(); DataConn = new System.Data.SqlClient.SqlConnection(); MainConn.ConnectionString = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=MSDN1;Data Source=(local)"; DataConn.ConnectionString = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=" + CurrentDBName + ";Data Source=(local)"; MainConn.Open(); DataConn.Open(); InsertNameCmd = MainConn.CreateCommand(); InsertNameCmd.CommandText = "INSERT INTO MSDNFileList(MFileID, MFileName, MDBName, MFileLength) VALUES (@MFileID, @MFileName, @MDBName, @MFileLength) "; InsertNameCmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@MFileID", System.Data.SqlDbType.Int, 4, "MFileID")); InsertNameCmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@MFileName", System.Data.SqlDbType.VarChar, 200, "MFileName")); InsertNameCmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@MDBName", System.Data.SqlDbType.VarChar, 10, "MDBName")); InsertNameCmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@MFileLength", System.Data.SqlDbType.Int, 4, "MFileLength")); InitInsertCmd(); } /// <summary> /// 初始化插入數據內容的命令對像 /// </summary> private void InitInsertCmd() { if( InsertCmd != null) InsertCmd.Dispose(); InsertCmd = DataConn.CreateCommand(); InsertCmd.CommandText = "INSERT INTO MSDNFile(MFileID, MFileContent) VALUES (@MFileID, @MFileContent)"; InsertCmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@MFileID", System.Data.SqlDbType.Int, 4, "MFileID")); InsertCmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@MFileContent", System.Data.SqlDbType.VarBinary, 2147483647, "MFileContent")); } /// <summary> /// 反編譯MSDN文檔的主程序 /// </summary> private void MsdnOut() { try { // 檢查MSDN安裝目錄 string strMSDNDir =@"C:\Program Files\MSDN\2003FEB\2052"; if( System.IO.Directory.Exists( strMSDNDir) == false) return ; // 檢查反編譯器程序 string strExeFile = @"C:\Program Files\Microsoft Help 2.0 SDK\hxcomp.exe"; if( System.IO.File.Exists( strExeFile ) == false) return ; // 準備臨時文件目錄 string strOutDir = this.txtOutPath.Text ; if( strOutDir == null || strOutDir.Trim().Length == 0) return ; strOutDir = strOutDir.Trim(); if( System.IO.Directory.Exists( strOutDir ) == false) System.IO.Directory.CreateDirectory( strOutDir ); string strTempPath = System.IO.Path.Combine( strOutDir , "temp"); if( System.IO.Directory.Exists( strTempPath ) == false) System.IO.Directory.CreateDirectory( strTempPath ); bolCancel = false; bolPause = false; InitDB(); using(System.Data.SqlClient.SqlCommand myCmd = MainConn.CreateCommand()) { myCmd.CommandText = "Delete From MSDNFile"; myCmd.ExecuteNonQuery(); myCmd.CommandText = "Delete From MSDNFileList"; myCmd.ExecuteNonQuery(); } int DBCount = 1 ; long FileSizeCount = 0 ; long TotalFileSize = 0 ; int FileCount = 0 ; string[] strFileNames = System.IO.Directory.GetFiles( strMSDNDir , "*.hxs"); this.InvokeSetLabelText( this.lblDB , "當前數據庫:" + CurrentDBName ); InvokeSetProgress( this.MainProgress , strFileNames.Length , 0 ); long HXSFileSize = 0 ; // 計算所有要處理的文件的長度 foreach( string strFileName in strFileNames) { System.IO.FileInfo myInfo = new System.IO.FileInfo( strFileName ); HXSFileSize += myInfo.Length ; } long HXFileSizeCount = 0 ; // 計算單個數據庫所能保存的數據大小,在此設置為1000MB int DBMaxSize = 1000 * 1024 * 1024 ; // 分別處理單個HXS文檔 for(int HXSFileCount = 0 ; HXSFileCount < strFileNames.Length ; HXSFileCount ++ ) { if( bolCancel ) break; string strFileName = ( string ) strFileNames[ HXSFileCount ]; System.IO.FileInfo myInfo = new System.IO.FileInfo( strFileName ); HXFileSizeCount += myInfo.Length ; InvokeSetProgress( this.MainProgress , (int)(HXSFileSize >> 5) , (int)( HXFileSizeCount >> 5 ) ); string strModleName = System.IO.Path.GetFileNameWithoutExtension( strFileName ) + "\\" ; InvokeSetLabelText( lblFile , "正在處理第 " + HXSFileCount + " 個文件 " + System.IO.Path.GetFileName( strFileName ) + " " + myInfo.Length + " 字節 ..." ); InvokeSetLabelText( lblState ,"正在反編譯..." ); string strOutSubDir = System.IO.Path.Combine( strOutDir ,"temp"); if( System.IO.Directory.Exists( strOutSubDir) == false) System.IO.Directory.CreateDirectory( strOutSubDir ); int BasePathLength = ( strOutSubDir.EndsWith("\\") ? strOutSubDir.Length : strOutSubDir.Length + 1 ) ; // 執行命令行程序來反編譯HXS文檔 string strCmd = " -d " + strOutSubDir + " -u \"" + strFileName + "\" -i -e -w -q"; System.Diagnostics.ProcessStartInfo myPInfo = new System.Diagnostics.ProcessStartInfo( strExeFile , strCmd ); myPInfo.CreateNoWindow = true; myPInfo.UseShellExecute = false; System.Diagnostics.Process myProcess = System.Diagnostics.Process.Start( myPInfo ); myProcess.WaitForExit(); if( bolCancel ) break; // 找到所有反編譯所得的文件 System.Collections.ArrayList myNames = GetFileNames( strOutSubDir ); InvokeSetLabelText(lblState , "正在導入到數據庫,共 " + myNames.Count + " 個文件 ..." ); for( int iCount = 0 ; iCount < myNames.Count ; iCount ++ ) { try { if( bolPause ) myThread.Suspend(); bolPause = false; InvokeSetProgress( this.myProgress , myNames.Count , iCount ); if( bolCancel ) break; // 讀取臨時文件數據 string strTempFileName = (string)myNames[iCount]; System.IO.FileInfo myTempInfo = new System.IO.FileInfo( strTempFileName ); byte[] bytData = new byte[ (int)myTempInfo.Length ]; System.IO.FileStream myFile = new System.IO.FileStream( strTempFileName , System.IO.FileMode.Open ); myFile.Read( bytData , 0 , bytData.Length ); myFile.Close(); InsertNameCmd.Parameters[0].Value = FileCount; InsertNameCmd.Parameters[1].Value = strModleName + strTempFileName.Substring( BasePathLength ); InsertNameCmd.Parameters[2].Value = CurrentDBName ; InsertNameCmd.Parameters[3].Value = bytData.Length ; InsertCmd.Parameters[0].Value = FileCount ; InsertCmd.Parameters[1].Value = bytData ; if( bolCancel ) break; InsertNameCmd.ExecuteNonQuery(); InsertCmd.ExecuteNonQuery(); FileSizeCount += bytData.Length ; TotalFileSize += bytData.Length ; FileCount ++ ; // 更換數據庫 if( FileSizeCount > DBMaxSize ) { DBCount ++ ; CurrentDBName = "MSDN" + DBCount.ToString(); InvokeSetLabelText( lblState , "更換數據庫為 " + CurrentDBName ); InsertCmd.Dispose(); using( System.Data.SqlClient.SqlCommand myCmd = MainConn.CreateCommand()) { myCmd.CommandText ="CREATE DATABASE " + CurrentDBName + " ON (NAME = " + CurrentDBName + ", FILENAME = f:\\db\\" + CurrentDBName + ".mdf )"; myCmd.ExecuteNonQuery(); } InsertCmd.Dispose(); DataConn.ChangeDatabase( CurrentDBName ); using( System.Data.SqlClient.SqlCommand myCmd = DataConn.CreateCommand()) { myCmd.CommandText = @" CREATE TABLE [MSDNFile] ( [MFileID] [int] NOT NULL , [MFileContent] [image] NULL , CONSTRAINT [PK_MSDNFile] PRIMARY KEY CLUSTERED ( [MFileID] ) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] "; myCmd.ExecuteNonQuery(); }//using InvokeSetLabelText(lblDB , "當前數據庫:" + CurrentDBName ); InitInsertCmd(); FileSizeCount = 0 ; }//if }//try catch(Exception ext) { System.Windows.Forms.MessageBox.Show( ext.ToString()); InitDB(); FileCount ++ ; } }//for InvokeSetProgress( this.myProgress , myNames.Count , 0 ); InvokeSetLabelText( lblState , "正在刪除臨時文件..." ); System.IO.Directory.Delete( strOutSubDir , true ); InvokeSetLabelText( lblState , "操作完畢"); }//for string strDir2 = System.IO.Path.Combine( strOutDir ,"temp"); if( System.IO.Directory.Exists( strDir2 )) System.IO.Directory.Delete( strDir2 , true ); InsertNameCmd.Dispose(); InsertCmd.Dispose(); InvokeSetProgress( this.MainProgress ,1 , 0 ); }//try catch(Exception ext) { System.Windows.Forms.MessageBox.Show( ext.ToString()); } this.BeginInvoke( new System.EventHandler( this.EndProcess) , new object[]{null,null}); MainConn.Close(); MainConn.Dispose(); DataConn.Close(); DataConn.Dispose(); }//public void MsdnOut() /// <summary> /// 獲得指定目錄及下層目錄下所有的文件的絕對路徑文件名 /// </summary> /// <param name="strRootDir">根目錄</param> /// <returns>保存文件名的列表對像</returns> public System.Collections.ArrayList GetFileNames( string strRootDir) { System.Collections.ArrayList myList = new System.Collections.ArrayList(); string[] strNames = System.IO.Directory.GetFiles( strRootDir , "*.*"); if( strNames != null && strNames.Length > 0 ) { myList.AddRange( strNames ); } strNames = System.IO.Directory.GetDirectories( strRootDir , "*.*"); if( strNames != null && strNames.Length > 0 ) { foreach( string strDir in strNames ) { myList.AddRange( GetFileNames ( strDir )); } } return myList ; }//public GetFileNames() #region 處理用戶界面的代碼群 ************************************************************** public delegate void SetLabelTextHandler( System.Windows.Forms.Label lbl , string Text ); public delegate void SetProgressBarHandler( System.Windows.Forms.ProgressBar pb , int vMaxValue , int vValue); private void InvokeSetProgress( System.Windows.Forms.ProgressBar pb , int vMaxValue , int vValue) { this.Invoke( new SetProgressBarHandler( this.SetProgressBar ) , new object[]{ pb , vMaxValue , vValue }); } private void InvokeSetLabelText( System.Windows.Forms.Label lbl , string Text ) { this.Invoke( new SetLabelTextHandler( this.SetLabelText ) , new object[]{ lbl , Text }); } private void SetLabelText( System.Windows.Forms.Label lbl , string Text ) { lbl.Text = Text ; lbl.Refresh(); } private void SetProgressBar ( System.Windows.Forms.ProgressBar pb , int vMaxValue , int vValue) { if( pb.Maximum != vMaxValue ) pb.Maximum = vMaxValue ; if( vValue >= 0 && vValue <= vMaxValue ) pb.Value = vValue ; } private void EndProcess( object sender , System.EventArgs e ) { txtOutPath.Enabled = true; cmdStart.Enabled = true; cmdStop.Enabled = false; cmdPose.Enabled = false; } private void cmdStart_Click(object sender, System.EventArgs e) { cmdStart.Enabled = false; txtOutPath.Enabled = false; cmdStop.Enabled = true; cmdPose.Enabled = true; System.Threading.ThreadStart st = new System.Threading.ThreadStart( this.MsdnOut ); myThread = new System.Threading.Thread(st); myThread.Start(); } private void cmdStop_Click(object sender, System.EventArgs e) { bolCancel = true; } private void cmdPose_Click(object sender, System.EventArgs e) { bolPause = true; System.Windows.Forms.MessageBox.Show("正在暫停"); bolPause = false; myThread.Resume(); } #endregion #region 系統自動生成的代碼 **************************************************************** private System.Windows.Forms.Label label1; private System.Windows.Forms.TextBox txtOutPath; private System.Windows.Forms.Label lblFile; private System.Windows.Forms.Button cmdStart; private System.Windows.Forms.Button cmdStop; private System.Windows.Forms.Label lblDB; private System.Windows.Forms.Label lblState; private System.Windows.Forms.ProgressBar myProgress; private System.Windows.Forms.ProgressBar MainProgress; private System.Windows.Forms.Button cmdPose; /// <summary> /// 必需的設計器變量。 /// </summary> private System.ComponentModel.Container components = null; public dlgMSDNOut() { // // Windows 窗體設計器支持所必需的 // InitializeComponent(); // // TODO: 在 InitializeComponent 調用後添加任何構造函數代碼 // } /// <summary> /// 清理所有正在使用的資源。 /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } /// <summary> /// 應用程序的主入口點。 /// </summary> [STAThread] static void Main(string[] args) { System.Windows.Forms.Application.Run( new dlgMSDNOut()); }//main #endregion #region Windows 窗體設計器生成的代碼 ****************************************************** /// <summary> /// 設計器支持所需的方法 - 不要使用代碼編輯器修改 /// 此方法的內容。 /// </summary> private void InitializeComponent() { this.label1 = new System.Windows.Forms.Label(); this.txtOutPath = new System.Windows.Forms.TextBox(); this.lblFile = new System.Windows.Forms.Label(); this.cmdStart = new System.Windows.Forms.Button(); this.cmdStop = new System.Windows.Forms.Button(); this.lblDB = new System.Windows.Forms.Label(); this.lblState = new System.Windows.Forms.Label(); this.myProgress = new System.Windows.Forms.ProgressBar(); this.MainProgress = new System.Windows.Forms.ProgressBar(); this.cmdPose = new System.Windows.Forms.Button(); this.SuspendLayout(); // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(16, 16); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(72, 17); this.label1.TabIndex = 0; this.label1.Text = "臨時文件夾:"; // // txtOutPath // this.txtOutPath.Location = new System.Drawing.Point(96, 16); this.txtOutPath.Name = "txtOutPath"; this.txtOutPath.Size = new System.Drawing.Size(352, 21); this.txtOutPath.TabIndex = 1; this.txtOutPath.Text = "c:\\msdnout"; // // lblFile // this.lblFile.AutoSize = true; this.lblFile.Location = new System.Drawing.Point(16, 168); this.lblFile.Name = "lblFile"; this.lblFile.Size = new System.Drawing.Size(91, 17); this.lblFile.TabIndex = 2; this.lblFile.Text = "當前處理的文件"; // // cmdStart // this.cmdStart.Location = new System.Drawing.Point(16, 48); this.cmdStart.Name = "cmdStart"; this.cmdStart.TabIndex = 3; this.cmdStart.Text = "開始"; this.cmdStart.Click += new System.EventHandler(this.cmdStart_Click); // // cmdStop // this.cmdStop.Location = new System.Drawing.Point(96, 48); this.cmdStop.Name = "cmdStop"; this.cmdStop.TabIndex = 4; this.cmdStop.Text = "結束"; this.cmdStop.Click += new System.EventHandler(this.cmdStop_Click); // // lblDB // this.lblDB.AutoSize = true; this.lblDB.Location = new System.Drawing.Point(16, 88); this.lblDB.Name = "lblDB"; this.lblDB.Size = new System.Drawing.Size(66, 17); this.lblDB.TabIndex = 5; this.lblDB.Text = "當前數據庫"; // // lblState // this.lblState.AutoSize = true; this.lblState.Location = new System.Drawing.Point(16, 112); this.lblState.Name = "lblState"; this.lblState.Size = new System.Drawing.Size(29, 17); this.lblState.TabIndex = 6; this.lblState.Text = "狀態"; // // myProgress // this.myProgress.Location = new System.Drawing.Point(16, 136); this.myProgress.Name = "myProgress"; this.myProgress.Size = new System.Drawing.Size(432, 23); this.myProgress.TabIndex = 7; // // MainProgress // this.MainProgress.Location = new System.Drawing.Point(16, 192); this.MainProgress.Name = "MainProgress"; this.MainProgress.Size = new System.Drawing.Size(432, 23); this.MainProgress.TabIndex = 8; // // cmdPose // this.cmdPose.Enabled = false; this.cmdPose.Location = new System.Drawing.Point(176, 48); this.cmdPose.Name = "cmdPose"; this.cmdPose.TabIndex = 9; this.cmdPose.Text = "暫停"; this.cmdPose.Click += new System.EventHandler(this.cmdPose_Click); // // dlgMSDNOut // this.AutoScaleBaseSize = new System.Drawing.Size(6, 14); this.ClientSize = new System.Drawing.Size(466, 223); this.Controls.Add(this.cmdPose); this.Controls.Add(this.MainProgress); this.Controls.Add(this.myProgress); this.Controls.Add(this.lblState); this.Controls.Add(this.lblDB); this.Controls.Add(this.lblFile); this.Controls.Add(this.txtOutPath); this.Controls.Add(this.label1); this.Controls.Add(this.cmdStop); this.Controls.Add(this.cmdStart); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.Name = "dlgMSDNOut"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "導出MSDN"; this.ResumeLayout(false); } #endregion }//public class dlgMSDNOut } |
| webasp.net |