如何实现自身的升级? 一般正在运行的应用程序不允许删除或修改的 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 //主程序进程 打开 升级程序进程{ 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程序。这个问题就像,如何给自己递头。 如何判断某个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. 我用批处理的方法function killself:boolean;var Batchfile: TextFile; BatchFileName: string; ProcessInfo: TProcessInformation; StartUpInfo: TStartupInfo; begin BatchFileName := ExtractFilePath(ParamStr(0)) + '$$a$$.bat'; AssignFile(BatchFile, BatchFileName); Rewrite(BatchFile); Writeln(BatchFile, ':try'); Writeln(BatchFile, 'del "' + GetShortName(ParamStr(0)) + '"'); Writeln(BatchFile, 'if exist "' + GetShortName(ParamStr(0)) + '"' + ' goto try');Writeln(BatchFile, 'move zjgl.new "' + GetShortName(ParamStr(0)) + '"');Writeln(BatchFile, 'del %0');Writeln(BatchFile, 'cls'); Writeln(BatchFile, 'exit'); CloseFile(BatchFile); FillChar(StartUpInfo, SizeOf(StartUpInfo), $00); StartUpInfo.dwFlags := STARTF_USESHOWWINDOW; StartUpInfo.wShowWindow := SW_Hide; if CreateProcess(nil, PChar(BatchFileName), nil, nil, False, IDLE_PRIORITY_CLASS, nil, nil, StartUpInfo, ProcessInfo) then begin CloseHandle(ProcessInfo.hThread); CloseHandle(ProcessInfo.hProcess); end; Application.Terminate; end; 只能用批处理的方法,建立.bat文件,在程序关闭的事件里运行.bat文件就行,在.bat里可以写实现方法,主要是你要把你的那个要更新本身的程序从服务器上载下来,改成另外一个名字,在批处理中,删除原文件,改新文件名. 把升级程序专门做一个EXE去判断是否有新版本如果没有,关闭升级.EXE,启动主程序.EXE如果有,下载相关更升文件下载完成后,关闭升级.EXE,启动主程序.EXE 将主程序的窗口句柄传给update.exe,由update.exe发WM_CLOSE消息关闭主程序,我就是这样实现的。推荐我的产品,免费使用:Visession Anyupdate自动升级软件系统免费将自动升级功能加入您的软件产品中网站:http://www.visession.com/anyupdate下载:http://www.visession.com/anyupdate/DownLoad.htm 新手请教,如何使用2维数组。 求:界面美化熟手 TXMLDocument 问题,请大家帮帮忙! 主窗口的背景图为什么总是出不来? 一个关于DBCHART的使用问题。 delphi+mapx,新手的简单问题:怎么我在一个图层上加feature,老是出错。。。 delphi+access 急,急,急 那里有InstallShield for Delphi 6下载 mssql 数据库 varchar(1000) 用BDE如何读 软件自动升级后的问题... MIDAS是否已经淘汰?
{ 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),
把真正的程序改个名字: 没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.
function killself:boolean;
var
Batchfile: TextFile;
BatchFileName: string;
ProcessInfo: TProcessInformation;
StartUpInfo: TStartupInfo;
begin
BatchFileName := ExtractFilePath(ParamStr(0)) + '$$a$$.bat';
AssignFile(BatchFile, BatchFileName);
Rewrite(BatchFile);
Writeln(BatchFile, ':try');
Writeln(BatchFile, 'del "' + GetShortName(ParamStr(0)) + '"');
Writeln(BatchFile, 'if exist "' + GetShortName(ParamStr(0)) + '"' + ' goto try');
Writeln(BatchFile, 'move zjgl.new "' + GetShortName(ParamStr(0)) + '"');
Writeln(BatchFile, 'del %0');
Writeln(BatchFile, 'cls');
Writeln(BatchFile, 'exit');
CloseFile(BatchFile);
FillChar(StartUpInfo, SizeOf(StartUpInfo), $00);
StartUpInfo.dwFlags := STARTF_USESHOWWINDOW;
StartUpInfo.wShowWindow := SW_Hide;
if CreateProcess(nil, PChar(BatchFileName), nil, nil,
False, IDLE_PRIORITY_CLASS, nil, nil, StartUpInfo,
ProcessInfo) then
begin
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
end;
Application.Terminate;
end;
如果没有,关闭升级.EXE,启动主程序.EXE
如果有,下载相关更升文件
下载完成后,关闭升级.EXE,启动主程序.EXE
免费将自动升级功能加入您的软件产品中
网站:http://www.visession.com/anyupdate
下载:http://www.visession.com/anyupdate/DownLoad.htm