最近用了下installshield 2010,感触良多,说实话,这款软件一度带给我惊喜,但更多的却是遗憾。作为普通安装程序制作软件,installshield绰绰有余了,但要想全程控制整个安装过程,还是有不少力不从心的地方,或者是自己对这款软件的了解还不够深吧。
下面是自己在使用中用到的一些东西,做个记号吧,或许哪天还需要翻一下。
一.安装前检查系统是否已安装某软件:
if(RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE)=0)then
if(RegDBKeyExist("SOFTWARE//Productname//featurename")=1)then
MessageBox("warning。。。",SEVERE);
Do (EXIT);
endif;
endif;
代码解释:通常情况下可以通过检查系统注册表判断是否已安装某软件,上面的代码就是一个简单的例子,通过判断HKEY_LOCAL_MACHINE下是否存在SOFTWARE//Productname//featurename来判断是否已安装某软件,
二.判断是否选择安装某feature:
一半来讲,安装过程中可以选择需要安装的组件,在安装中,往往需要根据用户选择的安装组件来进行不同的操作,因此这一步是很有用的:
if(FeatureIsItemSelected (MEDIA,FeatureName)=1)then
....
endif;
三.服务操作:
ServiceStartService
具体就不说了,帮助文档里说得很清楚。
四.让某程序设置为开机自动启动:
if(RegDBSetDefaultRoot(HKEY_LOCAL_MACHINE)=0)then
RegDBCreateKeyEx( "SOFTWARE//Microsoft//Windows//CurrentVersion//Run", "SystemTray");
RegDBSetKeyValueEx ( "SOFTWARE//Microsoft//Windows//CurrentVersion//Run", "SystemTray", REGDB_STRING, TARGETDIR^"Document//123.exe", -1 );
endif;
代码很肩带,不解释。
五.修改配置文件
在安装结束时我们可能需要对某个配置文件根据安装环境做出修改,可以考虑下面代码:
iWrite= WriteProfString(szBatPath^"cfg//config.ini", "path_list","path_count","1" );
if(iWrite<0)then
MessageBox("waring",INFORMATION);
endif;
六.获取系统日期并根据日期创建文件夹:
GetSystemInfo (DATE ,nvResult,svResult);
record=TARGETDIR^"fileName" + svResult;
// WriteProfString ( TARGETDIR^"//cfg//config.ini", "path_list","path", TARGETDIR^"//Recording"^svResult );
if(WriteProfString(szBatPath^"cfg//config.ini", "path_list", "path0", record)<0)then
MessageBox("warning information",INFORMATION);
endif;
if(CreateDir(record)<0)then
MessageBox("warning information",INFORMATION);
endif;
代码解释: GetSystemInfo()函数顾名思义用于获取系统信息,当然包括时间日期, CreateDir()函数用于创建文件夹。
七.调用程序或命令:
LaunchAppAndWait跟LaunchApp可以调用可执行程序以及系统命令,在安装中这两个函数的灵活使用可以省不少事。
八.控制自定义对话框中button的状态。
我们知道在内部对话框中可以使用Enable以及Disable函数让button改变状态,但是在外部dialog中却无效。下面几行代码就是用于custom dialog的:
case DLG_INIT: ;
hwndDlg = CmdGetHwndDlg( szDialogName );
case RES_PBUT_YES:
hwndItemYes = GetDlgItem( hwndDlg, 0 );
hwndItemNo = GetDlgItem( hwndDlg, 1 );
hwndItemCance = GetDlgItem( hwndDlg, 2 );
EnableWindow( hwndItemYes, FALSE);
EnableWindow( hwndItemNo, FALSE);
EnableWindow( hwndItemCance, FALSE);
九.自定义对话框
自定义对话框时installshield的一大亮点,说实话如果不用这个的话就没必要用installshield了,要使用自定义对话框首先需要创建一个对话框,具体方法就不多说了,类似于MFC。
创建好对话框后就可以通过下面代码将对话框加入程序:
#define RES_DIALOG_ID 13009//定义对话框ID
#define RES_PBUT_YES 0 //定义按钮ID
#define RES_PBUT_NO 1
#define RES_PBUT_CANCE 2
szDialogName = "exampleDialog";
hInstance = 0;
szDLLName = "";
szDialog = "";
hwndParent = 0;
nResult = DefineDialog (szDialogName, hInstance, szDLLName,
RES_DIALOG_ID, szDialog, hwndParent,
HWND_INSTALL, DLG_MSG_STANDARD|DLG_CENTERED);//初始化界面
if (nResult < 0) then
MessageBox ("Import Error dialog box", SEVERE);
bDone = TRUE;
abort;
endif;
installshield的灵活性毋庸置疑,正因为如此,熟悉脚本语言只是第一步,上面列出的也只是很小一部分,要真正做出让人满意的安装程序不难却也并不简单,这里就不一一说明了,让人遗憾的是目前当我使用installshield中reqreuistes功能添加.NET framework 3.5时会出现安装3.5时无进度条的情况,很容易给用户造成程序假死的错觉,目前始终未能找到完美的解决方案,不知道是不是因为安装包太大的原因,尝试过通过LaunchAppAndWait调用3.5安装程序,但界面效果始终不够理想,或者installshield2011会解决这个问题。
bDone = FALSE;
repeat
nCmdValue = WaitOnDialog(szDialogName);//此时才会调用界面
switch (nCmdValue)
case DLG_CLOSE:
Do (EXIT);
case DLG_ERR:
MessageBox ("Operation Error", SEVERE);
abort;
case DLG_INIT: ;
hwndDlg = CmdGetHwndDlg( szDialogName );
case RES_PBUT_YES:
......
..........
case RES_PBUT_NO:
...
......
case RES_PBUT_CANCE:
Do (EXIT);
endswitch;
until bDone;
一直有个问题让我很困惑,就是有一次我将某button ID定义成2,但结果跟踪时却发现返回给我的老是101,结果导致鼠标点击按钮没任何反应,最后不得已将ID改为101了。