实现软件自动升级

http://blog.csdn.net/bdmh/article/details/6120459

 

原理简单,在FTP上维护一个Update.ini文件,里面记录着要更新文件的版本号,本地也有一个Update.ini文件,每次启动更新程序时,先从FTP上下载Update.ini文件到本地名字为Update_new.ini,然后比较这两个文件,如果新的版本号大于旧的,或者新的文件在就ini中没有,这些就表示要更新的文件,然后逐一下载。

    本程序名字为AutoUpdate,你生成这个exe,然后和主程序一起打包,创建桌面快捷方式时,指向AutoUpdate,而不是主程序。

    在本地还有一个ini文件,比如叫ftp.ini吧,里面内容是

[coninfo]
main=Project1.exe
param={app}sayyes.pj2 -y bde.txt

 

main=Project1.exe:是主程序名称,和升级程序在同一目录

param={app}sayyes.pj2 -y bde.txt:这是命令行参数,app为当前路径,在程序中替换掉,传递给主程序(如果需要的话)

 

update.ini的内容格式如下

 

[root]
办事处查询.txt=20100519
[dbcard]
sayyes.pj2=20100519
FTP用户密码.txt=20100519

 

[root]代表根目录,后面的[dbcard]代表子目录,依次类推

 

  1. unit Main;  
  2.   
  3. interface  
  4.   
  5. uses  
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
  7.   Dialogs, StdCtrls, IdHTTP, IdBaseComponent, IdComponent, IdTCPConnection,  
  8.   IdTCPClient, IdFTP, ComCtrls, ExtCtrls,IniFiles,ShellAPI, jpeg;  
  9.   
  10. type  
  11.   TfrmMain = class(TForm)  
  12.     IdFTP1: TIdFTP;  
  13.     IdHTTP1: TIdHTTP;  
  14.     ProgressBar1: TProgressBar;  
  15.     GroupBox1: TGroupBox;  
  16.     ld_host: TLabeledEdit;  
  17.     ld_username: TLabeledEdit;  
  18.     ld_psw: TLabeledEdit;  
  19.     ld_port: TLabeledEdit;  
  20.     Label1: TLabel;  
  21.     cb_mode: TComboBox;  
  22.     ProgressBar2: TProgressBar;  
  23.     Label3: TLabel;  
  24.     list_file: TListView;  
  25.     Label4: TLabel;  
  26.     procedure IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode;  
  27.       const AWorkCount: Integer);  
  28.     procedure IdFTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);  
  29.     procedure FormCreate(Sender: TObject);  private  
  30.     { Private declarations }  
  31.     FSize:Integer;  
  32.     FPath: string;  
  33.     FExePath: string;  
  34.     FInitPath: string;  
  35.     FIniFile:TIniFile;  
  36.     FHandle:HWND;  
  37.     FMainExe:string;  
  38.     FParam: string;  
  39.   
  40.     procedure CheckUpdateList;  
  41.     function ConnectFTP:Boolean;  
  42.     procedure DownLoadFile;  
  43.     procedure LoadIni;  
  44.     procedure SaveIni;  
  45.   public  
  46.     { Public declarations }  
  47.   end;  
  48.   
  49. var  
  50.   frmMain: TfrmMain;  
  51.   
  52. implementation  
  53. uses  
  54.   Flash;  
  55. {$R *.dfm}  
  56. //下载进度   
  57. procedure TfrmMain.IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode;  
  58.   const AWorkCount: Integer);  
  59. begin  
  60.   ProgressBar1.Position := AWorkCount;  
  61.   Application.ProcessMessages;  
  62. end;  
  63.   
  64. procedure TfrmMain.IdFTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);  
  65. begin  
  66.   ProgressBar1.Position := 0;  
  67.   ProgressBar2.StepBy(1);  
  68. end;  
  69.   
  70. procedure TfrmMain.FormCreate(Sender: TObject);  
  71. var  
  72.   frm: TfrmFlash;  
  73. begin  
  74.   Self.Visible := False;  
  75.   //闪屏,可以不加   
  76.   frm := TfrmFlash.Create(nil);  
  77.   frm.Show;  
  78.   Application.ProcessMessages;  
  79.   FExePath := ExtractFilePath(Application.ExeName);  
  80.   FIniFile := TIniFile.Create(FExePath+'ftp.ini');  
  81.   //加载ini信息,就是主机和端口之类的信息   
  82.   LoadIni;  
  83.   try  
  84.     ConnectFTP;  
  85.     CheckUpdateList;  
  86.     Self.Visible := True;  
  87.     Application.ProcessMessages;  
  88.     DownLoadFile;  
  89.   finally  
  90.       
  91.     FreeAndNil(frm);  
  92.     IdFTP1.Quit;  
  93.     FParam := StringReplace(FParam,'{app}',FExePath,[rfReplaceAll]);  
  94. //更新完毕后,启动主程序,并传入命令行参数   
  95.     ShellExecute(Handle,'open',PChar(FExePath+FMainExe),PChar(FParam),nil,SW_NORMAL);  
  96.     Application.Terminate;  
  97.   end;  
  98. end;  
  99.   
  100. //检查更新列表   
  101. procedure TfrmMain.CheckUpdateList;  
  102. var  
  103.   oldFile,newFile:TStringList;  
  104.   i,ver,index:Integer;  
  105.   itemstr,itempath: string;  
  106.   item:TListItem;  
  107. begin  
  108.   oldFile := TStringList.Create;  
  109.   newFile := TStringList.Create;  
  110.   try  
  111.     list_file.Clear;  
  112.     //先下载服务器上的update.ini文件,存到本地update_new.ini   
  113.     IdFTP1.Get('update.ini',FExePath+'update_new.ini',True);  
  114.     if FileExists(FExePath + 'update.ini') = False then Exit;  
  115.     oldFile.LoadFromFile(FExePath + 'update.ini');  
  116.     newFile.LoadFromFile(FExePath + 'update_new.ini');  
  117.     itempath := '';  
  118.     //下面开始比较两个list,如果newFile的版本号大于oldFile的版本号或者oldFile中没有的都表示要更新的   
  119.     for i := 0 to newFile.Count - 1 do  
  120.     begin  
  121.       itemstr := newFile.Strings[i];  
  122.       if itemstr = '' then Continue;  
  123.       if itemstr[1] = '[' then  
  124.       begin  
  125.         itempath := Copy(itemstr,2,Length(itemstr)-2);  
  126.         //如果是根目录   
  127.         if itempath = 'root' then  
  128.           itempath := '/';  
  129.         Continue;  
  130.       end;  
  131.       itemstr := newFile.Names[i];  
  132.       index := oldFile.IndexOfName(itemstr);  
  133.       if index = - 1 then  
  134.       begin  
  135.         item := list_file.Items.Add;  
  136.         item.Caption := itemstr;  
  137.         item.SubItems.Add(itempath)  
  138.       end  
  139.       else  
  140.       begin  
  141.         ver := StrToIntDef(newFile.Values[itemstr],0);  
  142.         if ver > StrToIntDef(oldFile.Values[itemstr],0then  
  143.         begin  
  144.           item := list_file.Items.Add;  
  145.           item.Caption := itemstr;  
  146.           item.SubItems.Add(itempath);  
  147.         end;  
  148.       end;  
  149.     end;  
  150.     if list_file.Items.Count = 0 then Application.Terminate;  
  151.   finally  
  152.     oldFile.Free;  
  153.     newFile.Free;  
  154.   end;  
  155. end;  
  156.   
  157. function TfrmMain.ConnectFTP: Boolean;  
  158. begin  
  159.   Result := False;  
  160.   try  
  161.   IdFTP1.Host := ld_host.Text;  
  162.   IdFTP1.Port := StrToIntDef(ld_port.Text,21);  
  163.   IdFTP1.Username := ld_username.Text;  
  164.   IdFTP1.Password := ld_psw.Text;  
  165.   IdFTP1.Connect;  
  166.   IdFTP1.Passive := cb_mode.ItemIndex = 1;  
  167.   FInitPath := IdFTP1.RetrieveCurrentDir;  
  168.   Result := IdFTP1.Connected;  
  169.   except  
  170.     Result := False;  
  171.   end;  
  172. end;  
  173.   
  174. //下载文件更新   
  175. procedure TfrmMain.DownLoadFile;  
  176. var  
  177.   i:Integer;  
  178.   path:string;  
  179.   s1,s2:String;  
  180. begin  
  181.   ProgressBar2.Max := list_file.Items.Count;  
  182.   ProgressBar2.Position := 0;  
  183.   FIniFile.EraseSection('error');  
  184.   for i := 0 to list_file.Items.Count - 1 do  
  185.   begin  
  186.     Label4.Caption := '正在下载 '+list_file.Items[i].Caption;  
  187.     Application.ProcessMessages;  
  188.     IdFTP1.ChangeDir(FInitPath);  
  189.     path := list_file.Items[i].SubItems.Strings[0];  
  190.     if path <>'/' then  
  191.     begin  
  192.       IdFTP1.ChangeDir(path);  
  193.       ForceDirectories(FExePath+path);  
  194.       s1 := list_file.Items[i].Caption;  
  195.       s2 := FExePath+path+'/'+list_file.Items[i].Caption;  
  196.       IdFTP1.Get(s1,s2,True);  
  197.     end  
  198.     else  
  199.     begin  
  200.       s1 := list_file.Items[i].Caption;  
  201.       s2 := FExePath+'/'+list_file.Items[i].Caption;  
  202.       IdFTP1.Get(s1,s2,True);  
  203.       //记录失败项   
  204.       FIniFile.WriteString('error',list_file.Items[i].Caption,'成功');  
  205.     end;  
  206.     except  
  207.       //记录失败项   
  208.       FIniFile.WriteString('error',list_file.Items[i].Caption,'失败');  
  209.     end;  
  210.   end;  
  211.   Label4.Caption := '所有文件更新完毕!';  
  212.   DeleteFile(FExePath+'update.ini');  
  213.   CopyFile(PChar(FExePath+'update_new.ini'),PChar(FExePath+'update.ini'),False);  
  214. end;  
  215.   
  216. procedure TfrmMain.LoadIni;  
  217. begin  
  218.   ld_host.Text := FIniFile.ReadString('coninfo','host','******');  
  219.   ld_username.Text := FIniFile.ReadString('coninfo','user','******');  
  220.   ld_psw.Text := FIniFile.ReadString('coninfo','psw','******');  
  221.   ld_port.Text := FIniFile.ReadString('coninfo','port','21');  
  222.   cb_mode.ItemIndex := FIniFile.ReadInteger('coninfo','mode',1);  
  223.   FMainExe := FIniFile.ReadString('coninfo','main','Main.exe');  
  224.   FParam := FIniFile.ReadString('coninfo','param','');  
  225. end;  
  226.   
  227. procedure TfrmMain.SaveIni;  
  228. begin  
  229.   FIniFile.WriteString('coninfo','host',ld_host.Text);  
  230.   FIniFile.WriteString('coninfo','user',ld_username.Text);  
  231.   FIniFile.WriteString('coninfo','psw',ld_psw.Text);  
  232.   FIniFile.WriteString('coninfo','port',ld_port.Text);  
  233.   FIniFile.WriteInteger('coninfo','mode',cb_mode.ItemIndex);  
  234. end;  
  235.   
  236. end

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值