【问题标题】:Creating an installer that will perform an update if an older version is already installed如果已安装旧版本,则创建将执行更新的安装程序
【发布时间】:2013-03-16 08:13:09
【问题描述】:

我正在尝试为我的软件(这是一个 C# 软件)配置 Inno 设置。 我计划发布我的软件的多个版本,如果我的应用程序的旧版本已经安装在计算机上,我想更改 Inno 设置安装程序界面。 在这种情况下,用户应该无法更改安装目录。

有四种情况:

第一种情况:这是我的产品第一次安装,Inno设置应该可以正常进行。

第二种情况:产品已安装且安装程序包含较新版本。用户无法选择目标文件夹。他可以运行更新。

第三种情况:如果安装程序包含比已安装版本旧的版本,更新将被禁用并应显示一条消息。

第四种情况:安装程序版本与安装版本相同。如果需要,用户可以修复他的实际版本。

是否可以使用 InnoSetup 做到这一点?

【问题讨论】:

    标签: inno-setup updates


    【解决方案1】:

    如果您的 AppID 在应用程序的整个生命周期内保持不变,Inno Setup 已经自动处理案例 1、2 和 4。
    您还可以使用以下[Setup] 指令隐藏目录和组页面:

    DisableDirPage=auto
    DisableGroupPage=auto
    

    查看ISXKB article了解更多详情。

    对于案例 3,假设您的文件版本控制正确,Inno 不会降级任何东西,但它实际上不会警告用户。为此,您需要添加代码来检查这一点,很可能在 InitializeSetup() 事件函数中。

    【讨论】:

    • 实际上,如果您使用脚本向导创建脚本,那么应用程序文件的默认设置是添加ignoreversion 标志,在这种情况下,降级实际上会降级所有文件。添加警告消息以确认用户确实想要这样做仍然可能是一个好主意,但否则它应该可以正常工作 - 假设您的应用程序本身可以应对降级(例如数据兼容性问题)。如果没有,那么您应该添加错误而不是警告。
    • @Miral 我没有注意到这一点。感谢您的提醒。
    • 签入InitializeSetup 的示例逻辑会很棒...我假设已经为此在 inno 中加入了一些定义...
    • @Assimilater 没有内置方法,但是您可以在安装时将版本写入注册表,然后再次读取并进行比较。我手头没有任何代码。
    • 如果我们不得不求助于这样的黑客,我想真的没什么可说的了。我一个人就能搞定这么多
    【解决方案2】:

    如果您想为用户提供一些反馈,您可以尝试类似的方法。 首先,您的更新应该与您的主应用程序具有相同的AppId 名称。 然后你可以设置一些检查,这将显示消息以通知用户有关状态。

    #define MyAppVersion "1.2.2.7570"
    #define MyAppName "MyApp Update"
    
    [Setup]
    AppId=MyApp
    AppName={#MyAppName}
    AppVersion={#MyAppVersion}
    DefaultDirName={reg:HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MyApp_is1,InstallLocation}
    DisableDirPage=True
    
    [CustomMessages]
    MyAppOld=The Setup detected application version 
    MyAppRequired=The installation of {#MyAppName} requires MyApp to be installed.%nInstall MyApp before installing this update.%n%n
    MyAppTerminated=The setup of update will be terminated.
    
    [Code]
    var
    InstallLocation: String;
    
    function GetInstallString(): String;
    var
    InstPath: String;
    InstallString: String;
    begin
    InstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\MyApp_is1');
    InstallString := '';
    if not RegQueryStringValue(HKLM, InstPath, 'InstallLocation', InstallString) then
    RegQueryStringValue(HKCU, InstPath, 'InstallLocation', InstallString);
    Result := InstallString;
    InstallLocation := InstallString;
    end;
    
    function InitializeSetup: Boolean;
    var
    V: Integer;
    sUnInstallString: String;
    Version: String;
    begin
        if RegValueExists(HKEY_LOCAL_MACHINE,'Software\Microsoft\Windows\CurrentVersion\Uninstall\MyApp_is1', 'UninstallString') then begin
          RegQueryStringValue(HKEY_LOCAL_MACHINE,'Software\Microsoft\Windows\CurrentVersion\Uninstall\MyApp_is1', 'DisplayVersion', Version);
          if Version =< ExpandConstant('{#MyAppVersion}') then begin 
              Result := True;
              GetInstallString();
           end
           else begin
    MsgBox(ExpandConstant('{cm:MyAppOld}'+Version+'.'+#13#10#13#10+'{cm:MyAppRequired}'+'{cm:MyAppTerminated}'), mbInformation, MB_OK);
             Result := False;
      end;
    end
    else begin
      MsgBox(ExpandConstant('{cm:MyAppRequired}'+'{cm:MyAppTerminated}'), mbInformation, MB_OK);
      Result := False;
    end;
    end;
    

    【讨论】:

    • 1.检查是否安装了应用程序; 2.检查应用版本; 3.比较App版本和更新版本; 3a。如果更新更新然后安装; 3b。如果更新较旧,则不要安装; 3c。如果应用不存在则不安装
    • Inno 已经自动记住了安装目录,从而使您的 DefaultDirName 代码变得多余。您也没有为第一次安装指定默认值。
    • 它们不需要分开,Inno 会自动完成。如果他们需要包含更少的文件,那么只需保持相同的 AppID 和 [Setup] 指令即可。
    • 另外,您可以使用WizardForm.PrevAppDir 检索以前的{app} 文件夹,顺便说一句,这也是判断该应用程序之前是否已安装的好方法。不过话虽如此,我不确定从InitializeSetup 执行此操作是否有效;这可能为时过早。
    猜你喜欢
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 2017-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多