zoukankan      html  css  js  c++  java
  • Delphi

    Delphi 实现可执行程序的自动升级

    准备工作:

    1:Delphi调用TIdHTTP方式开发程序,生成程序打包外壳

    说明:程序工程命名为ERP_Update

    界面布局如下:

    代码实现如下:

      1 unit Unit1;
      2 
      3 interface
      4 
      5 uses
      6   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      7   Dialogs, StdCtrls, ExtCtrls,
      8   IdTCPConnection, SHELLAPI, ComCtrls, jpeg, IdHTTP,
      9   IdTCPClient, IdBaseComponent, IdComponent, Registry;
     10 
     11 type
     12   TFrm_FTP = class(TForm)
     13     Label4: TLabel;
     14     IdHTTP1: TIdHTTP;
     15     Image1: TImage;
     16     ProgressBar1: TProgressBar;
     17     Label1: TLabel;
     18     procedure RUN_START;
     19     procedure FormCreate(Sender: TObject);
     20     procedure IdHTTP1Work(Sender: TObject; AWorkMode: TWorkMode;
     21       const AWorkCount: Integer);
     22     procedure IdHTTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
     23       const AWorkCountMax: Integer);
     24     procedure IdHTTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
     25     function HttpDownLoad(aURL, aFile: string): Boolean;
     26     function GetURLFileName(aURL: string): string;
     27     function GET_CODE(V_s: TstringS; V_CODE: string): string;
     28     function GET_SubStr(V_s: string; V_CODE1, V_CODE2: string): string;
     29     procedure DelFile(V_Name: string);
     30     function GET_Ora_Home(): string;
     31   private
     32         { Private declarations }
     33 
     34   public
     35         { Public declarations }
     36   end;
     37 
     38 var
     39   Frm_FTP: TFrm_FTP;
     40   ss: Tstrings;
     41   V_Err: Boolean;
     42   BytesToTransfer: LongWord;
     43 
     44 implementation
     45 
     46 {$R *.dfm}
     47 
     48 function TFrm_FTP.GET_Ora_Home(): string;
     49 var
     50   v_Result: string;
     51 begin
     52   v_Result := '';
     53   with TRegistry.Create do
     54   try
     55     RootKey := HKEY_LOCAL_MACHINE;
     56     if OpenKey('SoftwareORACLE', false) then
     57     begin
     58       v_Result := ReadString('ORACLE_HOME');
     59       if v_Result <> '' then
     60         v_Result := v_Result + '
    etworkadmin	nsnames.ora';
     61       CloseKey;
     62     end;
     63   finally
     64     Free;
     65   end;
     66   Result := v_Result;
     67 end;
     68 
     69 procedure TFrm_FTP.RUN_start;
     70 var
     71   V_LiveUpdate, V_version, C_ServerIP, C_ServerVer, C_ExeVer, c_ExeName, C_ExePath: string;
     72   i: Integer;
     73 begin
     74   V_Err := False;
     75   C_ExePath := ExtractFilePath(Application.ExeName); //可执行程序的路径[D:CDERP长电包装生产管理系统]
     76   //获取本地的版本信息等数据
     77   ss := Tstringlist.create;
     78   ss.loadfromfile(C_ExePath + 'LiveUpdate.ini');
     79   V_version := GET_SubStr(ss.Strings[1], 'url=', ''); //服务器地址
     80   V_LiveUpdate := stringreplace(UpperCase(V_version), 'VERSION.INF', 'LIVEUPDATE.INI', [rfReplaceAll]); //服务器地址
     81   C_ExeVer := GET_SubStr(ss.Strings[2], 'version=', ''); //本地程序的版本
     82   C_ExeName := GET_SubStr(ss.Strings[3], 'exe=', ''); //本地程序的名称
     83   //获取服务器的版本
     84   if HttpDownLoad(V_version, C_ExePath + GetURLFileName(V_version)) then
     85   begin
     86     ss.loadfromfile(C_ExePath + 'version.inf');
     87     C_ServerVer := get_code(ss, '#version=');
     88   end
     89   else
     90     C_ServerVer := C_ExeVer; //如果升级服务器异常就不升级
     91   if (trim(ParamStr(1)) = '') or (trim(ParamStr(1)) = '/afterupgrade0') then
     92   begin
     93     //程序在本地第一次执行,如果需要升级将下载cderp.exe到本地update.exe并执行
     94     //比较版本信息
     95     if C_ServerVer > C_ExeVer then
     96     begin
     97       C_ExeVer := C_ServerVer;
     98       DelFile(C_ExePath + 'update.exe');
     99       HttpDownLoad(GET_SubStr(V_version, '', '/exe/') + '/exe/ERP_Update.exe', C_ExePath + 'update.exe');
    100       ShellExecute(handle, 'open', pchar(C_ExePath + 'ERP_Update.exe'), pchar('"' + C_ExePath + '" "' + C_ExeVer + '"'), nil, SW_ShowNormal);
    101     end
    102     else
    103       ShellExecute(handle, 'open', pchar(C_ExePath + C_ExeName), nil, nil, SW_ShowNormal);
    104     application.Terminate;
    105   end
    106   else
    107   begin
    108     Frm_FTP.WindowState := wsNormal;
    109     Frm_FTP.Visible := true;
    110     Frm_FTP.Refresh;
    111     V_Err := False;
    112     //防止可执行程序没有完全关闭, 等待一会
    113     ProgressBar1.max := 100;
    114     for i := 1 to 100 do
    115     begin
    116       Label4.Caption := '升级准备...';
    117       ProgressBar1.Position := i;
    118       Application.ProcessMessages;
    119       Sleep(50);
    120     end;
    121     for i := 1 to 100 do
    122     begin
    123       C_ServerIP := get_code(ss, '#url' + trim(IntToStr(i)) + '=');
    124       if C_ServerIP = '' then
    125       begin
    126         Break;
    127       end;
    128       HttpDownLoad(C_ServerIP, C_ExePath + GetURLFileName(C_ServerIP));
    129     end;
    130     HttpDownLoad(V_LiveUpdate, C_ExePath + GetURLFileName(V_LiveUpdate));
    131     if not V_Err then
    132     begin
    133       ss.loadfromfile(C_ExePath + GetURLFileName(V_LiveUpdate));
    134       ss.delete(3);
    135       ss.delete(2);
    136       ss.Add('version=' + C_ServerVer);
    137       ss.Add('exe=' + C_ExeName);
    138       ss.savetofile(C_ExePath + GetURLFileName(V_LiveUpdate));
    139       ss.free;
    140       Application.MessageBox('程序已经升级完成!', '升级完成', MB_ICONINFORMATION + MB_OK);
    141       ShellExecute(handle, 'open', pchar(C_ExePath + C_ExeName), nil, nil, SW_ShowNormal);
    142     end;
    143     application.Terminate;
    144   end;
    145 end;
    146 
    147 procedure TFrm_FTP.FormCreate(Sender: TObject);
    148 begin
    149   RUN_start;
    150 end;
    151 
    152 function TFrm_FTP.GET_CODE(V_s: TstringS; V_CODE: string): string;
    153 var
    154   i, j, l: integer;
    155   v_Result: string;
    156 begin
    157   j := V_s.Count - 1;
    158   l := length(v_code);
    159   i := 0;
    160   while i <= j do
    161   begin
    162     if copy(trim(UpperCase(V_s.Strings[i])), 1, l) = UpperCase(V_CODE) then
    163     begin
    164       v_Result := copy(trim(V_s.Strings[i]), l + 1, 500);
    165       j := 0;
    166     end;
    167     i := i + 1;
    168   end;
    169   Result := v_Result;
    170 end;
    171 
    172 function TFrm_FTP.GET_SubStr(V_s: string; V_CODE1, V_CODE2: string): string;
    173 var
    174   j, k: integer;
    175   v_str: string;
    176 begin
    177   //Label4.Caption := GET_SubStr('url=http://192.1.1.0/exe/ERP_Update/version.inf', '://', '/exe');
    178   //数据解析,找到字符串中的子串
    179   v_str := UpperCase(V_s);
    180   k := pos(UpperCase(v_code1), v_str);
    181   if v_code1 = '' then
    182   begin
    183     k := 1;
    184   end;
    185   if k > 0 then
    186   begin
    187     v_str := copy(v_str, k + length(v_code1), 500);
    188     if v_code2 = '' then
    189       k := 500
    190     else
    191       k := pos(UpperCase(v_code2), v_str);
    192     if k > 0 then
    193     begin
    194       v_str := copy(v_str, 1, k - 1);
    195     end
    196     else
    197     begin
    198       v_str := '';
    199     end;
    200   end
    201   else
    202   begin
    203     v_str := '';
    204   end;
    205   Result := v_str;
    206 end;
    207 
    208 procedure TFrm_FTP.DelFile(V_Name: string);
    209 var
    210   i: integer;
    211 begin
    212   i := 0;
    213   while FileExists(V_Name) do
    214   begin
    215     DeleteFile(V_Name);
    216     Application.ProcessMessages;
    217     i := i + 1;
    218     if i > 10 then
    219     begin
    220       if MessageDlg('系统不能执行删除操作[' + V_Name + '],是否重试?', mtConfirmation, [mbYes, mbNo], 0) = mrNO then
    221       begin
    222         i := 0;
    223         Abort;
    224       end;
    225     end;
    226   end;
    227 end;
    228 
    229 procedure TFrm_FTP.IdHTTP1Work(Sender: TObject; AWorkMode: TWorkMode;
    230   const AWorkCount: Integer);
    231 begin
    232   ProgressBar1.Position := AWorkCount;
    233 end;
    234 
    235 procedure TFrm_FTP.IdHTTP1WorkBegin(Sender: TObject; AWorkMode: TWorkMode;
    236   const AWorkCountMax: Integer);
    237 begin
    238   if AWorkCountMax > 0 then
    239     ProgressBar1.max := AWorkCountMax
    240   else
    241     ProgressBar1.Max := BytesToTransfer;
    242 
    243 end;
    244 
    245 procedure TFrm_FTP.IdHTTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
    246 begin
    247   BytesToTransfer := 0;
    248 
    249 end;
    250 //http方式下载
    251 
    252 function TFrm_FTP.HttpDownLoad(aURL, aFile: string): Boolean;
    253 var
    254   MyStream: TMemoryStream; //如果文件不存在
    255   F_Str: string;
    256 begin
    257   if V_Err then exit;
    258   try
    259     label4.Caption := '正在升级...' + GetURLFileName(aURL);
    260     label4.Refresh;
    261     MyStream := TMemoryStream.Create;
    262     IdHTTP1.Request.ContentRangeStart := 0;
    263     try
    264       IdHTTP1.Get(stringreplace(UpperCase(aURL), '192.1.1.0/EXE/', '192.1.1.0/EXE/', [rfReplaceAll]), MyStream); //开始下载
    265       MyStream.SaveToFile(aFile);
    266       if pos('.REG', UpperCase(aFile)) > 0 then
    267         WinExec(pchar('regedit.exe /s "' + aFile + '"'), SW_HIDE);
    268 
    269       if pos('TNSNAMES.ORA', UpperCase(aFile)) > 0 then
    270       begin
    271         F_Str := GET_Ora_Home;
    272         if F_Str <> '' then MyStream.SaveToFile(F_Str);
    273       end;
    274 
    275       label4.Caption := '升级完成';
    276     finally
    277       MyStream.Free;
    278     end;
    279     Result := True;
    280   except
    281     on E: Exception do
    282     begin
    283       Application.MessageBox(PChar('升级[' + GetURLFileName(aURL) + ']过程中出现错误了,错误信息如下:' + #13 + #10 + E.Message), PChar('系统提示'), Mb_OK + MB_ICONERROR);
    284       V_Err := True;
    285       Result := False;
    286     end;
    287   end;
    288 end;
    289 
    290 function TFrm_FTP.GetURLFileName(aURL: string): string;
    291 var
    292   i: integer;
    293   s: string;
    294 begin
    295   s := aURL;
    296   i := Pos('/', s);
    297   while i <> 0 do //去掉"/"前面的内容剩下的就是文件名了
    298   begin
    299     Delete(s, 1, i);
    300     i := Pos('/', s);
    301   end;
    302   Result := s;
    303 end;
    304 
    305 end.

    2:FTP服务器搭建,FTP用户创建

    举例说明如下:

    在192.1.1.0上创建FTP账户Test 密码Test,路径 exe;

    案例:将Test.exe系统做出一个可以自动升级的系统

    文件准备:

    1:Test.exe (目标系统);

    2:ERP_Update.exe (自动升级外壳程序);

    3:创建配置文件 (LiveUpdate.ini、Version.inf);

    建立一个记事本文件,命名为LiveUpdate.ini,内容输入

    [LiveUpdate]
    url=http://192.1.1.0/exe/Test/version.inf
    version=0
    exe=Test.EXE

    建立一个记事本文件,命名为version.inf,内容输入

    #############################################################
    #   Generated by AutoUpgrader Pro at: 2019-8-29 20:50:39    #
    #############################################################
    #message={}
    #url1=http://192.1.1.0/exe/ERP_Update.exe
    #url2=http://192.1.1.0/exe/Test/Test.exe
    #url3=http://192.19.1.0/exe/Test/version.inf
    #method=0 (self-upgrade)
    #version=0

    4:FTP操作(文件替换、配置文件更新);

    将Test.exe (目标系统)、ERP_Update.exe (自动升级外壳程序)、创建配置文件 (LiveUpdate.ini、Version.inf)文件同时放到192.1.1.0FTP服务器exeTest文件夹下。

    并手工修改LiveUpdate中的Version,同理Version中也需要这么改。

    至此在本地打开ERP_Udapate即可实现自动升级。

      作者:Jeremy.Wu
      出处:https://www.cnblogs.com/jeremywucnblog/
      本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    Android 开发 深入理解Handler、Looper、Messagequeue 转载
    Android 开发 Handler的基本使用
    Java 学习 注解
    Android 开发 AlarmManager 定时器
    Android 开发 框架系列 百度语音合成
    Android 开发 框架系列 Google的ORM框架 Room
    Android 开发 VectorDrawable 矢量图 (三)矢量图动画
    Android 开发 VectorDrawable 矢量图 (二)了解矢量图属性与绘制
    Android 开发 VectorDrawable 矢量图 (一)了解Android矢量图与获取矢量图
    Android 开发 知晓各种id信息 获取线程ID、activityID、内核ID
  • 原文地址:https://www.cnblogs.com/jeremywucnblog/p/11429115.html
Copyright © 2011-2022 走看看