[转]exe与dll的自我更新

原地址:http://blog.csdn.net/allenky/archive/2008/10/16/3087444.aspx

 

在改写一个软件的自动更新程序时遇到一个问题

exe与dll在载入的时候是不能覆盖与删除的...

自动更新的时候,如何把用http/ftp下载下来的新版本替换旧版本

 

第一种是最老土的办法:

假设a.exe要更新自己, down下来为a.exe.upd, 关闭自己,并execute一个第三方程序b.exe,

b.exe 功能就是 将a.exe.upd拷贝替换a.exe,再execute a.exe

优点:用几个简单的api就能搞定,基本上没什么难度...许多软件/游戏的自动更新程序用这种办法

缺点:适应性差,不能用于被别的程序占用文件的改写,只能用于exe文件,而且名称之类相对固定,需要第三方程序

 

第二种重启计算机大法

一般的安装程序都用此法,象驱动程序,系统软件安装,均提示需要重启电脑生效,

这种方法涉及到一个关键的API ::MoveFileEx 些函数详见MSDN

BOOL MoveFileEx(

LPCTSTR lpExistingFileName,

LPCTSTR lpNewFileName,

DWORD dwFlags

);

它的第三个参数使用

MOVEFILE_DELAY_UNTIL_REBOOT标志与MOVEFILE_REPLACE_EXISTING标志时

将在电脑启动时,自动替换文件...

以下是半伪半真代码...

a.exe 下载新版本a.exe.upd

if succeed(deletefile( a.exe))

movefile(a.exe.upd,a.exe);//如果删除成功,直接替换

else

{

MoveFileEx("'a.exe", "a.exe.upd",MOVEFILE_DELAY_UNTIL_REBOOT|MOVEFILE_REPLACE_EXISTING);

MessageBox("restart computer, yes/no?");

}

优点:适用性强,基本上能处理任何类型和任何情况的文件,非常保险

缺点:要重启计算机

 

第三种方法,也是我试过很多种后,使用的办法

前面说过exe与dll在载入的时候是不能覆盖与删除的,但是它能被改名

a.exe 下载新版本a.exe.upd

先将a.exe改成a.exe.tmp,

现在a.exe.tmp是不能被删除与覆盖的,

而a.exe这个文件不存在了

将a.exe.upd改名为a.exe

再关闭自己,重新启动a.exe,这时a.exe已经是新版的了

DeleteFile("a.exe.tmp");//以防万一,删除a.exe.tmp

Rename("a.exe","a.exe.tmp");

if SUCCEED(Rename("a.exe.upd","a.exe")){

Execute("a.exe");

CloseSelf();

}

else{

//特殊情况,连a.exe.tmp都被占用了,按第二种方法重启处理吧

}

优点:自己搞定,简单明了

缺点:不能用于被别的程序占用文件的改写,只能用于exe或者dll文件

原文地址:https://www.cnblogs.com/foxhengxing/p/2048235.html