如何实现自身的升级?
一般正在运行的应用程序不允许删除或修改的
[解决办法]
主程序进程 打开 升级程序进程
升级程序进程 将 更新的文件 下载
升级程序进程 关闭 主程序进程
升级程序进程 替换 新主程序文件
升级程序进程 打开 新主程序进程
新主程序进程 关闭 升级程序进程
新主程序进程 替换 新升级程序文件
-.-!!!是不是有点晕
[解决办法]
//主程序进程 打开 升级程序进程
{ TODO : 先判断是否已经打开 }
WinExec(PChar(Format( 'LiveUpdate.exe %d ', [Handle])), 0);
//升级程序进程 将 更新的文件 下载
{ TODO }
//升级程序进程 关闭 主程序进程
//关闭主窗体
CloseWindow(StrToIntDef(ParamStr(0), 0));
//升级程序进程 替换 新主程序文件
CopyFile( 'newApplication.exe ', 'Application.exe ', True);
//DeleteFile( 'newApplication.exe ');
//升级程序进程 打开 新主程序进程
WinExec(PChar(Format( 'Application.exe %d ', [Handle])), 0);
//新主程序进程 关闭 升级程序进程
CloseWindow(StrToIntDef(ParamStr(0), 0));
//新主程序进程 替换 新升级程序文件
CopyFile( 'newLiveUpdate.exe ', 'LiveUpdate.exe ', True);
//DeleteFile( 'newLiveUpdate.exe ');
[解决办法]
修正,上面代码中
ParamStr(0) -> ParamStr(1),
[解决办法]
另外写一个update.exe程序。
这个问题就像,如何给自己递头。
[解决办法]
用传奇的升级方法:
把真正的程序改个名字: 没mir.exe改成米mir.dat 然后做个升级的EXE文件:
先到服务器下载文件版本(其实就是一个INI文件) 跟当前的版本对比(也是一个INI文件)
如果发现版本不对,就把新的载下来(在服务器上装个IIS或APACHE服务器什么的 用URLDownloadToFile这个API就可以载文件了,uses一下URLMon)
我写的:
const
HostIp= '192.168.2.126:8080 ';
IniLink = '/IM/update.ini ';
ExeLink = '/IM/Im.dat ';
BinName = 'Im.dat ';
var
PI:TProcessInformation;
SI:TStartUpInfo;
fSuccess:boolean;
rt:HResult;
path:string;
oldIniFile, newIniFile: TiniFile;
oldIniPath, newIniPath:string;
oldVersion, newVersion:string;
Label EXECBIN;
begin
Application.Initialize;
Path:= ExtractFilePath(Application.ExeName)+ 'config\ ';
oldIniPath:= Path+ 'old\ '+ 'update.ini ';
newIniPath:= Path+ 'new\ '+ 'update.ini ';
//下载版本信息
//showmessage( 'http:// '+HostIp+IniLink);
rt:= URLDownloadToFile(nil, pchar( 'http:// '+HostIp+IniLink), pchar(newIniPath), 0,nil);
if rt = S_OK then
begin
//showmessage( 'ok ');
end else
begin
//showmessage( 'down err ');
goto EXECBIN;
end;
//对比版本号,不同就下载最新的
newIniFile:= TIniFile.Create(newIniPath);
oldIniFile:= TIniFile.Create(oldIniPath);
//newIniFile.ReadString( 'update ', 'exename ', ' ');
newVersion:= newIniFile.ReadString( 'update ', 'version ', ' ');
oldVersion:= oldIniFile.ReadString( 'update ', 'version ', ' ');
if oldVersion <> newVersion then
begin
rt:= URLDownloadToFile(nil, pchar( 'http:// '+HostIp+ExeLink), pchar(ExtractFilePath(Application.ExeName)+BinName), 0,nil);
if rt = S_OK then
begin
//showmessage( 'ok ');
copyFile(pchar(newIniPath), pchar(oldIniPath), false);
end else
begin
showmessage( '程序不是最新的,且下载失败! ');
goto EXECBIN;
end;
end
else
begin
goto EXECBIN; //最新的
end;
EXECBIN:
FillChar(SI,sizeof(SI),#0);
with SI do
begin
cb:=sizeof(SI);
dwFlags:=StartF_UsesTDHandles or STARTF_USESHOWWINDOW;
lptitle:=nil;
wShowWindow:=SW_Show;
end;
fSuccess:= CreateProcess(PChar(ExtractFilePath(Application.ExeName)+BinName),
nil,nil,nil,true,DETACHED_PROCESS,nil,nil,SI,PI);
if fSuccess then
begin
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
end;
Application.Terminate;
end.