|
为了给自己的程序实现自动升级的功能,这2天查了点资料,写了这个程序。就算是原创吧,当然也参考了网上的资料。呵呵。当然,还不完美,目前只是将就实现了基本的功能,下载大文件窗体假死的问题还是没有解决,还有,进度条的问题也处理不好,还有很多要完善的地方。希望需要的朋友自己去完善。
我开始也在网上找了相关的代码,但都不完整,不是缺这个就是少那个,很少有能拿来就用的。估计是作者只提供了部分的代码吧。以下是我的全部源代码,没有删除任何内容,保证大家复制之后,添加完相应的控件就可以运行。使用了Tlhelp323,这个文件的代码,在:http://blog.csdn.net/leoruby/archive/2010/11/01/5979545.aspx
以下是我的配置文件的格式,这个大家可以根据自己的需要再更改,本程序就是通过比较这2个文件,来进行更新的。
本地version.ine文件格式:
[update]
version=1.0
远程update.ini文件格式:
[update]
version=2.1
[updatelist]
up1=1.exe
up2=2.dll
up3=3.txt
......
//////////////////////////////////////////////////////////////////
unit MainFrm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, FileCtrl, ShellApi, IniFiles, Tlhelp323,
IdAntiFreezeBase, IdAntiFreeze, IdBaseComponent, IdComponent,
IdTCPConnection, IdTCPClient, IdHTTP, StdCtrls;
type
TMainForm = class(TForm)
ProgressBar1: TProgressBar;
IdHTTP1: TIdHTTP;
IdAntiFreeze1: TIdAntiFreeze;
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure CheckVersion();
procedure UpdateStart();
procedure Deletedir(str:string);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainForm: TMainForm;
//全局变量
weburl: string = 'http://192.168.100.88/update/'; //升级文件存放目录
implementation
{$R *.dfm}
procedure TMainForm.Button1Click(Sender: TObject);
begin
IdAntiFreeze1.OnlyWhenIdle:=false; //防止idhttp假死,不过好像不管用
button1.visible:=false;
CheckVersion; //调用版本检查程序
end;
procedure TMainForm.CheckVersion();
var
h:TIdhttp;
MyStream:TMemoryStream;
updateini,versionini: Tinifile;
newversion:string;//updateini
oldversion:string;//versionini
begin
//下载新版本文件,保存到本地 //////////////////////////
MyStream:=TMemoryStream.Create;
h:=Tidhttp.Create(nil);
try
h.get(weburl+'update.ini',MyStream);
except
showmessage('网络连接出错,请稍候再试!');
MyStream.Free;
exit;
end;
CreateDir('update'); //创建文件夹 uses FileCtrl
MyStream.SaveToFile('update/update.ini'); //保存文件
MyStream.Free;
//showmessage('下载新版本说明文件成功');
/////////新旧版本文件比较,判断是否需要升级////////////////////////
versionini:=Tinifile.Create(ExtractFilePath(Paramstr (0))+'version.ini');
updateini:=Tinifile.Create(ExtractFilePath(Paramstr (0))+'update/update.ini');
oldversion:=versionini.ReadString('update','Version','');
newversion:=updateini.ReadString('update','Version','');
if newversion <= oldversion then
begin
showmessage('您当前的软件是最新版本,不需要进行更新');
Deletedir('update');
//application.Terminate;
button1.Visible:=true;
end
else begin
if newversion > oldversion then
begin
showmessage('发现新版本,开始更新');
UpdateStart; //调用升级程序
end;
end;
end;
procedure TMainForm.UpdateStart();
var
h:TIdhttp;
res : String;
MyStream:TMemoryStream;
updateini,versionini: Tinifile;
filename:string;
newversion:string;//updateini
oldversion:string;//versionini
list1: array [1..100] of string;
list :array [1..100] of string;
i,sum: integer;
//进度条使用
FileSize: integer;
j,k: integer;
begin
IdAntiFreeze1.OnlyWhenIdle:=false;
//////////////关联ini文件及流媒体文件等初始化操作///////////////////
versionini:=Tinifile.Create(ExtractFilePath(Paramstr (0))+'version.ini');
updateini:=Tinifile.Create(ExtractFilePath(Paramstr (0))+'update/update.ini');
//MyStream:=TMemoryStream.Create;
///////////////////////////////////////////////// 取得更新列表
for i:=1 to 100 do
begin
list:='up'+inttostr(i);
list1:=updateini.ReadString('updatelist',list,'');
end;
//统计需要下载的文件个数
for i:=1 to 100 do
begin
if list1<>'' then sum:=sum+1;
end;
/////////////下载更新文件
i:=1;
CreateDir('update'); //创建下载更新的临时文件夹 uses FileCtrl
while list1<>'' do
begin
try
//进度条使用开始
//showmessage(weburl+list1);
IdHTTP1.Head(weburl+list1);
FileSize :=IdHTTP1.Response.ContentLength;
progressbar1.Max:=filesize;
k:=filesize div 5;
//showmessage(weburl+list1);
progressbar1.Max:=j;
for j:=1 to k do
begin
Progressbar1.Position:=j
end;
//showmessage('下载完毕');
//进度条使用结束
//开始下载文件
MyStream:=TMemoryStream.Create;
h:=Tidhttp.Create(nil);
h.get(weburl+list1,MyStream);
except
showmessage('网络出错,更新失败,请稍候更新!!');
MyStream.Free;
exit;
end;
//显示更新个数
label1.Caption:='本次总共需要下载文件'+inttostr(sum)+'个,已经下载'+inttostr(i)+'个';
MyStream.SaveToFile('update/'+list1); //保存文件
MyStream.Free;
i:=i+1;
end;
showmessage('下载所需的更新文件成功,如果您开启了主程序,升级程序将关闭主程序进行软件更新');
KillTask('test.exe'); //关闭要更新的软件进程
sleep(1000);
////////导入文件
i:=1;
while list1<>'' do
begin
if CopyFile(pchar('update/'+list1),pchar(list1),false) then
begin
i:=i+1;
end
else begin
showmessage('更新失败,请稍候更新!');
exit;
end;
end;
///重写versionini文件
oldversion:=versionini.ReadString('update','Version','');
newversion:=updateini.ReadString('update','Version','');
versionini.writestring('update','version',newversion);
//更新成功,删除临时文件 ,重启程序。
showmessage('软件更新成功,程序将重新启动');
Deletedir('update');
winexec(PChar(test.exe'), SW_SHOWNORMAL); //启动指定的可执行程序
application.Terminate;//关闭自己
end;
//删除包含文件的文件夹
procedure TMainForm.Deletedir(str:string);
Var
T:TSHFileOpStruct;
P:String;
begin
P:= str; //'update';//这里改成你要删除的任意目录名,P:=str str 是传过来的目录路径
With T do
Begin
Wnd:=0;
wFunc:=FO_DELETE;
pFrom:=Pchar(P);
pTo:=nil;
fFlags:=FOF_ALLOWUNDO+FOF_NOCONFIRMATION+FOF_NOERRORUI;//标志表明允许恢复,无须确认并不显示出错信息
hNameMappings:=nil;
lpszProgressTitle:= '正在删除文件夹 ';
fAnyOperationsAborted:=False;
End;
SHFileOperation(T);
//Application.MessageBox( '删除成功! ', '系统提示 ',64);
end;
end. |
|