Delphi realizes the function of automatic software upgrade
The principle is simple. Maintain an Update.ini file on FTP, which records the version number of the file to be updated. There is also an Update.ini file locally. Every time the update program is started, the Update.ini file is first downloaded from FTP to the local name. is Update_new.ini, and then compares the two files. If the new version number is greater than the old one, or the new file is not in the old ini, these represent the files to be updated, and then download them one by one.
The name of this program is AutoUpdate. You generate this exe and then package it with the main program. When creating a desktop shortcut, point to AutoUpdate instead of the main program.
There is also an ini file locally, let's call it ftp.ini for example. The content inside is
[coninfo]
main=Project1.exe
param={app}sayyes.pj2 -y bde.txt
main=Project1.exe: is the name of the main program, which is in the same directory as the upgrade program
param={app}sayyes.pj2 -y bde.txt: This is the command line parameter, app is the current path, replace it in the program and pass it to the main program (if necessary)
The content format of update.ini is as follows
[root]
Office inquiry.txt=20100519
[dbcard]
sayyes.pj2=20100519
FTP user password.txt=20100519
[root] represents the root directory, and [dbcard] represents the subdirectory, and so on.
unit Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, IdHTTP, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdFTP, ComCtrls, ExtCtrls,IniFiles,ShellAPI, jpeg; type TfrmMain = class(TForm) IdFTP1: TIdFTP; IdHTTP1: TIdHTTP; ProgressBar1: TProgressBar; GroupBox1: TGroupBox; ld_host: TLabeledEdit; ld_username: TLabeledEdit; ld_psw: TLabeledEdit; ld_port: TLabeledEdit; Label1: TLabel; cb_mode: TComboBox; ProgressBar2: TProgressBar; Label3: TLabel; list_file: TListView; Label4: TLabel; procedure IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer); procedure IdFTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode); procedure FormCreate(Sender: TObject) ; private { Private declarations } FSize:Integer; FPath: string; FExePath: string; FInitPath: string; FIniFile:TIniFile; FHandle:HWND; FMainExe:string; FParam: string; procedure CheckUpdateList; function ConnectFTP:Boolean; end; var frmMain: TfrmMain; implementation uses Flash; {$R *.dfm} //Download progress procedure TfrmMain.IdFTP1Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer); begin ProgressBar1.Position := AWorkCount; Application.ProcessMessages; end; procedure TfrmMain.IdFTP1WorkEnd(Sender: TObject; AWorkMode: TWorkMode); begin ProgressBar1.Position := 0; ProgressBar2.StepBy(1); end; procedure TfrmMain.FormCreate(Sender: TObject); var frm: TfrmFlash; begin Self.Visible := False; //Flash screen, you can not add frm := TfrmFlash.Create(nil ); frm.Show; Application.ProcessMessages; FExePath := ExtractFilePath(Application.ExeName); FIniFile := TIniFile.Create(FExePath+'ftp.ini'); //Load ini information, which is information such as host and port. LoadIni; try ConnectFTP; CheckUpdateList; Self.Visible := True; Application.ProcessMessages; DownLoadFile; finally FreeAndNil(frm); IdFTP1.Quit; FParam := StringReplace(FParam,'{app}',FExePath,[rfReplaceAll]); //After the update is completed, start the main program and pass in the command line parameters ShellExecute(Handle,'open',PChar(FExePath+FMainExe),PChar( FParam),nil,SW_NORMAL); Application.Terminate; end; end; //Check update list procedure TfrmMain.CheckUpdateList; var oldFile,newFile:TStringList; i,ver,index:Integer; itemstr,itempath: string; item:TListItem; begin oldFile := TStringList.Create; newFile := TStringList.Create; try list_file.Clear; / /First download the update.ini file on the server and save it to the local update_new.ini IdFTP1.Get('update.ini',FExePath+'update_new.ini',True); if FileExists(FExePath + 'update.ini') = False then Exit; oldFile.LoadFromFile(FExePath + 'update.ini'); newFile .LoadFromFile(FExePath + 'update_new.ini'); itempath := ''; //The following starts to compare the two lists. If the version number of newFile is greater than the version number of oldFile or there is no version number in oldFile, it means that it needs to be updated. for i := 0 to newFile.Count - 1 do begin itemstr := newFile.Strings[i ]; if itemstr = '' then Continue; if itemstr[1] = '[' then begin itempath := Copy(itemstr,2,Length(itemstr)-2); //If it is the root directory if itempath = 'root' then itempath := '/'; Continue; end; itemstr := newFile.Names[i]; index := oldFile.IndexOfName(itemstr); if index = - 1 then begin item := list_file.Items .Add; item.Caption := itemstr; item.SubItems.Add(itempath) end else begin ver := StrToIntDef(newFile.Values[itemstr],0); if ver > StrToIntDef(oldFile.Values[itemstr],0) then begin item := list_file.Items.Add; item.Caption := itemstr; item.SubItems.Add( itempath); end; end; end; if list_file.Items.Count = 0 then Application.Terminate; finally oldFile.Free; newFile.Free; end; end; function TfrmMain.ConnectFTP: Boolean; begin Result := False; try IdFTP1.Host := ld_host.Text; IdFTP1.Port := StrToIntDef(ld_port.Text,21); IdFTP1 .Username := ld_username.Text; IdFTP1.Password := ld_psw.Text; IdFTP1.Connect; IdFTP1.Passive := cb_mode.ItemIndex = 1; FInitPath := IdFTP1.RetrieveCurrentDir; Result := IdFTP1.Connected; except Result := False; end; end; //Download file update procedure TfrmMain .DownLoadFile; var i:Integer; path:string; s1,s2:String; begin ProgressBar2.Max := list_file.Items.Count; ProgressBar2.Position := 0; FIniFile.EraseSection('error'); for i := 0 to list_file.Items.Count - 1 do begin Label4.Caption := 'Downloading'+list_file.Items[i].Caption; Application.ProcessMessages; IdFTP1.ChangeDir(FInitPath); path := list_file.Items[i].SubItems.Strings[0]; if path <>'/' then begin IdFTP1.ChangeDir(path); ForceDirectories(FExePath+path); s1 := list_file.Items[i].Caption; s2 := FExePath+path+'/'+list_file.Items[i].Caption; IdFTP1.Get(s1,s2,True); end else begin s1 := list_file.Items[i].Caption; s2 := FExePath+'/'+ list_file.Items[i].Caption; IdFTP1.Get(s1,s2,True); //Record failed items FIniFile.WriteString('error',list_file.Items[i].Caption,'Success'); end; except //Record failed items FIniFile.WriteString('error',list_file.Items[i]. Caption,'Failed'); end; end; Label4.Caption := 'All files updated! '; DeleteFile(FExePath+'update.ini'); CopyFile(PChar(FExePath+'update_new.ini'),PChar(FExePath+'update.ini'),False); end; procedure TfrmMain.LoadIni; begin ld_host.Text := FIniFile.ReadString('coninfo','host','******'); ld_username.Text := FIniFile.ReadString('coninfo','user','******'); ld_psw.Text := FIniFile.ReadString('coninfo','psw','***** *'); ld_port.Text := FIniFile.ReadString('coninfo','port','21'); cb_mode.ItemIndex := FIniFile.ReadInteger('coninfo','mode',1); FMainExe := FIniFile.ReadString('coninfo','main','Main.exe'); FParam := FIniFile.ReadString('coninfo','param ',''); end; procedure TfrmMain.SaveIni; begin FIniFile.WriteString('coninfo','host',ld_host.Text); FIniFile.WriteString('coninfo','user',ld_username.Text); FIniFile.WriteString('coninfo','psw',ld_psw.Text) ; FIniFile.WriteString('coninfo','port',ld_port.Text); FIniFile.WriteInteger('coninfo','mode',cb_mode.ItemIndex); end; end.
If you have any questions, please leave a message or go to the community of this site to communicate and discuss. Thank you for reading. I hope it can help everyone. Thank you for your support of this site!