您的位置:首页 > 其它

InstallShield学习笔记三:脚本(2)

2014-09-11 00:09 375 查看

5.设置安装模式

InstallScript MSI不足:

在InstallScript MSI中,在OnFirstUIBefore()执行完成后,即安装完成,这个时候需要做后续的操作,如写注册表等,这些操作要在OnFirstUIAfter()中执行。

如果此时点击取消,然后在此安装时,InstallShield会提示先卸载之前的安装,这个体验非常不好,而且InstallScript MSI还没有办法修改。

而在InstallScript 提供了一个逻辑条件,即OnShowUI(),这个可以自己修改安装模式,代码如下

function OnShowUI()
BOOL    bMaintenanceMode, bUpdateMode;
string    szIgnore, szTitle;
begin

// Enable dialog caching
Enable( DIALOGCACHE );

// Determine what events to show.
bUpdateMode    = FALSE;
bMaintenanceMode = FALSE;

// Remove this to disabled update mode.
if( UPDATEMODE ) then
bUpdateMode = TRUE;
endif;

// Remove this to disable maintenance mode.
if ( MAINTENANCE ) then
bMaintenanceMode = TRUE;
endif;

// Show appropriate UI

// TODO: Enable if you want to enable background etc.
//if ( LoadStringFromStringTable( "TITLE_MAIN", szTitle ) < ISERR_SUCCESS ) then // Load the title string.
//    szTitle = IFX_SETUP_TITLE;
//endif;
//SetTitle( szTitle, 24, WHITE );
//Enable( FULLWINDOWMODE );
//Enable( BACKGROUND );
//SetColor( BACKGROUND, RGB( 0, 128, 128 ) );

if( bUpdateMode ) then
OnUpdateUIBefore();
else
if ( bMaintenanceMode ) then
OnMaintUIBefore();
else
OnFirstUIBefore();
endif;
endif;

// Move Data
OnMoveData(); // 这里可以安装,也可以卸载组件

if( bUpdateMode ) then
OnUpdateUIAfter();
else
if ( bMaintenanceMode ) then
OnMaintUIAfter();
else
OnFirstUIAfter();
endif;
endif;

// Disable dialog caching
Disable(DIALOGCACHE);

end;


分析:

(1)可以看到可以显示有3中模式:OnUpdateUIBefore,OnMaintUIBefore,OnFirstUIBefore(对应有After),分别表示升级,维护(卸载,重安装),首次安装。

(2)OnMoveData()。这个是整个方法最重要的部分,表示数据安装或者卸载。具体使用会在后面分析。

如果我们不需要用户升级,可以将OnUpdateUIBefore()替换为OnFirstUIBefore(),OnUpdateUIAfter()替换为OnFirstUIAfter()不要删除,替换即可。修改后,即使用户安装中途取消,再次运行安装程序时,也是首次安装的状态(表现为:如果在在安装包中选择弹出语言选择框,此时这个语言选择框也会弹出。。)

6.在卸载组件中OnMoveData()的使用

在第5点中展示了使用OnMoveData,这里要说下使用过程中要注意到东西。

代码:

function OnMoveData()
number    nResult, nMediaFlags;
begin

// Don't install the DISK1COMPONENT if MAINT_OPTION_NONE was specified.
if( MAINT_OPTION = MAINT_OPTION_NONE ) then
FeatureSelectItem( MEDIA, DISK1COMPONENT, FALSE );
endif;

// Updated in 11.5, disable the cancel button during file transfer unless
// this is non-maintenance mode or repair mode.
if( MAINTENANCE && ( !REINSTALLMODE || UPDATEMODE ) ) then
Disable( CANCELBUTTON );
endif;

// Show Status
// Note: Start status window at 1 in case CreateInstallationInfo call
// is lengthy.
SetStatusWindow( 1, "" );
Enable( STATUSEX );
StatusUpdate( ON, 100 );

// Create the uninstall infomation (after displaying the progress dialog)
// Don't create uninstall information if MAINT_OPTION_NONE was specified.
if( MAINT_OPTION != MAINT_OPTION_NONE ) then
CreateInstallationInfo();
endif;

// Move Data
nResult = FeatureTransferData( MEDIA );

// Moved in 11.0, Check for failure before creating uninstall key.
// Handle move data error and abort if error occured.
if( nResult < ISERR_SUCCESS ) then
OnComponentError();
abort;
endif;

// Create uninstall key, if DISK1COMPONENT was installed.
if( IFX_DISK1INSTALLED ) then

// Store text-subs for maintenance mode later, only do this when
// disk 1 is installed. Note that any text-subs that are updated after
// this call will not be remembered during maintenance mode.
FeatureSaveTarget("");

// Write uninstall information.
MaintenanceStart();

// Customize Uninstall Information
OnCustomizeUninstInfo();

endif;

// Disable Status
Disable( STATUSEX );

end;


这里最重要的是FeatureTransferData(MEDIA)这个使用。

这个方法可以查看帮助文档,安装和卸载时是不一样的。

安装:Installs features that are selected(安装只勾选的组件Feature)

卸载:Uninstalls features that are not selected and are currently installed(卸载不勾选的组件Feature)。

问题来了:

在卸载时,即调用OnMaintUIBefore()的时候,调用的是nResult = SdFeatureTree( szTitle, szMsg, TARGETDIR, "", -1 );

这样会出现的一个现象是:在卸载的时候,勾选的组件卸载不掉,不勾选的反而卸载了(这个根本原因是组件重新安装)。

(这里只贴上OnMaintUIBefore()部分代码)

Dlg_SdFeatureTree:
if ( nType = MODIFY ) then
szTitle = "";
szMsg = SdLoadString( SD_STR_COMPONENT_MAINT_MSG );
nResult = SdFeatureTree( szTitle, szMsg, TARGETDIR, "", -1 );
if ( nResult = BACK ) goto Dlg_Start;
endif;


解决办法:反选组件。

使用FeatureSelectItem()来控制。思路是:如果只卸载Feature1,后台设置Feature1为不勾选状态,而将Featreu2设置为勾选状态;Feature2同理。

示例代码如下:

function OnMoveData()
number    nResult, nMediaFlags;
begin

…………

// Show Status
// Note: Start status window at 1 in case CreateInstallationInfo call
// is lengthy.
SetStatusWindow( 1, "" );
Enable( STATUSEX );
StatusUpdate( ON, 100 );

// Create the uninstall infomation (after displaying the progress dialog)
// Don't create uninstall information if MAINT_OPTION_NONE was specified.
if( MAINT_OPTION != MAINT_OPTION_NONE ) then
CreateInstallationInfo();
endif;

// 只有卸载时才需要这样配置,安装不需要
if(REMOVEONLY) then
  // 只卸载Feature1,将Feature1设置为不选状态,将Feature2设置为选中状态
  if(bSelectFeature1 && !bSelectFeature2) then
      FeatureSelectItem(MEDIA, "DefaultFeature\\NewFeature2", TRUE);
  FeatureSelectItem(MEDIA, "DefaultFeature\\NewFeature1", FALSE);
    // 只卸载Feature2,将Feature2设置为不选状态,将Feature1设置为选中状态
  elseif (bSelectFeature2 && !bSelectFeature1) then
      FeatureSelectItem(MEDIA, "DefaultFeature\\NewFeature1", TRUE);
  FeatureSelectItem(MEDIA, "DefaultFeature\\NewFeature2", FALSE);
  endif;
endif;

// Move Data
nResult = FeatureTransferData( MEDIA );

// Moved in 11.0, Check for failure before creating uninstall key.
// Handle move data error and abort if error occured.
if( nResult < ISERR_SUCCESS ) then
OnComponentError();
abort;
endif;

…………
end;


7.运行第三方程序

在InstallShield中,提供给调用exe,bat等文件。

LaunchAppAndWait ( szProgram, szCmdLine, nOptions );

代码示例:

function OnFirstUIAfter()
STRING szTitle, szMsg1, szMsg2, szOpt1, szOpt2;
NUMBER bvOpt1, bvOpt2;
STRING szProgram, szCmd;
begin

ShowObjWizardPages(NEXT);

szTitle = "";
szMsg1 = "";
szMsg2 = "";
szOpt1 = "";
szOpt2 = "";
bvOpt1   = FALSE;
bvOpt2   = FALSE;

szProgram = WINDIR ^ "System32\\PING.exe";
// szProgram = SUPPORTDIR ^ "test.bat"; // 如果使用自定义的bat,需要在Support Files/Billboards中存入bat文件
szCmd = "www.baidu.com";

LaunchAppAndWait (szProgram, szCmd, LAAW_OPTION_NOWAIT|LAAW_OPTION_HIDDEN);
nResult = LAAW_PARAMETERS.nLaunchResult;

//{{IS_SCRIPT_TAG(Dlg_SdDinishEx)
if ( BATCH_INSTALL ) then
SdFinishReboot ( szTitle , szMsg1 , SYS_BOOTMACHINE , szMsg2 , 0 );
else
SdFinish ( szTitle , szMsg1 , szMsg2 , szOpt1 , szOpt2 , bvOpt1 , bvOpt2 );
endif;
//}}IS_SCRIPT_TAG(Dlg_SdDinishEx)
end;


这里基本上展示了LaunchAppAndWait 的用法,重点记录的是获取返回值,这个值在bat中通过使用exit()获取返回值,如exit(-1)。

8.取消安装提示信息修改

在安装和卸载过程中,如果点击取消,此时会发现弹出的信息一模一样,默认是显示取消安装的信息。试想,在取消卸载时,提示这样的信息会让用户一头雾水。

这时候需要修改取消过程中的信息,修改OnCanceling()

原始代码:

function OnCanceling()
STRING szTitle, szMsg1, szMsg2, szOpt1, szOpt2;
NUMBER bvOpt1, bvOpt2;
begin
if (IDYES = SprintfBox(MB_YESNO|MB_ICONEXCLAMATION|MB_DEFBUTTON2, SdLoadString(SD_STR_ONCANCELING_TITLE), SdLoadString(SD_STR_ONCANCELING_CONFIRM_MSG))) then
//Close the current dialog.
EndCurrentDialog();
//Display Finish dialog.
szTitle = "";
szMsg1 = SdLoadString( SD_STR_ONCANCELING_FINISH_MSG1 );
szMsg2 = SdLoadString( SD_STR_ONCANCELING_FINISH_MSG2 );
szOpt1 = "";
szOpt2 = "";
bvOpt1   = FALSE;
bvOpt2   = FALSE;
SdFinish ( szTitle, szMsg1, szMsg2 , szOpt1, szOpt2, bvOpt1, bvOpt2 );

abort;
endif;
end;


修改后的代码:

技巧:这里使用“@”可以获取资源文件中的信息。

修改后代码:

function OnCanceling()
STRING szTitle, szMsg1, szMsg2, szOpt1, szOpt2;
NUMBER bvOpt1, bvOpt2;
STRING szBoxTitle, szBooxMsg;
begin

if(MAINTENANCE) then
szBoxTitle = SdLoadString(SD_STR_ONCANCELING_TITLE);
szBooxMsg = SdLoadString(SD_STR_ONCANCELING_CONFIRM_MSG);

// 这个与弹出框没有关系,这里呈现的地方是退出向导页面,默认是安装完成
szMsg1 = SdLoadString( SD_STR_ONCANCELING_FINISH_MSG1 );
szMsg2 = SdLoadString( SD_STR_ONCANCELING_FINISH_MSG2 );
else
szBoxTitle = @UNINSTALL_BOX_TITLE;
szBooxMsg = @UNINSTALL_BOX_MSG;

// 这个与弹出框没有关系,这里呈现的地方是退出向导页面
szMsg1 = @UNINSTALL_TITLE;
szMsg2 = @UNINSTALL_MSG;
endif;

if (IDYES = SprintfBox(MB_YESNO|MB_ICONEXCLAMATION|MB_DEFBUTTON2, szBoxTitle, szBooxMsg)) then
//Close the current dialog.
EndCurrentDialog();
//Display Finish dialog.
szTitle = "";
szOpt1 = "";
szOpt2 = "";
bvOpt1   = FALSE;
bvOpt2   = FALSE;
SdFinish ( szTitle, szMsg1, szMsg2 , szOpt1, szOpt2, bvOpt1, bvOpt2 );

abort;
endif;
end;


效果:





内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: