首页 > 开发 > 综合 > 正文

C#反编译微软MSDN2003的帮助文档,并将反编译结果保存到一个SQLSERVER数据库中

2024-07-21 02:17:41
字体:
来源:转载
供稿:网友
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 [email protected]"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
}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表