用PB实现客户端程序的自动升级

C/S结构的运行模式虽然没有B/S结构更加容易扩展和简便,但由于其稳定性好、安全性高、运行速度快等特点,现在仍然被广泛应用于各种大型应用系统中,有些则和B/S形成混合的运行模式。
  B/S优越于C/S的一个很大特点就是,客户端不需要安装客户端软件,通过浏览器就可以实现各种应用,并且服务器上的内容的变化可以快速反映到客户端。如果让客户端软件也实现自动升级,可以弥补C/S模式在这方面的缺陷。本文就给出了一种可自动升级客户端软件的设计思路,并给出了使用PB的实现方法。
1 实现思路
  整个软件结构包括:升级数据库服务器、升级代理程序、客户端应用程序、升级服务管理程序等。升级数据库器保存各个版本软件的版本、文件名、文件内容等信息;升级代理程序负责读取升级数据库服务器中的最新版本信息和文件信息,完成最新版本下载和更新,并启动客户端应用程序;客户端应用程序为客户端具体应用的程序软件,即为需要实现更新的软件;最新版本上载程序是升级信息管理程序,用于上传最新的版本信息和相应的文件内容。整体结构如图1所示。
 
图1 自动升级的软件实现方案
  客户端应用程序运行之前,先启动一个升级代理程序,该代理从升级数据库服务器中读取升级信息,如果存在最新版本,提示用户并决定是否下载最新版本,然后并启动客户端应用程序。
  升级信息使用如下数据表(soft_fileinfo)进行维护和管理,文件版本号保存文件的版本信息,文件名和文件内容保存文件的名称和文件的二进制内容。创建改变的SQL语句如下(ASA7数据库):
CREATE TABLE dba.soft_fileinfo(
version char(14) NOT NULL, //文件版本号
filename char(30) NOT NULL, //文件名
filedata long binary, //文件内容
PRIMARY KEY (version, filename)); //以文件版本号和文件名为主键
  下面给出PB中的程序实现方法,假设客户端应用程序执行文件名为"sale.exe",升级数据库服务器采用ASA7。

2 客户端升级代理程序实现
  在PB中创建一个应用,在应用的实例变量中声明:
string old_version

declare get_new_filename cursor for
select filename
from dba.soft_fileinfo
where version > :old_version;

在Open事件中编写如下代码:
string ls_newversion
//连接升级服务器,这里我们用ASA7数据库代替升级数据库服务器
SQLCA.DBMS = "ODBC"
SQLCA.AutoCommit = False
SQLCA.DBParm = "ConnectString='DSN=EAS Demo DB V4;UID=dba;PWD=sql', ConnectOption='SQL_DRIVER_CONNECT,SQL_DRIVER_NOPROMPT'"
connect using sqlca;
if sqlca.sqlcode = 0 then
//读取本地版本号
RegistryGet("HKEY_LOCAL_MACHINE/Software/MySoftware/sale", "Version", RegString!, old_version)
//读取升级服务器上的最新版本号
select max(version) into :ls_newversion
from dba.soft_fileinfo;
//如果升级服务器上的最新版本号大于本地版本号,提示下载最新程序
if old_version < ls_newversion then
if MessageBox("注意","存在最新版本程序,是否立即升级?",Question!,YesNo!) = 1 then
//下载最新程序
string ls_filename
blob lb_filedata
blob lb_tempdata
long max_len = 32765
long ll_len
//通过游标,得到所有需要更新的文件名,然后分别处理
open get_new_filename;
fetch get_new_filename into :ls_filename;
do while (sqlca.sqlcode = 0)
//得到最新版本的相应文件内容
selectblob filedata into :lb_filedata
from dba.soft_fileinfo
where filename = :ls_filename
order by version desc;
long ll_file,loops,i
//删除旧版本文件
FileDelete(ls_filename)
//创建新的文件
ll_file = FileOpen(ls_filename,StreamMode!,Write!,LockReadWrite!, Append!)
ll_len = len(lb_filedata)
//由于PB中的FileWrtie一次只能写入32765大小的文件,所以必须分多次读写
IF ll_len > max_len THEN
IF Mod(ll_len, max_len) = 0 THEN
loops = ll_len/max_len
ELSE
loops = (ll_len/max_len) + 1
END IF
ELSE
loops = 1
END IF
FOR i = 1 to loops
lb_tempdata = BlobMid(lb_filedata,(i - 1)*max_len + 1,max_len)
FileWrite(ll_file,lb_tempdata)
NEXT
FileClose(ll_file)
//读取下一个文件内容
fetch get_new_filename into :ls_filename;
loop
close get_new_filename;
end if
end if
else
MessageBox("错误","没有成功连接升级服务器")
end if
//运行应用程序
Run("sale.exe")

3 升级服务管理程序实现
  升级服务管理程序的实现实际就是一个维护soft_fileinfo表的应用程序,可以修改版本信息,也可以添加新的版本信息和文件内容。这一部分思路比较简单,这里不再给出所有具体的程序代码,仅给出PB将新版本文件写入数据库的方法。
integer li_FileNum, loops, i
long flen, bytes_read, new_pos
blob b, tot_b
//得到当前选择的文件的内容大小,sle_filename包含文件所在路径及文件名
flen = FileLength(sle_filename.Text)
//打开文件
li_FileNum = FileOpen(sle_filename.Text,StreamMode!, Read!, LockRead!)
//由于FileRead函数一次只能读出32765大小的数据,所以先计算读取次数
IF flen > 32765 THEN
IF Mod(flen, 32765) = 0 THEN
loops = flen/32765
ELSE
loops = (flen/32765) + 1
END IF
ELSE
loops = 1
END IF
new_pos = 1
//分多次读出文件中的所有数据,放在tot_b变量中
FOR i = 1 to loops
bytes_read = FileRead(li_FileNum, b)
tot_b = tot_b + b
NEXT
//关闭文件
FileClose(li_FileNum)
修改当前版本的文件内容
updateblob dba.soft_fileinfo
set filedata = :tot_b
where version = current_version;
//如果保存成功,递交数据库
IF sqlca.SQLNRows > 0 THEN
COMMIT;
else
rollback;
messagebox("错误","文件内容保存失败!")
END IF

 

你可能感兴趣的:(PowerBuilder,(PB))