论坛交流
首页办公自动化| 网页制作| 平面设计| 动画制作| 数据库开发| 程序设计| 全部视频教程
应用视频: Windows | Word2007 | Excel2007 | PowerPoint2007 | Dreamweaver 8 | Fireworks 8 | Flash 8 | Photoshop cs | CorelDraw 12
编程视频: C语言视频教程 | HTML | Div+Css布局 | Javascript | Access数据库 | Asp | Sql Server数据库Asp.net  | Flash AS
当前位置 > 文字教程 > C语言程序设计教程
Tag:新手,函数,指针,数据类型,对象,Turbo,入门,运算符,数组,结构,二级,,tc,游戏,试题,问答,编译,视频教程

C语言教程:用vc设计系统援救程序

文章类别:C语言程序设计 | 发表日期:2010-12-26 9:10:32

C语言教程:用vc设计系统援救程序 

一.引言 
  Windows的system.dat和user.dat中存储着windows注册表,win.ini和system.ini中也存储着一些重要的初始化信息,对它们进行备份可以避免一些重装系统之类的繁琐.虽然windos自带一些备份和恢复系统信息的功能,但是使用起来很不方便.经过一些研究,我发现你完全可以非常容易地设计出自己的系统援救程序. 

二.关键问题分析 
  1.在程序中调用系统现有的程序. 

  使用WinExec(),ShellExecute(),CreateProcess()调用其它应用程序的这三种方法基本已经人所共知.但是有一些命令和程序它们不能调用,如DOS中的内部命令和sys.com等一些外部命令.这时,我们可以首先建立一个.bat的批处理文件,然后再用这三种方法之一采用隐藏的方式来调用这个批处理文件.这样我们可以在用户不知不觉中,来使用一些系统现成的功能. 

  2.如何备份系统信息 

  可以调用windows目录下command\目录中的scanreg.exe来备份系统信息,用/backup参数可以使前面介绍的文件被压缩成一个cab文件存储于windows目录下的sysbckup\目录中,文件名自动为rb000,rb001等.此命令不能直接调用,必须通过前面介绍的方法来使用它.如果你不想使用scanreg.exe,也可以使用同一个目录中的extract.exe来生成cab文件,这样虽然麻烦一些,但是灵活性较强. 

  注意,为了程序的通用性, windows目录不应根据你的计算机上的目录直接指定,而应使用GetWindowsDirectory()来获得. 

  3.如何恢复系统信息 

  注册表文件的恢复必须在纯DOS方式下,因此你的程序应让系统重启(使用ExitWindowsEx()),在没进入windows之前恢复系统信息.这可以通过修改autoexec.bat来实现.如果在备份时你使用的是scanreg /backup,那么在恢复时你可以在autoexec.bat中加入scanreg /restore.如果你备份时使用的是extract 那么你可以将形式如下的一条语句加入到autoexec.bat中: 

  extract /Y /L C:\windows myBackedFile.cab *.* 

  另外除特殊情况外,在纯DOS方式下一般不支持长路径名.因此在程序中将语句写入autoexec.bat时,要先用GetShortPathName()来转化为短路径名. 

  4.援救盘的创建 

  恢复系统可分两种情况.一种是用户想把系统信息恢复成以前某次备份时的状态,此时可使用户在程序中选择要恢复的备份,然后程序控制重启并在autoexec.bat中恢复即可.另一种情况则是用户由于误操作或其它原因是系统出错而不能进入windows,因此要建立援救软盘,以使用户能够恢复系统.援救盘的目的一个是启动系统,可以通过windows目录下command\目录中的sys.com来实现(如sys c: a:).另外软盘重要记住备份存放的位置,以便通过命令来恢复系统. 

三.程序实现 
  1.在头文件中加入: 

  CString m_strWinDir(' ',_MAX_DIR); 

  2.在构造函数中加入: 

  GetWindowsDirectory(m_strWinDir.GetBuffer(0),_MAX_DIR); 

  m_strWinDir.ReleaseBuffer();   

  3.加入一个进展条,并用ClassWazid生成一个控制型变量m_progress. 

  4.加入两个函数: 

  CString CRescueSysDlg::getMyDir()    //用来得到程序的当前目录. 

  { 

  TCHAR sFilename[_MAX_PATH]; 

  TCHAR sDrive[_MAX_DRIVE]; 

  TCHAR sDir[_MAX_DIR]; 

  TCHAR sFname[_MAX_FNAME];    //不带扩展名 

  TCHAR sExt[_MAX_EXT];       //扩展名,前面有"." 

  GetModuleFileName(AfxGetInstanceHandle(), sFilename, _MAX_PATH); 

  _tsplitpath(sFilename, sDrive, sDir, sFname, sExt);   

  CString homeDir(CString(sDrive) + CString(sDir)); 

  int nLen=homeDir.GetLength(); 

  if (homeDir.GetAt(nLen-1) != _T('\\')) 

    homeDir+=_T("\\");   

  return homeDir;   

  } 

  CString CRescueSysDlg::toShortPath(CString m_inDir)     //用来将长路径名转化为短路径名. 

  { 

  char strBuffer[_MAX_PATH]; 

  GetShortPathName(m_inDir,strBuffer,_MAX_PATH); 

  CString m_toDir(strBuffer); 

  return m_toDir; 

  } 

  5.为"开始备份"按钮或菜单项生成一个响应函数: 

  void CRescueSysDlg::OnBeginBkup() 

  { 

  CInputName m_inNameDlg; 

  // CinputName是一个对话框类,用来将用户输入的备份名称保存在inNameDlg .m_strInputEdit中. 

  if(IDCANCEL==m_inNameDlg.DoModal()) 

    return; 

  CFile f1; 

  CString m_allFileName[20]; 

  int m_savedNum=0; 

  if(f1.Open(getMyDir()+"backedCab.mqy",CFile::modeRead)) 

  //读出用户以前所有备份的名称. 

  { 

    CArchive ar1(&f1,CArchive::load); 

    ar1>>m_savedNum; 

    for(int i=0;i

      ar1>>m_allFileName[i]; 

    ar1.Close(); 

    f1.Close(); 

  } 

  CTime m_curTime=CTime::GetCurrentTime(); 

  CString strInputAdded,strIsFileName; 

  strInputAdded.Format("_%d_%d_%d_%d_%d",m_curTime.GetYear(),m_curTime.GetMonth(),

    m_curTime.GetDay(),m_curTime.GetHour(),m_curTime.GetMinute()); 

  strIsFileName=m_inNameDlg.m_strInputEdit+strInputAdded; 

  CFile f2; 

  f2.Open(getMyDir()+"backedCab.mqy",CFile::modeCreate|CFile::modeWrite); 

  CArchive ar2(&f2,CArchive::store); 

  ar2<

  for(int j=0;j

    ar2<

  ar2<

  ar2.Close(); 

  f2.Close();   

  m_savedNum++; 

  DeleteFile(toShortPath(m_strWinDir)+"\\sysbckup\\rb000.cab");   

  CStdioFile f;    //建立包含系统备份命令的批处理文件并执行. 

  f.Open(getMyDir()+"myTemp.bat", CFile::modeCreate|CFile::modeWrite,NULL); 

  CString m_strCommand=toShortPath(m_strWinDir)+"\\command\\scanreg.exe/backup\n";

  f.WriteString(m_strCommand); 

  f.Close(); 

  WinExec(getMyDir()+"myTemp.bat",SW_HIDE); 

  CString m_toRbName; 

  m_toRbName.Format("rb0%d.cab", m_savedNum);     //格式化存储文件名. 

  CTime m_beginTime=CTime::GetCurrentTime(); 

  CTimeSpan m_timeSpan=CTime::GetCurrentTime()-m_beginTime; 

  SYSTEM_INFO sysInfo; 

  GetSystemInfo(&sysInfo); 

  int delayTime=150/sysInfo.wProcessorLevel;     //根据计算机的速度算出大致的完成时间. 

  while(!CopyFile(m_strWinDir+"\\sysbckup\\rb000.cab",getMyDir()+m_toRbName,0)) 

  { 

    MSG msg; 

    if(::PeekMessage(&msg,m_hWnd,0,0,PM_REMOVE)) 

    { 

      ::TranslateMessage(&msg); 

      ::DispatchMessage(&msg); 

    } 

    if(!(m_progress.GetPos()>=100)) 

      m_progress.SetPos(100*m_timeSpan.GetSeconds()/delayTime); 

    m_timeSpan=CTime::GetCurrentTime()-m_beginTime; 

  } 

  m_progress.SetPos(100); 

  AfxMessageBox("已经成功的备份了系统文件"); 

  DeleteFile(getMyDir()+"myTemp.bat"); 

  } 

  6.为"开始恢复"按钮或菜单项生成一个响应函数: 

  void CRescueSysDlg::OnBeginRestore() 

  { 

  CRestoreDlg m_restoreDlg; 

  // CRestoreDlg是一个对话框类,用来将用户输入的恢复名称保存在m_restoreDlg.m_strSeled中. 

  if(IDCANCEL==m_restoreDlg.DoModal()) 

    return; 

  CStdioFile f;       //建立Autoexec.bat和rescueS.bat,将恢复系统的命令写入. 

  f.Open(getMyDir()+"Autoexec.bat", CFile::modeCreate|CFile::modeWrite,NULL); 

  CString m_strCommand=(CString)"echo off \n"+"cls \n"+ 

    toShortPath(getMyDir())+"rescueS.bat \n"; 

  f.WriteString(m_strCommand); 

  f.Close(); 

  f.Open(getMyDir()+"rescueS.bat", CFile::modeCreate|CFile::modeWrite,NULL); 

  m_strCommand=(CString)"echo off \n"+"cls \n"+ 

    "del "+toShortPath(m_strWinDir)+"\\sysbckup\\*.cab\n"+ 

    "copy "+toShortPath(getMyDir())+m_restoreDlg.m_strSeled+" "+toShortPath(m_strWinDir) +"\\sysbckup\\rb000.cab \n"+ 

    "copy "+toShortPath(getMyDir())+"Autoexec.bak c:\\Autoexec.bat /Y \n"+ 

    toShortPath(m_strWinDir)+"\\command\\scanreg.exe/restore"; 

  f.WriteString(m_strCommand); 

  f.Close(); 

  CopyFile(getMyDir()+"Autoexec.bak","c:\\Autoexec.bat",0); 

  CopyFile("c:\\Autoexec.bat",getMyDir()+"Autoexec.bak",0); 

  CopyFile(getMyDir()+"Autoexec.bat","c:\\Autoexec.bat",0); 

  if(IDCANCEL==AfxMessageBox("必须重启才能生效,你想现在重启吗?",MB_OKCANCEL)) 

    return; 

  else 

    ExitWindowsEx(EWX_REBOOT,NULL); 

  } 

  7.为"创建援救盘"按钮或菜单项生成一个响应函数: 

  void CRescueSysDlg::OnCreatea() 

  { 

  if(IDCANCEL==AfxMessageBox("请插入一张软盘,然后按确定键.\n\n注意:软盘上的所有内容将被删除.",MB_OKCANCEL)) 

    return; 

  CStdioFile f;         //建立包含建立启动盘的命令的批处理文件并执行. 

  f.Open(getMyDir()+"myTemp.bat", CFile::modeCreate|CFile::modeWrite,NULL); 

  CString m_strCommand=toShortPath(m_strWinDir)+"\\command\\deltree /Y a:\\ \n"+ 

    toShortPath(m_strWinDir)+"\\command\\sys c: a:\n"+ 

    "dir "+getMyDir()+"rescueSys.exe >> "+getMyDir()+"abcdefgh.txt"; 

  f.WriteString(m_strCommand); 

  f.Close(); 

  WinExec(getMyDir()+"myTemp.bat",SW_HIDE);   

  CTime m_beginTime=CTime::GetCurrentTime(); 

  CTimeSpan m_timeSpan=CTime::GetCurrentTime()-m_beginTime; 

  CFileFind finder; 

  while(!finder.FindFile(getMyDir()+"abcdefgh.txt")) 

  //如果找到了abcdefgh.txt则说明批处理已经执行完毕. 

  { 

    MSG msg; 

    if(::PeekMessage(&msg,m_hWnd,0,0,PM_REMOVE)) 

    { 

      ::TranslateMessage(&msg); 

      ::DispatchMessage(&msg); 

    } 

    if(!(m_progress.GetPos()>=100)) 

      m_progress.SetPos(100*m_timeSpan.GetSeconds()/30); 

    m_timeSpan=CTime::GetCurrentTime()-m_beginTime; 

  } 

  m_progress.SetPos(100); 

  f.Open("a:\\autoexec.bat", CFile::modeCreate|CFile::modeWrite,NULL); 

  m_strCommand=(CString)"echo off \n"+"cls \n"+ 

    "copy "+toShortPath(getMyDir())+"*.cab "+toShortPath(m_strWinDir)+"\\sysbckup /Y \n"+ 

    toShortPath(m_strWinDir)+"\\command\\scanreg.exe/restore \n"; 

  f.WriteString(m_strCommand); 

  f.Close(); 

  AfxMessageBox("已经成功的创建了援救盘.");   

  DeleteFile(getMyDir()+"myTemp.bat"); 

  DeleteFile(getMyDir()+"abcdefgh.txt"); 

  }

视频教程列表
文章教程搜索
 
C语言程序设计推荐教程
C语言程序设计热门教程
看全部视频教程
购买方式/价格
购买视频教程: 咨询客服
tel:15972130058