Delphi 實(shí)現(xiàn)軟件自動(dòng)升級(jí)的功能
Delphi 實(shí)現(xiàn)軟件自動(dòng)升級(jí)的功能
原理簡(jiǎn)單,在FTP上維護(hù)一個(gè)Update.ini文件,里面記錄著要更新文件的版本號(hào),本地也有一個(gè)Update.ini文件,每次啟動(dòng)更新程序時(shí),先從FTP上下載Update.ini文件到本地名字為Update_new.ini,然后比較這兩個(gè)文件,如果新的版本號(hào)大于舊的,或者新的文件在就ini中沒有,這些就表示要更新的文件,然后逐一下載。
本程序名字為AutoUpdate,你生成這個(gè)exe,然后和主程序一起打包,創(chuàng)建桌面快捷方式時(shí),指向AutoUpdate,而不是主程序。
在本地還有一個(gè)ini文件,比如叫ftp.ini吧,里面內(nèi)容是
[coninfo]
main=Project1.exe
param={app}sayyes.pj2 -y bde.txt
main=Project1.exe:是主程序名稱,和升級(jí)程序在同一目錄
param={app}sayyes.pj2 -y bde.txt:這是命令行參數(shù),app為當(dāng)前路徑,在程序中替換掉,傳遞給主程序(如果需要的話)
update.ini的內(nèi)容格式如下
[root]
辦事處查詢.txt=20100519
[dbcard]
sayyes.pj2=20100519
FTP用戶密碼.txt=20100519
[root]代表根目錄,后面的[dbcard]代表子目錄,依次類推
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; procedure DownLoadFile; procedure LoadIni; procedure SaveIni; public { Public declarations } end; var frmMain: TfrmMain; implementation uses Flash; {$R *.dfm} //下載進(jìn)度 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; //閃屏,可以不加 frm := TfrmFlash.Create(nil); frm.Show; Application.ProcessMessages; FExePath := ExtractFilePath(Application.ExeName); FIniFile := TIniFile.Create(FExePath+'ftp.ini'); //加載ini信息,就是主機(jī)和端口之類的信息 LoadIni; try ConnectFTP; CheckUpdateList; Self.Visible := True; Application.ProcessMessages; DownLoadFile; finally FreeAndNil(frm); IdFTP1.Quit; FParam := StringReplace(FParam,'{app}',FExePath,[rfReplaceAll]); //更新完畢后,啟動(dòng)主程序,并傳入命令行參數(shù) ShellExecute(Handle,'open',PChar(FExePath+FMainExe),PChar(FParam),nil,SW_NORMAL); Application.Terminate; end; end; //檢查更新列表 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; //先下載服務(wù)器上的update.ini文件,存到本地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 := ''; //下面開始比較兩個(gè)list,如果newFile的版本號(hào)大于oldFile的版本號(hào)或者oldFile中沒有的都表示要更新的 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 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; //下載文件更新 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 := '正在下載 '+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); //記錄失敗項(xiàng) FIniFile.WriteString('error',list_file.Items[i].Caption,'成功'); end; except //記錄失敗項(xiàng) FIniFile.WriteString('error',list_file.Items[i].Caption,'失敗'); end; end; Label4.Caption := '所有文件更新完畢!'; 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.
如有疑問請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
上一篇:Delphi 調(diào)用外部程序并阻塞到外部程序中
欄 目:Delphi
本文標(biāo)題:Delphi 實(shí)現(xiàn)軟件自動(dòng)升級(jí)的功能
本文地址:http://mengdiqiu.com.cn/a1/Delphi/8593.html
您可能感興趣的文章
- 01-10在Delphi實(shí)現(xiàn)在數(shù)據(jù)庫(kù)中存取圖像的圖文演示無(wú)錯(cuò)
- 01-10delphi建立、讀取、存貯INI文件的方法《三》
- 01-10Delphi Command模式
- 01-10delphi 正弦曲線圖
- 01-10delphi建立、讀取、存貯INI文件的方法《二》
- 01-10插件管理框架 for Delphi(二)
- 01-10插件管理框架 for Delphi(一)
- 01-10Delphi中判斷文件是否為文本文件的函數(shù)
- 01-10delphi中一個(gè)值得大家來(lái)考慮的DLL問題
- 01-10初探Delphi中的插件編程


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10在Delphi實(shí)現(xiàn)在數(shù)據(jù)庫(kù)中存取圖像的圖
- 01-10delphi建立、讀取、存貯INI文件的方法
- 01-10delphi 正弦曲線圖
- 01-10Delphi Command模式
- 01-10delphi建立、讀取、存貯INI文件的方法
- 01-10插件管理框架 for Delphi(二)
- 01-10插件管理框架 for Delphi(一)
- 01-10Delphi中判斷文件是否為文本文件的函
- 01-10delphi中一個(gè)值得大家來(lái)考慮的DLL問題
- 01-10初探Delphi中的插件編程
隨機(jī)閱讀
- 01-10delphi制作wav文件的方法
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 04-02jquery與jsp,用jquery
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什