Delphi는 소프트웨어의 자동 업그레이드 기능을 실현한다
FTP에서 Update를 유지하는 방법은 간단합니다.ini 파일, 업데이트할 파일의 버전 번호가 기록되어 있고, 로컬에도 Update가 있습니다.ini 파일, 업데이트 프로그램을 시작할 때마다 FTP에서 Update를 다운로드합니다.ini 파일의 로컬 이름은 Updatenew.ini, 그리고 이 두 파일을 비교합니다. 만약 새로운 버전 번호가 낡은 것보다 크거나, 새로운 파일이 ini에 없다면, 이것은 업데이트할 파일을 표시하고, 하나씩 다운로드합니다.
이 프로그램의 이름은 AutoUpdate입니다. 이exe를 만들고 메인 프로그램과 함께 포장해서 데스크톱 단축키를 만들 때 AutoUpdate를 가리키며 메인 프로그램이 아닌 AutoUpdate를 가리킵니다.
로컬에 ini 파일이 하나 더 있습니다. 예를 들어 ftp입니다.네, 그것도 좋아요.
[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]는 하위 디렉터리를 대표하며, 순서대로 유추한다.
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}
//
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 ,
LoadIni;
try
ConnectFTP;
CheckUpdateList;
Self.Visible := True;
Application.ProcessMessages;
DownLoadFile;
finally
FreeAndNil(frm);
IdFTP1.Quit;
FParam := StringReplace(FParam,'{app}',FExePath,[rfReplaceAll]);
// , ,
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;
// 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 := '';
// list, newFile oldFile 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);
//
FIniFile.WriteString('error',list_file.Items[i].Caption,' ');
end;
except
//
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.
궁금한 점이 있으면 댓글을 남기거나 본 사이트 지역사회에 가서 토론을 교류하고 읽어주셔서 감사합니다. 여러분께 도움이 되었으면 좋겠습니다. 본 사이트에 대한 지지에 감사드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.