通过Windows Installer安装应用程序的问题

6
我有一个Windows安装程序用于我的应用程序。应用程序包中还包含Installer类,在其中执行了一些操作,其他操作在自定义操作中执行。
在安装期间,自定义操作从Installer安装另一个应用程序。我想知道如果已经存在相同版本的此应用程序,则不想安装或提供消息框询问是否重新安装(Y/N)。
如果我的应用程序已经安装,并且我再次点击相同的安装程序,我会得到“修复”和“删除”选项。但是,如果安装程序是新构建的,则会出现一个对话框,指出“已经安装了另一个版本……请使用添加/删除程序删除”。因此,我无法更新现有版本而不卸载它。如何更新现有版本?
非常感谢您对这两个问题的任何帮助或指导。我在网上搜索过这些问题,但找不到合适的答案。如果您能帮助我,那将真的很棒。
代码 product.xml
<?xml version="1.0" encoding="utf-8" ?>
<Product xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper"
 ProductCode="My.Bootstrapper.ABC">

 <!-- Create Package, Product Manifest http://msdn.microsoft.com/en-us/library/ee335702.aspx
  Schema Reference : http://msdn.microsoft.com/en-us/library/ms229223.aspx
   -->

 <PackageFiles>
     <PackageFile Name="XYZ.exe"/>
 </PackageFiles>

 <InstallChecks>
     <!-- If its installed, it will be in Uninstall. DisplayName will be XYZ2.1_rc22  
     Can still get values of DisplayVersion (2.1_rc22) & UninstallString from this key
     -->
    <RegistryCheck
       Property="IS_XYZ_INSTALLED"
       Key="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\XYZ"
       Value="DisplayName"/>
  </InstallChecks>

  <Commands>
     <Command PackageFile="XYZ.exe" Arguments="/Install">
     <InstallConditions>
         <BypassIf Property="IS_XYZ_INSTALLED" 
           Compare="ValueEqualTo" Value="XYZ2.1_rc22"/>    // tHIS IS THE DISPLAYNAME, THAT I SEE IN REGISTY
        <FailIf Property="AdminUser"
           Compare="ValueNotEqualTo" Value="True"
           String="NotAnAdmin"/>
     </InstallConditions>

     <ExitCodes>
       <ExitCode Value="0" Result="Success"/>
       <ExitCode Value="1641" Result="SuccessReboot"/>
       <ExitCode Value="3010" Result="SuccessReboot"/>
       <DefaultExitCode Result="Fail" String="GeneralFailure"/>
     </ExitCodes>
   </Command>
 </Commands>

</Product>

package.xml

<?xml version="1.0" encoding="utf-8" ?>
<Package  xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper"
    Name="DisplayName" Culture="Culture">

 <!--Check for XYZversion 2.1_rc22 -->
 <Strings>
    <String Name="DisplayName">Install My XYZ</String>
    <String Name="Culture">en</String>
   <String Name="NotAnAdmin">Administrator permissions are required to install XYZ.Contact your 
              administrator.</String>
   <String Name="GeneralFailure">A general error has occurred while installing this   
          package.</String>
  </Strings>
</Package>
更新: 如果在计算机上未安装XYZ,则我希望安装它。使用上述代码时,它不会作为先决条件安装。在先决条件中,我选择我的应用程序(以及Windows Installer 3.1和.NET 3.5),并选择“从与我的应用程序相同的位置下载先决条件”。在设置项目构建时,我在Rel文件夹中获得3个文件夹(用于winIns、Net和要安装为先决条件的应用程序XYZ)。目前,XYZ未安装在我的计算机上,因此找不到密钥。当我安装安装程序时,它安装了应用程序,但未安装先决条件即XYZ.exe应用程序。我错在哪里了吗?
谢谢。

在自定义操作中如何安装其他应用程序,它是另一个MSI吗? - Jodrell
@Jodrell,另一个应用程序是Windows安装程序文件。在自定义操作中,我将该文件添加到“安装”下。因此,在安装过程中执行它,exe文件安装其他应用程序。 - Tvd
2个回答

3
安装程序在安装期间通过自定义操作安装另一个应用程序。我想知道,如果该应用程序已经存在于相同的版本中,我不想安装它或者提供一个消息框询问是否重新安装Y / N。
您应该使用先决条件而不是自定义操作。如果您正在使用Visual Studio安装项目,则可以参考以下链接:添加自定义先决条件到Visual Studio安装项目 如果您使用其他安装工具,请了解其是否支持先决条件。
如果我的应用程序已经安装,并且我再次单击相同的安装程序,我会得到“修复”和“删除”选项。但是如果重新构建安装程序,我会收到一个对话框,指出“已安装另一个版本...请使用添加/删除程序卸载”。因此,我无法更新现有版本而不进行卸载。如何更新现有版本?
这是因为您修改了软件包,但没有增加ProductVersion并修改ProductCode。如果要进行自动升级,您需要对它们进行修改。
但是,如果您只是在测试并且不想增加ProductVersion,则需要在安装新软件包之前手动卸载旧软件包。这就是Windows Installer升级的工作方式。

@Cosmin,我不知道如何在我的应用程序中使用/配置引导清单。我正在使用Windows Installer。我的应用程序名称是"ABS.exe",我要安装的另一个应用程序是由我自己定制的"XYZ.exe"。系统可能有其原始完整版本。我构建的应用程序的exe文件名与原始完整版本的exe文件名相同。我通过识别安装路径中的文件和文件夹名称来识别我的构建版本。由于这个复杂性,我无法理解如何使用自定义先决条件。你能帮帮我吗?我觉得我在这一切中迷失了。 - Tvd
@Cosmin,REG“已安装另一个版本...”。有没有办法处理这个问题。我的意思是,我能否提供自定义消息而不是系统消息。如果可以处理,那么如何处理这部分? - Tvd
1
是的,前提条件只有在未找到时才会安装。您可以将其他安装程序作为主包的前提条件添加进去。 - rmrrm
@Cosmin 谢谢。但它仍然无法安装 - 目前未安装 XYZ,因此找不到密钥。我尝试使用“ValueEqualTo”和“ValueNotEqualTo”,但在任何情况下都无法安装。我在product.xml中进行更改,并将其复制到MicrosoftSDKs的引导程序包文件夹中。重新构建我的设置项目。我看到strapper文件夹,在其中exe文件可用于在我的Release目录中安装(因为已从应用程序文件夹中选择下载)。我想到这里的事情都很好。也没有收到“未响应”的错误。我猜条件仍然是错误的。还缺少什么?如何定义公共属性? - Tvd
代码已按照您的指示更新。 - Tvd
显示剩余7条评论

0
  1. 您可以使用GetFileVersionInfoVerQueryValue WinAPI函数(必须有.Net对应函数)来检查可执行文件的版本。

  2. 每次生成MSI包时,您都可以更改ProductCode。升级必须包括当前版本,即您需要允许在软件包的相同版本之间进行升级,而不更改ProductVersion

    然而,我会建议遵循Cosmin's recommendation


更新:回复评论。

<Upgrade Id="Your-Upgrade-GUID">
  <UpgradeVersion Minimum="$(var.ProductVersion)"
                  IncludeMinimum="no"
                  OnlyDetect="yes"
                  Language="1033"
                  Property="NEWPRODUCTFOUND" />
  <!-- NEWPRODUCTFOUND property is set if a newer product version
       is installed. It is used to prevent downgrades. -->

  <UpgradeVersion Minimum="1.0.0"
                  IncludeMinimum="yes"
                  Maximum="$(var.ProductVersion)"
                  IncludeMaximum="yes"
                  Language="1033"
                  Property="UPGRADEFOUND" />
  <!-- UPGRADEFOUND property is set if older product version is installed
       or the same as the value of ProductVersion variable -->
</Upgrade>

我们使用上述代码来执行应用程序版本之间的升级,即使是同一版本也可以。 ProductVersion 是一个 WiX 预处理器变量,它包含产品的当前版本。 PackageCode 在每次构建时都会自动生成,在 .wsx 文件中使用 * 作为其值。
使其工作的关键是第二个 UpgradeVersion 元素中的 IncludeMaximum="yes" 属性以及每个生成的软件包都具有唯一的 PackageCode

@Alexey,我该如何处理我的应用程序升级?我需要更改产品代码或版本以进行升级吗?如果是升级,那么安装路径应该自动出现而不允许更改。如何在安装程序中实现这一点?我还有安装程序类。 - Tvd
@alexey,谢谢。但是我使用SEtu和VS 2008使用Windows Installer进行安装。如何使用设置和部署项目实现相同的功能。由于您推荐了Cosmins的建议,您能否请查看一下代码以及我在Cosmin答案下添加的评论。或者如何使用设置和部署Windows Installer MSI来处理以上问题。真的非常感激。 - Tvd
@Tvd 很遗憾,我不知道如何使用安装和部署项目来完成它。引导程序对我来说看起来很好。也许它在卸载时将注册表项弄错了。或者您的先决条件没有写入任何注册表条目,是吗? - Alexey Ivanov
@Alexey,我该如何在自定义操作中检查可执行文件和安装时的版本?我想到了添加“搜索目标计算机”的想法。使用密钥,我可以在属性中获取版本。但是,我该如何将该条件添加到自定义操作中-因为我觉得该条件适用于CustomActions中的CustomActionData... - Tvd
第二个问题是,我是否可以在Installer Class中执行其他应用程序的.exe文件(通过NSIS生成的安装程序)?我应该在哪里查找该文件 - 默认情况下,它会在/ windows目录中查找,而不是从我的应用程序运行的文件夹中查找? - Tvd
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接