分享
 
 
 

用vc设计系统援救程序

王朝厨房·作者佚名  2007-01-04
窄屏简体版  字體: |||超大  

一.引言

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");

}

摘自《赛迪网》聂栋栋/文

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有