我用的是installshield11.5,我先说明,installshield11.5做的安装程序本身,是可以设置成自动检测有没有新的版本的,嗯,我不懂怎么搞,我想了这样的办法,这样的办法可以用在installshield 6.x的版本里的
这个办法要求在做安装程序的时候,一定要先在注册表里写上程序的安装路径和机器类型
安装路径就是程序安装在什么路径下了,在installshield里是由变量TARGETDIR记录的,我在注册表里,用了install这样的健值记录
机器类型就是安装程序的机器是做什么用的,有的机器安装程序,是用来做服务器的,这个机器上面带有数据库,升级的时候,有时要升级数据库的,我选择在服务器上升级数据库,有的机器安装程序,是用来做客户端的,这个机器上面没有数据库,升级的时候,要跳过数据库升级部分
我测试了一个项目,在注册表里,我写了这样的一个注册项:HKEY_LOCAL_MACHINE\SOFTWARE\NNLL,在这个注册项下面,我有两个键值,一个是install,记录安装路径,一个是sc,记录机器类型
这些注册项怎么在安装程序里写进去,可以查看这篇博客:user1/9/archives/2006/2757.html
这里讲的是怎么利用这两个注册表键值做一个可以自动升级数据库和文件的升级程序
新键一个安装工程,设置要安装的文件,全都和普通的安装程序一样做法,不同的地方是Installation Interview这一步,这里有四个设置:
第一个Licerse Agreement Dialog,是设置要不要显示软件协议
第二个prompt users to enter their Company Name and User Name,是设置要不要用户在安装时输入公司名和用户名
第三个modify the installation location of your application,是设置可以不可以让用户选择安装路径
第四个selectively install only certain parts of your application,是设置可以不可以让用户选择安装程序里的哪部分内容
这四个东西,在升级的时候全都用不上,全部都设置成NO
还有一个不同呢,就是因为升级程序一般都是单个文件的好,所以在Build Installation里,要选择Single Executable,这样安装包到最后就会被打包成一个单一的文件了
最后呢,就是修改安装脚本,修改OnFirstUIBefore函数,在声明变量的部分,要添加五个变量,szPath是记录安装路径的,szServer是记录机器类型的
//NNLL添加变量
string szPath,szServer;
string szKey;
number
nType,nRootKey;
//NNLL添加结束
在Dlg_SdFeatureTree后,添加下面的脚本,读取安装路径和机器类型,设置安装路径
//提取注册表,取安装路径和是否服务器端
//置根为nRootKey
nRootKey =
HKEY_LOCAL_MACHINE;
RegDBSetDefaultRoot
(nRootKey);
//取安装路径
szKey="SOFTWARE\\NNLL";
if RegDBKeyExist(szKey)
= 1 then
//存在这个项,取这个项下的键值
nSize=-1;
nType=REGDB_STRING;
//取安装路径
szName="install";
RegDBGetKeyValueEx (szKey,
szName, nType, szPath, nSize);
//取是否服务器端
szName="sc";
RegDBGetKeyValueEx (szKey, szName, nType, szServer, nSize);
//设置安装路径
TARGETDIR=szPath;
else
//如果没有这个注册项,退出升级程序
MessageBox("升级程序在非法安装的程序上无效,请购买正版软件",SEVERE);
abort;
endif;
上面取到的szServer是机器类型,要根据这个的值,判断是不是要用升级数据库,很简单的,给Dlg_SQLServer和Dlg_ObjDialogs加上判断就行了
if szServer="S" then
//如果是服务器端的,就升级数据库
Dlg_SQLServer:
nResult =
OnSQLServerInitialize( nResult );
if( nResult = BACK ) goto
Dlg_SdFeatureTree;
Dlg_ObjDialogs:
nResult = ShowObjWizardPages( nResult );
if
(nResult = BACK) goto Dlg_SQLServer;
endif;
这段是判断sc,如果值是S,就是服务器机器,要升级数据库
下面我说一下升级数据库的问题,在Server Configuration->SQL Script里,添加连接,给连接添加一个sql脚本,把你的数据库要升级的东西,全都写在脚本里,就可以了
看我这一段,我在数据库里,有一个表,叫nnll_version,里面有一个build字段,是记录补丁号的,我每次升级,最少也要把这个补丁号写上,所以我的最简单升级脚本就是这个
use NNLLTABLE
declare @build varchar(20)
select @build=build from
nnll_version
if ( @build<'20061117' )
begin
update
nnll_version set build='20061117'
end
go
关于升级数据库脚本的设置,详细的可以看这篇博客:user1/9/archives/2006/2755.html
下面呢,我再说这个升级的安装程序搞好后,每个版本要怎么搞,嗯,我的意思是啊,我在20061117升级了程序,我做了一个升级程序的工程,如果我在20061217程序又要升级了,我们不用重新做一个升级程序的工程的,修改下面几项:
1、项目名称:菜单Project->Settings,在Application标签,修改Product的设置,我是这样设置的:NNLL的软件 v1 build 20061117 升级程序
2、要升级的文件:Organization->Setup Design,在这里,要重新设置对应的Component里面的Static File Links,把原来的文件去掉,换上新的文件就可以了
3、要升级的数据库脚本:Server Configuration->SQL Scripts,在这里,把你的脚本重新修改成新的
4、安装包的名字:Media->Releases,选中你的安装包,补丁文件都是单文件的好,所以呢,是SINGLE_EXE_IMAGE,选中这个,就可以修改他的属性了,修改Single Exe File Name,我是修改成:NNLL软件v1build20061117补丁.exe
5、项目名称:菜单Project->Settings,在Application标签,Product那一栏的id编号,点击Change按钮,这样第二次使用这个projcet,build出来的升级程序时,就不会叫你卸载
最后呢,就是重新生成安装包:菜单Build->Build SINGLE_EXE_IMAGE,等生成完了,你就可以在Media\SINGLE_EXE_IMAGE\Package目录下找到你的升级程序了
我说一下我的这个办法有什么不好的地方
1、我放成installshield11.5的新功能不用,自己想了一个办法,嗯,是因为我对着一堆的英文,看得很辛苦,对中文也辛苦
2、如果有坏蛋的用户,他们升级客户端机器,不升级服务器,那我的数据库就变成没有升级了,如果升级程序有动了数据库结构,那新的文件版本就对不上旧的数据库了,客户端运行的时候,肯定会报错,用户就肯定会找你的,说你的软件出错了
我想过这个的解决办法,就是要读取数据库的信息,如果数据库里面build字段是>=当前升级脚本的补丁号的,那就允许升级客户端机器,else呢,来一个
MessageBox("请先升级服务器",SEVERE);
abort;
嗯,我不知道怎么在installshield的脚本里读数据库里的build的值,所以我不知道这个办法怎么搞
我想过把这个数据库的版本号写在注册表里,那就要安装程序也修改了,要再加一个注册表键值,好麻烦啊,我不要搞了,谁喜欢,谁搞
3、反安装的问题,这样子搞法,连补丁都可以反安装了,还要是反安装补丁后,是把补丁里面的文件删除的,就是说呢,如果有用户反安装了补丁,那我们的软件就变成少了几个文件了,安装程序是可以设置不可以反安装的,我现在还不懂怎么搞