找回密码
 立即注册
查看: 1075|回复: 0

自己用delphi7参考网上资料写的一个在线升级程序

[复制链接]

6772

主题

8

回帖

2万

积分

管理员

积分
21723
发表于 2019-5-20 21:54:07 | 显示全部楼层 |阅读模式
    为了给自己的程序实现自动升级的功能,这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.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表