【问题标题】:Setting Minor or Major Upgrade within InstallScript Project在 InstallScript 项目中设置次要或主要升级
【发布时间】:2017-03-10 15:47:14
【问题描述】:

我正在使用 InstallShield 2012 Spring - Premier Edition,并且在再次运行安装脚本时,我正在尝试用新安装脚本中的任何内容替换我们软件的现有安装(如果存在)。

我在网上阅读了一些关于配置次要和主要升级设置的内容。

我有一个 InstallScript 项目,但我找不到如何进行 Minor 和 Major 升级,就像使用 Basic MSI 项目一样。我在网上读到,这可以通过 MSI 项目来完成,方法是转到 Installation Designer,然后是 Media/Upgrades,然后配置升级。此选项在 InstallScript 项目中不可用。

我可以在 InstallScript 项目中使用什么来改变这种行为?提前谢谢你。

【问题讨论】:

  • 您是否需要能够通过脚本更新次要/主要版本?如果您只需要通过 InstallShield 界面更新它,您可以通过 Project 菜单中的 Settings 进行更新。在项目设置对话框的应用程序选项卡上,您可以更新产品版本值。
  • 我想要完成的是当用户第二次运行安装脚本时,它会覆盖现有的安装(如果存在)。现在,即使我升级产品版本,它也会进入维护模式并要求先卸载,我不希望这样。由于这是一个 InstallScript 项目,我没有设置主要和次要升级的选项。
  • 如果这更有意义,我正在尝试让 InstallScript Project 覆盖以前的安装而不卸载。
  • 好的,我明白了。我经历了完全相同的问题。通过更新版本号,您已经完成了一半,但还需要在脚本中添加一些额外的代码来检测 UPDATE 与 MAINT 模式。我将在下面发布我认为可以解决您的问题(或至少让您走上正轨)的答案。希望对您有所帮助。
  • InstallScript 或 InstallScript MSI 项目类型?

标签: installshield installscript installshield-2012 major-upgrade


【解决方案1】:

我相信您需要在主脚本中添加更多事件处理程序。首先,您需要添加以下处理程序(如果它们尚不存在):

  • OnShowUI
  • OnUpdateUIBefore
  • OnUpdateUIAfter
  • OnMaintUIBefore
  • OnMaintUIAfter

重要的是要有 OnShowUI 以便运行适当的“之前”方法。以下是我的工作;您需要在其他方法中执行您需要执行的任何操作(我的方法非常特定于域,我无法直接提供这些方法)。

//---------------------------------------------------------------------------
// OnShowUI
//
// This function drives the UI sequence and file transfer of the setup.
// 
// The OnShowUI event is called directly by the framework to initiate
// the UI sequence and file transfer of the setup. By default this event
// displays UI that informs the end user that the maintenance setup has been
// completed successfully.
//---------------------------------------------------------------------------
function OnShowUI()
    BOOL bMaintenanceMode, bUpdateMode;
    string szIgnore, szTitle;
    LIST listDirs;
    number nFindAllDirsResult, nFindAllFilesResult;
    BOOL lDirEmpty;

begin
    // Enable dialog caching
    Enable( DIALOGCACHE );

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

    // Remove this to disabled update mode
    if (UPDATEMODE) then
        // checking to make sure app still exists in orig location
        if Is(PATH_EXISTS, TARGETDIR) then
            // Also check for empty TargetDir
            lDirEmpty = IsTargetDirEmpty();

            if (lDirEmpty) then
                // TARGETDIR is completely empty, so disable UPDATE mode
                bUpdateMode = FALSE;
            else
                // TARGETDIR has some contents, so continue with UPDATE
                bUpdateMode = TRUE;
            endif;
        else
            // Turn off Update mode if original folder is gone
            bUpdateMode = FALSE;
        endif;

        if (!bUpdateMode) then
            // If Update mode is set but the original target is missing
            // need to flag the installer to force full reinstall (otherwise it will 
            // think all features have already been installed (by analyzing the log))
            FeatureReinstall();
        endif;
    endif;

    // Remove this to disable maintenance mode.
    if (MAINTENANCE) then
        // checking to make sure app still exists in orig location
        if Is(PATH_EXISTS, TARGETDIR) then
            // Also check for empty TargetDir
            lDirEmpty = IsTargetDirEmpty();

            if (lDirEmpty) then
                // TARGETDIR is completely empty, so disable Maint mode
                bMaintenanceMode = FALSE;
            else
                // TARGETDIR has some contents, so continue with Maint
                bMaintenanceMode = TRUE;
            endif;
        else
            // Turn off maintenance mode if original folder is gone
            bMaintenanceMode = FALSE;
        endif;

        if (!bMaintenanceMode) then
            // If Maintenance mode is set but the original target is missing
            // need to flag the installer to force full reinstall (otherwise it will
            // think all features have already been installed (by analyzing the log))
            FeatureReinstall();
        endif;
    endif;

    // Show appropriate UI

    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;

我会说,在 OnUpdateUIBefore 中,我注释掉了以下代码:

// Check whether the update is needed.
if( nResult = VERSION_COMPARE_RESULT_SAME ) then
    // Note: This result should occur only for differential media, since the setup
    // will display OnMaintUIBefore or OnFirstUIBefore by default if the versions match
    // for full setup media.
    szMsg = SdLoadString( IDS_IFX_WARNING_UPDATE_NOT_NEEDED );
    SdSubstituteProductInfo( szMsg );
    if( MessageBox( szMsg, MB_ICONEXCLAMATION | MB_YESNO ) != IDYES ) then
        abort;
    endif;
endif;

我不记得为什么,但我怀疑它导致更新模式无法按预期工作。

我自动化了我的 Installshield 构建(通过 COM——如果有兴趣,请参阅 this answer 了解基本信息),并且该过程的一部分涉及增加次要版本,以便在针对旧版本运行新安装程序时触发更新模式。

祝你好运!

【讨论】:

  • 随着您对函数 OnShowUI() 的更改,请解释您为“if (UPDATEMODE) then”和“if (MAINTENANCE) then”修改的代码如何使安装脚本跳过卸载和覆盖现有安装?我看到您添加了检查 TARGETDIR 是否完全为空,但我不明白这将如何抑制维护模式/卸载屏幕并在现有屏幕上进行完整安装?
  • 我建议在项目设置中禁用卸载和维护模式。使用我的技术,在现有安装之上安装新版本只需在新版本中添加任何新文件或更新现有文件(如果新版本中的任何文件已更新)。换句话说,它不会从头开始完全重新安装。
  • 您为此使用什么维护经验:“标准”或“不卸载或维护”?
  • 我使用标准。但是,如果我的示例可以提供任何指示,那么让事情按照您的意愿工作可能会非常棘手(如果不是几乎不可能的话)。有时为了理智,最好不要卸载/维护(我以前不得不走那条路)。
  • 我明白了。使用“不卸载或维护”的唯一问题是我无法从添加或删除程序中卸载软件。因此,如果我理解正确,如果我像您一样更改函数 OnShowUI(),然后像您一样在 OnUpdateUIBefore 中注释掉该部分,我将能够运行我的安装脚本,它会像更新一样覆盖文件并且我仍然可以从“添加或删除程序”中卸载它?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-05
  • 2012-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多