如何在软件中实现"在线智能升级",请给出源码(100分)(100分)

  • 主题发起人 主题发起人 ably
  • 开始时间 开始时间
关注中。
实际上这个问题理论上是比较好解决的。
在网上把要升级的文件放上去后,然后用一文件来表示版本号。
要升级时把文件背下来。与当前的比较,如果是网上新的话。就把升级的文件给覆装置掉,即可。
就是不知原码该怎么写。
 
1。找一个FTP服务器
2。将要升级的文件与版本记录文件上传。
3。下载版本记录文件, 检查是否要升级。
4。如要升级的话用FTP控件下载。
5。覆盖原文件。
FTP的程序Delphi中有例子。
 
以前见过有类似的控件,忘了名字了,我再找找
 
使用TMSPack。
 
program with delphi6.0
use indy:http
the content of version.ini is:
1.0.0.0 (only one line)

procedure checkupdate;
var
ustream:tmemorystream;
verstr:string;
oldname,newname:pchar;
oldsize,newsize:dword;
begin
ustream :=tmemorystream.Create ;
try
//get new version infomation
verstr:=frmclient.HTTPC.Get('/jfgl/version.ini');
if (verstr<>'') and ((strtointdef(fetch(verstr,'.'),1)>1) or (strtointdef(fetch(verstr,'.'),0)>1) or (strtointdef(fetch(verstr,'.'),1)>0) or (strtointdef(fetch(verstr,'.'),1)>0)) then
try
//get new exe file and rename to filename.tmp
frmclient.httpc.Get('/jfgl/client.exe',ustream);
ustream.SaveToFile(ChangeFileExt(application.ExeName,'.tmp'));
//replace exe file until last boot because it is now running
//if you have better method please tell me,thank's
getmem(oldname,max_path);
fillchar(oldname[0],max_path-1,0);
getshortpathname(pchar(application.exename),oldname,oldsize);
getmem(newname,max_path);
fillchar(newname[0],max_path-1,0);
getshortpathname(pchar(ChangeFileExt(application.ExeName,'.tmp')),newname,newsize);
movefileex(newname,oldname,MOVEFILE_DELAY_UNTIL_REBOOT or MOVEFILE_REPLACE_EXISTING);
except
end;
except
//
end;
freeandnil(ustream);
end;
 
我觉得这个东东好做。

程序中得到文件的版本,与更新的文件比较,然后更新就是了。简单。
 
这个问题从原理上来讲不难,但实际操作不知从何入手,
请问hhzh426,server从何运行,server不运行,client不工作.
我本意是:在一个网站中(不一定是FTP网站),可以下载一个文件,比较版本,
然后再下载更版文件,例如:KVW3000.
我需要DELPHI5.0...
 
补充两句:
思路是:(从flashget升级的方法而知)
在升级服务器上存放一个信息文件,注明新版本的各项特性,进行升级时新下载该信息文件
与当前文件进行比较,然后决定是否从服务器上下载新版本的程序文档。
刚发上的例子仅仅是个演示。信息文件中存放的是版本信息
major.minor.release.build,在主程序中用一个变量存放当前的版本信息,也可以在程序
中实时的获取当前使用的文件的版本信息。然后进行比较。
下载完毕后要做的就是如何将当前正在运行的程序文件进行替换的问题了。可以用运行
*.bat的方法,也可以用特殊的文件更名的方法(我给出的程序段就是这种方法),该方法
将在下次启动时将文件替换掉,程序中有一段更改为短文件名的代码,因为我在论坛中获知
说用长文件名可能出现问题。
 
再说两句:
既然是在线升级就必须有服务器,通常情况下使用ftp、http协议访问服务器比较可行。
我给出的程序段使用的是delphi6.0,但是使用的协议是http协议,在delphi5.0中用也可以
顺利使用的,只要将indy的http控件换为别的http控件就可以了,如果功底深的话,直接
用winsock进行编程也可以。最主要的是探讨一种方法,不要拘泥于程序的版本和编程的
语言。
 
局域网的作过。因为给人家做系统有十几个点,客户老是要改
东西(开始用时),又不想每做一改动就跑十几个地点,操做十几次WINDOWSXX..
(不跑?不要钱了你?)
思路是:EXE,dll 等 文件本身就有版本信息,BUILD 时加入就是了,
不需要存放一个信息文件(当然是指在局域网中)。
专门作了一个程序叫UPDATEFILE.EXE ,客户用的文件叫A.EXE.
A 运行开始时,按内定的(或写在数据表中) 的路径找到 //REMOTE/A.EXE ,
比较版本信息,if <, then 关闭自己的同时运行UPDATEFILE.EXE ,
UPDATEFILE 实现 copy //remote/a.exe ->a.exe ,覆盖掉本机的a.exe ,
关闭自己的同时运行A.EXE 。当然要加些提示信息,免得客户看到画面没啥动静,
硬盘确花花叫,以为中毒了,那可要跑无数趟了.....
挺好用的,省不少劲。

为何要单独作一个UPDATEFILE.EXE ?因为我做不到 A 运行的同时又把 A 覆盖掉,
有法子吗,虾's? 希望给出的点子不要建议我 RESTART WINDOWS ,我会恨死你的:)

功底不深,不会搞ftp、http协议,对得起客户自己又能偷懒就OK了...


ps:hhzh426的方法挺好的,有功底,呵呵...


 
有很多方法取得文件信息。
1。规范的文件命名方法 (如: program-version-language-platform.ext)
2。使用信息文件保存文件版本信息
或使用数据库保存文件版本信息
3。使用服务端脚本返回文件信息 (如果可用,这个方法较好)
或客户端程序读取文件信息。

......
应该还有更多方法
 
运用 HTTP 通讯协议搭配 UPDATER.EXE 自动比对文件日期时间并自动下载文件的构件
http://vcl.vclxx.org/DELPHI/D32FREE/UPDATER.ZIP
 
ridolph,没源码
hhzh426,DELPHI5.0调试不通
注意:从网站下载,不是FTP,全部源码>>>另加300分
 
tnmhttp也可以使用吧!
 
unit Updater;
//{$A+,B-,D-,L-,M-,O+,Q-,R-,S-,X+,Y-}
(*
TChkUpdate 1.3

"Lets go get the net!"

-------- -------- -------- -------- -------- -------- -------- --------

Contents:
TChkUpdate - Component for checking wether an update of an application
is available on your homepage.

-------- -------- -------- -------- -------- -------- -------- --------
Copyrights (C) 1999 ved T Skovmand Eriksen
email: TSEriksen@cyberdude.com
ALL RIGHTS RESERVED
-------- -------- -------- -------- -------- -------- -------- --------

This source is freeware and may be used as follows:

* In development of in-house applications which will not be published.

* In development of freeware applications PROVIDED that credit is given
to me in the applications aboutbox or helpfile.

* In development of shareware and commercial applications PROVIDED that
I, Troels S Eriksen, recieve a free unlimited copy of all versions of
said application AND that credits are given to me in the applications
aboutbox or helpfile.

* In printed or electronic form (fx. in a book) or in a source-library
(fx. on CD) PROVIDED that I, Troels S Eriksen, recieve a royality-free
unlimited copy of said book or library.

* In any other way PROVIDED that I, Troels S Eriksen, give my explicit
permission to the suggested use.

By using this source you do acknowledge that the above restrictions apply to
you and your use of this component and that you will confirm by them.

-------- -------- -------- -------- -------- -------- -------- --------

Revision history:
TChkUpdate
01 - Component created.
02 - Ver. 1.1: Property for Version number check added.
03 - Internet Connection check added - doesn't seem to work, though...
04 - Ver. 1.2: AutoProxy property added thanks to Jura Kornienko.
05 - Minor bugfixes. Allows more loose syntax in ver/rev comments.
06 - Ver. 1.3: Background execute (Threaded) added.
07 - Threaded property added.

-------- -------- -------- -------- -------- -------- -------- --------

TChkUpdate Properties:
AutoProxy When TRUE uses IE's default proxy settings.
Homepage The URL to the main homepage of your company or
application. (Used by the OnFound method)
Revision Current revision. Is checked against the <!--rev #-->
comment on the webpage
Threaded When TRUE connects to the internet in a separate
thread for version/revision checking. When FALSE the
main thread is blocked while check occurs.
URL URL to an internet document containing the revision
comment to check for
Version Current version. Is checked against the <!--ver #.#-->
comment on the webpage

TChkUpdate Events
OnFound Triggered if the revision comment is greather than
the current revision. Use the Launch value to decide
wether the end-users default browser should open the
homepage.
OnNotFound Triggered if the above is not the true.
OnNoConnect Triggered if connection to the internet could not be
established or if the URL was not found.
TChkUpdate Methods:
Execute Connects to the url and checks the revision and version.
If Threaded is TRUE return value is always TRUE. If
Threaded is FALSE will only return TRUE if connection
to the server could be established and the URL found.
IsConnected Returns TRUE is an connection to the server defined
in the URL property may be established. FALSE will be
returned if no internet connection currently exists.

-------- -------- -------- -------- -------- -------- -------- --------

Requirements:
wininet.dll Windows 32bit Internet API library must be present
and working.

-------- -------- -------- -------- -------- -------- -------- --------

Thanks to:
Jura Kornienko Who had the ideas for rev. 04-06, made me sit up, add
a few lines of code and end up with a better component.

-------- -------- -------- -------- -------- -------- -------- --------

Bugs:
None reported - none fixed.

"It is not a bug, its an undisclosed feature for further extension of
this applications feasibility"

-------- -------- -------- -------- -------- -------- -------- --------

How to use:
First, create an webpage for your application. Somewhere within the
first kilobyte of this homepage, add a revision comment - like this:
"<!--rev #-->" and/or a version comment like this: "<!--ver #.##-->".
Everytime you update your app, increase the rev number (the #) or the
version number (the #.##) on this webpage.

Second, Drop a TChkUpdate component on your main form, enter the URL to
the webpage in the URL property and the current revision number in the
Revision property and the current version number in the version property.

Add some code to the OnFound / OnNotFound properties to inform the
end-user wether there is an update available or not. If you set the
variable Launch to true, the users browser will automatically show
the URL from the Homepage property. (Would be nice to ask the users
permission before launching anything).

If the homepage property points to an .zip or .exe-file - user should
automatically be asked to download/open the file directly (at least in
IE3 and later).

Then add some way that the user may call the Execute method (fx. a
button). Check the return value and inform the user if an internet
connection could not be made.

*)


interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;


{ Import function from Wininet.dll - this has been left out of Inprises
(Borlands) official import unit. Shame, Shame, Shame...
}
function InternetAttemptConnect(dwReserved:DWord):dword; stdcall;

{ Then the component itself
}
type
TUpdateEvent = procedure (Sender:TObject;var Launch:boolean) of object;

type
TChkUpdate = class(TComponent)
private
{ Private declarations }
fAutoProxy : boolean;
fURL : string;
fHomepage : string;
fRevision : integer;
fVersion : string;
fThreaded : boolean;
fOnFound : TUpdateEvent;
fOnNotFound : TNotifyEvent;
fOnNoConnect : TNotifyEvent;
// procedure SetVersion(Value:string);
// function GetVersion:string;
protected
procedure ChkResult(WebVer:double;WebRev:integer);
function ThreadExecute:boolean;
function BlockingExecute:boolean;
public
{ Methods }
constructor Create(AnOwner:TComponent); override;
function IsConnected:boolean;
function Execute:boolean;
published
{ Properties }
property AutoProxy : boolean read fAutoProxy write fAutoProxy;
property Homepage : string read fHomepage write fHomepage;
property Revision : integer read fRevision write fRevision;
property Threaded : boolean read fThreaded write fThreaded;
property URL : string read fURL write fURL;
property Version : string read fVersion write fVersion;
{ Events }
property OnFound : TUpdateEvent read fOnFound write fOnFound;
property OnNotFound : TNotifyEvent read fOnNotFound write fOnNotFound;
property OnNoConnect: TNotifyEvent read fOnNoConnect write fOnNoConnect;
end;

{ ------- -------- -------- -------- -------- -------- -------- ------- }

TChkResult = procedure(WebVer:double;WebRev:integer) of object;

{ ------- -------- -------- -------- -------- -------- -------- ------- }

TThreadedChecker = class(TThread)
private
{ Private declarations }
anURL : string;
aFlag : DWORD;
fVer : double;
fRev : integer;
fCallBack : TChkResult;
procedure ReturnResult;
protected
procedure Execute; override;
constructor Create(flags:integer;URL:string;Callback:TChkResult);
end;

procedure Register;


implementation
uses
Wininet, ShellApi;

{ ------- -------- -------- -------- -------- -------- -------- ------- }

procedure TThreadedChecker.ReturnResult;
begin
fCallBack(fVer,fRev);
end;

procedure TThreadedChecker.Execute;
type
tbuffer = array[0..1023] of char;
pbuffer = ^TBuffer;
var
Tmp : string;
Rev : integer;
Ver : double;
Launch : boolean;
buffer : pBuffer;
b : integer;
a : dword;
ihConnect,
iDocument : HINTERNET;
LocalDecSep: char;
begin
// Forbind til internettet
ihConnect:=InternetOpen('Modzilla/2.0 (Updater/Eriksen)', aFLAG, '', '', 0);
// 舃n dokument
iDocument:=InternetOpenURL(ihConnect,
pChar(anURL), NIL, $ffffffff, INTERNET_FLAG_RELOAD or
INTERNET_FLAG_DONT_CACHE or INTERNET_FLAG_RAW_DATA, 0);
// L鎠 f鴕ste kilobyte af dokument
Rev:=-1;
Ver:=-1;
if iDocument<>NIL then try
New(buffer);
InternetReadFile(iDocument, Buffer, sizeof(TBuffer), a);
Buffer^[a]:=#0;
// Indg錼 kommentaren "rev" i f鴕ste kb ?
Rev:=0;
a:=pos('<!--rev',AnsiLowercase(string(buffer^)));
if (a=0) then a:=pos('<!-- rev',AnsiLowercase(string(buffer^)));
if a>0 then begin
// Ja - afl鎠 revisionsnummer - det skal f鴏ge efter rev teksten
if UpCase(buffer[a+6])='V' then inc(a);
b:=a+6;
while buffer in ['0'..'9',' '] do inc(b);
// Returner Sand hvis h鴍ere rev nr findes p?net
tmp:=Copy(string(Buffer^),a+7,b-a-6);
rev:=StrToIntDef(Trim(Tmp),0);
end;
// Indg錼 kommentaren "Ver" i f鴕ste kb ?
Ver:=0.0;
a:=pos('<!--ver',AnsiLowercase(string(buffer^)));
if (a=0) then a:=pos('<!-- ver',AnsiLowercase(string(buffer^)));
if a>0 then begin
// Ja - afl鎠 versionsnummer - det skal f鴏ge efter ver teksten
if UpCase(buffer[a+6])='R' then inc(a);
b:=a+6;
while buffer in ['0'..'9',' ','.',','] do inc(b);
// Returner Sand hvis h鴍ere ver nr findes p?net
LocalDecSep:=DecimalSeparator;
try
DecimalSeparator:='.';
tmp:=Copy(string(Buffer^),a+7,b-(a+6));
ver:=StrToFloat(trim(tmp));
except
ver:=0.0;
end;
DecimalSeparator:=LocalDecSep;
end;
// Er en opdatering tilg鎛gelig?
finally
internetCloseHandle(iDocument);
Dispose(buffer);
InternetCloseHandle(ihConnect);
end;
fVer:=Ver;
fRev:=Rev;
Synchronize(ReturnResult);
end;

constructor TThreadedChecker.Create(flags:integer;URL:string;Callback:TChkResult);
begin
inherited Create(FALSE);
anUrl:=URL;
aFlag:=flags;
fCallBack:=Callback;
end;

{ ------- -------- -------- -------- -------- -------- -------- ------- }

procedure Register;
begin
RegisterComponents('Samples', [TChkUpdate]);
end;

function Str2Float(value:string):double;
var
LocalDecSep : char;
begin
try
LocalDecSep:=DecimalSeparator;
try
DecimalSeparator:='.';
result:=StrToFloat(trim(value));
except
result:=0.0;
end;
finally
DecimalSeparator:=LocalDecSep;
end;
end;

{ ------- -------- -------- -------- -------- -------- -------- ------- }
{
procedure TChkUpdate.SetVersion(Value:string);
var
c : char;
begin
fVersion:= Value;
end;

function TChkUpdate.GetVersion:string;
var
c : char;
begin
c:=DecimalSeparator;
try
DecimalSeparator:='.';
result:=FormatFloat('0.00',fVersion);
finally
DecimalSeparator:=c;
end;
end;
}
{ ------- -------- -------- -------- -------- -------- -------- ------- }

function TChkUpdate.IsConnected:Boolean;
begin
result:=boolean(InternetAttemptConnect(0));
end;

procedure TChkUpdate.ChkResult;
var
launch : boolean;
LocalDecSep : char;
ver : double;
begin
ver:=Str2Float(version);
if (WebRev<0) and (WebVer<0) and (assigned(fOnNoConnect)) then
fOnNoConnect(SELF)
else begin
if ((WebRev>Revision) or (WebVer>Ver)) and (assigned(fOnFound)) then begin
Launch:=FALSE;
fOnFound(Self,Launch);
If (launch) and (trim(fHomepage)>'') then
ShellExecute(Application.Handle,'open',pChar(fHomepage),'','',
SW_SHOWNORMAL);
end else if assigned(fOnNotFound) then fOnNotFound(Self);
end;
end;

function TChkUpdate.ThreadExecute:Boolean;
var
flag : integer;
begin
Case fAutoProxy of
FALSE : Flag:=LOCAL_INTERNET_ACCESS;
TRUE : Flag:=INTERNET_OPEN_TYPE_PRECONFIG;
end;
With TThreadedChecker.Create(flag,fURL,ChkResult) do ;
result:=true;
end;

{
function TChkUpdate.BlockingExecute:Boolean;
type
tbuffer = array[0..1023] of char;
pbuffer = ^TBuffer;
var
Tmp : string;
Rev, Ver,
Launch : boolean;
buffer : pBuffer;
a : dword;
b : integer;
ihConnect,
iDocument : HINTERNET;
LocalDecSep: char;
begin
result:=false;
// Forbind til internettet
Case fAutoProxy of
FALSE : ihConnect:=InternetOpen('Modzilla/2.0 (Updater/Eriksen)',
LOCAL_INTERNET_ACCESS, '', '', 0);
TRUE : ihConnect:=InternetOpen('Modzilla/2.0 (Updater/Eriksen)',
INTERNET_OPEN_TYPE_PRECONFIG, '', '', 0);
end;
// 舃n dokument
iDocument:=InternetOpenURL(ihConnect,
pChar(fURL), NIL, $ffffffff, INTERNET_FLAG_RELOAD or
INTERNET_FLAG_DONT_CACHE or INTERNET_FLAG_RAW_DATA, 0);
// L鎠 f鴕ste kilobyte af dokument
if iDocument<>NIL then try
New(buffer);
InternetReadFile(iDocument, Buffer, sizeof(TBuffer), a);
Buffer^[a]:=#0;
// Indg錼 kommentaren "rev" i f鴕ste kb ?
Rev:=FALSE;
a:=pos('<!--rev',AnsiLowercase(string(buffer^)));
if (a=0) then a:=pos('<!-- rev',AnsiLowercase(string(buffer^)));
if a>0 then begin
// Ja - afl鎠 revisionsnummer - det skal f鴏ge efter rev teksten
if UpCase(buffer[a+6])='V' then inc(a);
b:=a+6;
while buffer in ['0'..'9',' '] do inc(b);
// Returner Sand hvis h鴍ere rev nr findes p?net
tmp:=Copy(string(Buffer^),a+7,b-a-6);
rev:=StrToIntDef(Trim(Tmp),0)>fRevision;
end;
// Indg錼 kommentaren "Ver" i f鴕ste kb ?
Ver:=FALSE;
a:=pos('<!--ver',AnsiLowercase(string(buffer^)));
if (a=0) then a:=pos('<!-- ver',AnsiLowercase(string(buffer^)));
if a>0 then begin
// Ja - afl鎠 versionsnummer - det skal f鴏ge efter ver teksten
if UpCase(buffer[a+6])='R' then inc(a);
b:=a+6;
while buffer in ['0'..'9',' ','.',','] do inc(b);
// Returner Sand hvis h鴍ere ver nr findes p?net
LocalDecSep:=DecimalSeparator;
try
DecimalSeparator:='.';
tmp:=Copy(string(Buffer^),a+7,b-(a+6));
ver:=StrToFloat(trim(tmp))>fVersion;
except
ver:=FALSE;
end;
DecimalSeparator:=LocalDecSep;
end;
// Er en opdatering tilg鎛gelig?
result:=(Rev or Ver);
// Vis h鎛delse
try
case result of
true : if assigned(fOnFound) then begin
Launch:=FALSE;
fOnFound(Self,Launch);
If (launch) and (trim(fHomepage)>'') then
ShellExecute(Application.Handle,'open',pChar(fHomepage),'','',
SW_SHOWNORMAL);
end;
false: if assigned(fOnNotFound) then
fOnNotFound(Self);
end;
finally
result:=true;
end;
finally
internetCloseHandle(iDocument);
Dispose(buffer);
InternetCloseHandle(ihConnect);
end;
if (not result) and (assigned(fOnNoConnect)) then
fOnNoConnect(SELF);
end;
}

function TChkUpdate.BlockingExecute:Boolean;
type
tbuffer = array[0..1023] of char;
pbuffer = ^TBuffer;
var
Tmp,s,s1 : string;
Rev, Ver,
Launch : boolean;
buffer : pBuffer;
a,l,p : dword;
b : integer;
ihConnect,
iDocument : HINTERNET;
LocalDecSep: char;
begin
result:=false;
// Forbind til internettet
Case fAutoProxy of
FALSE : ihConnect:=InternetOpen('Modzilla/2.0 (Updater/Eriksen)',
LOCAL_INTERNET_ACCESS, '', '', 0);
TRUE : ihConnect:=InternetOpen('Modzilla/2.0 (Updater/Eriksen)',
INTERNET_OPEN_TYPE_PRECONFIG, '', '', 0);
end;
// 舃n dokument
iDocument:=InternetOpenURL(ihConnect,
pChar(fURL), NIL, $ffffffff, INTERNET_FLAG_RELOAD or
INTERNET_FLAG_DONT_CACHE or INTERNET_FLAG_RAW_DATA, 0);
// L鎠 f鴕ste kilobyte af dokument
if iDocument<>NIL then try
New(buffer);
InternetReadFile(iDocument, Buffer, sizeof(TBuffer), l);
Buffer^[l]:=#0;
// Indg錼 kommentaren "rev" i f鴕ste kb ?
Rev:=FALSE;
s := '<!--version' ;
p:=pos(s,AnsiLowercase(string(buffer^)));
if p>0 then begin
while (buffer[p]<>'=') and (p<l) do inc(p);
inc(p);
while (buffer[p]<>'-') and (p<l) do begin
s1:=s1+buffer[p];
inc(p);
result := true;
end;
if result then version := s1;
end;
try
case result of
true : if assigned(fOnFound) then begin
Launch:=FALSE;
fOnFound(Self,Launch);
If (launch) and (trim(fHomepage)>'') then
ShellExecute(Application.Handle,'open',pChar(fHomepage),'','',
SW_SHOWNORMAL);
end;
false: if assigned(fOnNotFound) then
fOnNotFound(Self);
end;
finally
result:=true;
end;
finally
internetCloseHandle(iDocument);
Dispose(buffer);
InternetCloseHandle(ihConnect);
end;
if (not result) and (assigned(fOnNoConnect)) then
fOnNoConnect(SELF);
end;

function TChkUpdate.Execute:boolean;
begin
Case fThreaded of
TRUE : result:=ThreadExecute;
FALSE: result:=BlockingExecute;
end;
end;

{ ------- -------- -------- -------- -------- -------- -------- ------- }

constructor TChkUpdate.Create(AnOwner:TComponent);
begin
Inherited ;
URL :='http://webserver/application/revision.htm';
Homepage :='http://webserver/application/';
Revision :=1;
Version :='1.0';
AutoProxy:=FALSE;
Threaded :=FALSE;
end;

{ ------- -------- -------- -------- -------- -------- -------- ------- }

// Statisk kald til ikke-predef funktion i dll

const
winetdll = 'wininet.dll';

function InternetAttemptConnect; external winetdll name 'InternetAttemptConnect';

end.

 
给出思路有分吗?
1.服务器,FTP的实现起来容易一些.存放更新文件和板本信息
2.一个板本判断程序(这个程序不参与更新),INI文件(存放当前信息)也可用注册,
实际要用的程序.
3.主要的工作在判断程序上做,板本判断通过 shellexec(实际要用的程序)
不通过 FTP 删除旧的,下新程序 shellexec(实际要用的程序
 
1、程序采用插件式或多用动态链接设计,方便升级。并且多做软件工程,将程序外壳尽量
做成微代码,减少更改升级的机会,核心模块清晰划分,这样就有了明确的升级目的,
建立注册表信息检查启动机制,每次启动程序先检查注册表里的信息来判断程序需要启动
哪些插件或者启动程序所要做的事情的先后次序,为下面升级做准备(中国目前不缺代
码员,缺少系统分析员)
2、使用ftp,可以通过internet和直接拨号两种方式。尽量为客户使用方便。
3、使用ini或者其他形式在ftp中存放当前各个主件版本信息,以供比较。
4、软件升级时先下载版本文件,在比较,过滤出高版本即需要升级的模块,由于前面做
了很好的模块划分,所以升级都是固定项目,通过过滤给出一个选单,不用升级模块为
enable:=false;其余可选择下载(类似金山毒霸)。也可以不选择,程序自动下载高版
本模块(类似指南针证券分析软件)。将必要文件下载到临时目录中,并建立一个升级
文件列表。
5、主模块只是一个shell,不需要升级,但其他的模块可能在运行,所以直接拷贝会有共享
冲突。修改程序启动的注册表信息文件,改为启动升级模式,要求程序重新启动。
6、程序启动,检查到这次启动为升级模式,在只启动了shell的时候,参照升级文件列表
将相应文件拷入相应目录中。将注册表中的信息恢复为正常,在按照其它的选项启动相
应模块或者插件。
完成升级!!
可以参考《金山毒霸》和《指南针分析软件》的模式
多说两句:
希望我们都重视软件的分析能力,代码只占20%工作时!一个软件的成功不在于数据结构的
优化和代码的效率,更应该重视软件的设计。一个好的软件应当在需求文档做的不能在做的
时候才开始初级代码,然后在做文档,在修改代码,螺旋进行。如这个项目,有几十个点,
就用当考虑到升级维护问题,并且与客户广泛交流(与大多数直接用户之间),这样做的软
件成本会是最低的,代码效率会是最高的,软件的生命周期会是最长的。
个人见解,各位批评指正!
 
后退
顶部