如何让wix更新以前安装的程序版本

时间:2021-11-26 06:57:24

I wrote an install program with wix and it worked fine to install my program. Now I need to update it, so I bumped up the version number but when I go to install the new program over the old one it complains that an older version is already installed and tells me to uninstall it first.

我用wix编写了一个安装程序,它可以很好地安装我的程序。现在我需要更新它,所以我提高了版本号,但当我去安装新程序时,它抱怨已经安装了旧版本,并告诉我先卸载它。

How do I get it to update or automatically uninstall it before reinstalling?

如何在重新安装之前更新或自动卸载它?

5 个解决方案

#1


I feel that none of the provided answers are complete or self-contained, so after digging my way through this swamp, here's the steps I think are necessary to get the (utterly self-evident) requirement of an update to work:

我觉得所提供的答案都不是完整的或独立的,所以在挖掘了这个沼泽之后,我认为这是必要的步骤以获得更新工作的(完全不言而喻的)要求:

  1. Make sure your Product Id changes every time you build. If you don't, you'll always get the "already installed" message the OP mentioned.

    确保每次构建时您的产品ID都会更改。如果不这样做,您将始终获得OP提到的“已安装”消息。

    <Product Id="*" ...>
    
  2. Change the Product Version every time the product itself changes. I suppose the best option is to bind it to an assembly version (which should be auto-incremented as well), but of course you could also just change it manually. This step is not strictly required if you use the AllowSameVersionUpgrades attribute in point 4, but I'd venture to say that keeping your product version constant is bad practise in any case.

    每次产品本身更改时更改产品版本。我想最好的选择是将它绑定到程序集版本(也应该自动增加),但当然你也可以手动更改它。如果您在第4点使用AllowSameVersionUpgrades属性,则不严格要求此步骤,但我冒昧地说保持产品版本不变是任何情况下的不良做法。

    <Product Version="!(bind.FileVersion.MyAssemblyDll)" ...>
    <File Id="MyAssemblyDll" Name="$(var.001_Application.MyAssembly.TargetFileName)" Source="$(var.001_Application.MyAssembly.TargetPath)" />
    
  3. Keep your UpgradeCode constant (e.g.):

    保持您的UpgradeCode不变(例如):

    <Product UpgradeCode="f4d7f199-28f6-45d5-ad99-7c62938274be" ...>
    
  4. Add the MajorUpgrade element (from Wix 3.5.1315.0). To circumnavigate the catch that the MajorUpgrade will disregard changes in the revision number of the product version, add the AllowSameVersionUpgrades (or if you prefer AllowDowngrades) attribute. This way, you will be able to upgrade from e.g. 1.0.0.7 to 1.0.0.8. and not just from 1.0.7.0 to 1.0.8.0. If you don't do this, you may see multiple installations in Programs and Features.

    添加MajorUpgrade元素(来自Wix 3.5.1315.0)。要绕过MajorUpgrade忽略产品版本修订号更改的捕获,请添加AllowSameVersionUpgrades(或者如果您更喜欢AllowDowngrades)属性。这样,您就可以从例如1.0.0.7至1.0.0.8。而不只是从1.0.7.0到1.0.8.0。如果不这样做,您可能会在“程序和功能”中看到多个安装。

    <MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
    

Here's my whole .wix file (relevant parts, the two fragments that lead to the assembly which is used for product binding are mostly optional and for illustration, any way you can get a hold of the assembly will work):

这是我的整个.wix文件(相关部分,导致用于产品绑定的程序集的两个片段大多是可选的,为了说明,你可以使用任何方式来保存程序集):

<?xml version="1.0" encoding="UTF-8"?>
<?define ProductVersion="!(bind.FileVersion.MyAssemblyDll)"?>
<?define UpgradeCode="f4d7f199-28f6-45d5-ad99-7c62938274be"?>

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
  <Product
    Id="*"
    Name="My Product's name"
    Language="1033"
    Version="$(var.ProductVersion)"
    Manufacturer="My company"
    UpgradeCode="$(var.UpgradeCode)"
    Codepage="1252">

    <Package
      InstallerVersion="200"
      Compressed="yes"
      InstallScope="perUser"
      Description="My product description"
      Manufacturer="My company"
      Languages="1033"
      SummaryCodepage="1252"
      InstallPrivileges="limited" />

    <MajorUpgrade AllowSameVersionUpgrades="yes" 
                  DowngradeErrorMessage="A newer version of [ProductName] is already installed. If you are sure you want to downgrade, remove the existing installation via Programs and Features." />

  </Product>

  <Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="LocalAppDataFolder">
        <Directory Id="INSTALLFOLDER" Name="My Install Dir" >
          <Component Id="INSTALLFOLDER" Guid="f6ba8a12-6493-4911-8edd-dce90e1d8e8b" >
            <RemoveFolder On="both" Id="INSTALLFOLDER"/>
            <RegistryValue Root="HKCU" Key="Software\[Manufacturer]\[ProductName]" Type="string" Value="My Registry value" />
          </Component>
        </Directory>
      </Directory>
    </Directory>
  </Fragment>

  <Fragment>
    <ComponentGroup Id="ProductComponents" >
      <Component Id="ProductComponent" Guid="1939f0f5-19f6-498b-bf95-8f1c81501294" DiskId="1" Directory="INSTALLFOLDER" >
        <File Id="MyAssemblyDll" Name="$(var.001_MyApplication.MyAssembly.TargetFileName)" Source="$(var.001_MyApplication.MyAssembly.TargetPath)" />
      </Component>
    </ComponentGroup>
  </Fragment>
</Wix>

#2


I checked through all the posts mentioned above and still spent ages trying to get this to work.

我检查了上面提到的所有帖子,但仍然花了很多时间试图让它工作。

The hint on the official HOWTO for upgrades in Step 3 helped a lot: You need a new Product/@Id to disable the message "Another version of this product is already installed".

官方HOWTO在步骤3中进行升级的提示有很多帮助:您需要一个新的产品/ @Id来禁用消息“此产品的另一个版本已经安装”。

I used this upgrade section (child of Product):

我使用了这个升级部分(Product的子级):

<Upgrade Id="$(var.UpgradeCode)">
  <UpgradeVersion Minimum="1.0.0"
                  IncludeMinimum="yes"
                  OnlyDetect="no"
                  Maximum="$(var.Version)"
                  IncludeMaximum="no"
                  Property="PREVIOUSFOUND" />
</Upgrade>

Note that OnlyDetect is set to "no". This triggers the removal of the old version, if you have the following section (child of Product):

请注意,OnlyDetect设置为“no”。如果您有以下部分(Product的子代),则会触发删除旧版本:

<InstallExecuteSequence>
  <RemoveExistingProducts After="InstallInitialize"/>
</InstallExecuteSequence>

Also note that apparently, only the first three components of the version number are used to check for upgrades...

另请注意,显然,只有版本号的前三个组件用于检查升级...

#3


you need to use the upgrade table:

你需要使用升级表:

< Upgrade Id='15E2DAFB-35C5-4043-974B-0E342C25D76A'>
    < UpgradeVersion Property='OLDVERSIONFOUND' IncludeMinimum='no' Minimum='0.0.0.0' />
< /Upgrade>

you need also add a action:

你还需要添加一个动作:

    < InstallExecuteSequence>
          < LaunchConditions After='AppSearch' />
          < RemoveExistingProducts After='InstallValidate' />
    < /InstallExecuteSequence>

here is a tutorial

这是一个教程

#4


I tried this and it worked for me.

我试过这个,它对我有用。

  1. Put your product tag like this:

    Product Id="*" Name="Something" Language="1033" Version="1.0.0.0" Manufacturer="Someone" UpgradeCode="43ab28d7-6681-4a05-a6b5-f980733aeeed"

    Product Id =“*”Name =“Something”Language =“1033”Version =“1.0.0.0”Manufacturer =“Someone”UpgradeCode =“43ab28d7-6681-4a05-a6b5-f980733aeeed”

Product Id should be set to * so that every time you build your project, it takes different id.

产品ID应设置为*,以便每次构建项目时,它都需要不同的ID。

  1. Nest a MajorUpgrade tag inside your Package element which looks like:

    MajorUpgrade AllowDowngrades="no" DowngradeErrorMessage="A newer version of [ProductName] is already installed." AllowSameVersionUpgrades="yes" /

    MajorUpgrade AllowDowngrades =“no”DowngradeErrorMessage =“已经安装了[ProductName]的更新版本。” AllowSameVersionUpgrades =“是”/

So, every time you update your version(or your version is same, not less than current version), it reinstalls your product by removing the previous files and installing the product files. It will not downgrade your product.

因此,每次更新版本(或版本相同,不低于当前版本)时,都会通过删除以前的文件并安装产品文件来重新安装产品。它不会降级您的产品。

#5


Just put this element under the Product element:

只需将此元素放在Product元素下:

<MajorUpgrade AllowDowngrades="yes" />

More info in this HowTo

更多信息在这个HowTo

#1


I feel that none of the provided answers are complete or self-contained, so after digging my way through this swamp, here's the steps I think are necessary to get the (utterly self-evident) requirement of an update to work:

我觉得所提供的答案都不是完整的或独立的,所以在挖掘了这个沼泽之后,我认为这是必要的步骤以获得更新工作的(完全不言而喻的)要求:

  1. Make sure your Product Id changes every time you build. If you don't, you'll always get the "already installed" message the OP mentioned.

    确保每次构建时您的产品ID都会更改。如果不这样做,您将始终获得OP提到的“已安装”消息。

    <Product Id="*" ...>
    
  2. Change the Product Version every time the product itself changes. I suppose the best option is to bind it to an assembly version (which should be auto-incremented as well), but of course you could also just change it manually. This step is not strictly required if you use the AllowSameVersionUpgrades attribute in point 4, but I'd venture to say that keeping your product version constant is bad practise in any case.

    每次产品本身更改时更改产品版本。我想最好的选择是将它绑定到程序集版本(也应该自动增加),但当然你也可以手动更改它。如果您在第4点使用AllowSameVersionUpgrades属性,则不严格要求此步骤,但我冒昧地说保持产品版本不变是任何情况下的不良做法。

    <Product Version="!(bind.FileVersion.MyAssemblyDll)" ...>
    <File Id="MyAssemblyDll" Name="$(var.001_Application.MyAssembly.TargetFileName)" Source="$(var.001_Application.MyAssembly.TargetPath)" />
    
  3. Keep your UpgradeCode constant (e.g.):

    保持您的UpgradeCode不变(例如):

    <Product UpgradeCode="f4d7f199-28f6-45d5-ad99-7c62938274be" ...>
    
  4. Add the MajorUpgrade element (from Wix 3.5.1315.0). To circumnavigate the catch that the MajorUpgrade will disregard changes in the revision number of the product version, add the AllowSameVersionUpgrades (or if you prefer AllowDowngrades) attribute. This way, you will be able to upgrade from e.g. 1.0.0.7 to 1.0.0.8. and not just from 1.0.7.0 to 1.0.8.0. If you don't do this, you may see multiple installations in Programs and Features.

    添加MajorUpgrade元素(来自Wix 3.5.1315.0)。要绕过MajorUpgrade忽略产品版本修订号更改的捕获,请添加AllowSameVersionUpgrades(或者如果您更喜欢AllowDowngrades)属性。这样,您就可以从例如1.0.0.7至1.0.0.8。而不只是从1.0.7.0到1.0.8.0。如果不这样做,您可能会在“程序和功能”中看到多个安装。

    <MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
    

Here's my whole .wix file (relevant parts, the two fragments that lead to the assembly which is used for product binding are mostly optional and for illustration, any way you can get a hold of the assembly will work):

这是我的整个.wix文件(相关部分,导致用于产品绑定的程序集的两个片段大多是可选的,为了说明,你可以使用任何方式来保存程序集):

<?xml version="1.0" encoding="UTF-8"?>
<?define ProductVersion="!(bind.FileVersion.MyAssemblyDll)"?>
<?define UpgradeCode="f4d7f199-28f6-45d5-ad99-7c62938274be"?>

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
  <Product
    Id="*"
    Name="My Product's name"
    Language="1033"
    Version="$(var.ProductVersion)"
    Manufacturer="My company"
    UpgradeCode="$(var.UpgradeCode)"
    Codepage="1252">

    <Package
      InstallerVersion="200"
      Compressed="yes"
      InstallScope="perUser"
      Description="My product description"
      Manufacturer="My company"
      Languages="1033"
      SummaryCodepage="1252"
      InstallPrivileges="limited" />

    <MajorUpgrade AllowSameVersionUpgrades="yes" 
                  DowngradeErrorMessage="A newer version of [ProductName] is already installed. If you are sure you want to downgrade, remove the existing installation via Programs and Features." />

  </Product>

  <Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="LocalAppDataFolder">
        <Directory Id="INSTALLFOLDER" Name="My Install Dir" >
          <Component Id="INSTALLFOLDER" Guid="f6ba8a12-6493-4911-8edd-dce90e1d8e8b" >
            <RemoveFolder On="both" Id="INSTALLFOLDER"/>
            <RegistryValue Root="HKCU" Key="Software\[Manufacturer]\[ProductName]" Type="string" Value="My Registry value" />
          </Component>
        </Directory>
      </Directory>
    </Directory>
  </Fragment>

  <Fragment>
    <ComponentGroup Id="ProductComponents" >
      <Component Id="ProductComponent" Guid="1939f0f5-19f6-498b-bf95-8f1c81501294" DiskId="1" Directory="INSTALLFOLDER" >
        <File Id="MyAssemblyDll" Name="$(var.001_MyApplication.MyAssembly.TargetFileName)" Source="$(var.001_MyApplication.MyAssembly.TargetPath)" />
      </Component>
    </ComponentGroup>
  </Fragment>
</Wix>

#2


I checked through all the posts mentioned above and still spent ages trying to get this to work.

我检查了上面提到的所有帖子,但仍然花了很多时间试图让它工作。

The hint on the official HOWTO for upgrades in Step 3 helped a lot: You need a new Product/@Id to disable the message "Another version of this product is already installed".

官方HOWTO在步骤3中进行升级的提示有很多帮助:您需要一个新的产品/ @Id来禁用消息“此产品的另一个版本已经安装”。

I used this upgrade section (child of Product):

我使用了这个升级部分(Product的子级):

<Upgrade Id="$(var.UpgradeCode)">
  <UpgradeVersion Minimum="1.0.0"
                  IncludeMinimum="yes"
                  OnlyDetect="no"
                  Maximum="$(var.Version)"
                  IncludeMaximum="no"
                  Property="PREVIOUSFOUND" />
</Upgrade>

Note that OnlyDetect is set to "no". This triggers the removal of the old version, if you have the following section (child of Product):

请注意,OnlyDetect设置为“no”。如果您有以下部分(Product的子代),则会触发删除旧版本:

<InstallExecuteSequence>
  <RemoveExistingProducts After="InstallInitialize"/>
</InstallExecuteSequence>

Also note that apparently, only the first three components of the version number are used to check for upgrades...

另请注意,显然,只有版本号的前三个组件用于检查升级...

#3


you need to use the upgrade table:

你需要使用升级表:

< Upgrade Id='15E2DAFB-35C5-4043-974B-0E342C25D76A'>
    < UpgradeVersion Property='OLDVERSIONFOUND' IncludeMinimum='no' Minimum='0.0.0.0' />
< /Upgrade>

you need also add a action:

你还需要添加一个动作:

    < InstallExecuteSequence>
          < LaunchConditions After='AppSearch' />
          < RemoveExistingProducts After='InstallValidate' />
    < /InstallExecuteSequence>

here is a tutorial

这是一个教程

#4


I tried this and it worked for me.

我试过这个,它对我有用。

  1. Put your product tag like this:

    Product Id="*" Name="Something" Language="1033" Version="1.0.0.0" Manufacturer="Someone" UpgradeCode="43ab28d7-6681-4a05-a6b5-f980733aeeed"

    Product Id =“*”Name =“Something”Language =“1033”Version =“1.0.0.0”Manufacturer =“Someone”UpgradeCode =“43ab28d7-6681-4a05-a6b5-f980733aeeed”

Product Id should be set to * so that every time you build your project, it takes different id.

产品ID应设置为*,以便每次构建项目时,它都需要不同的ID。

  1. Nest a MajorUpgrade tag inside your Package element which looks like:

    MajorUpgrade AllowDowngrades="no" DowngradeErrorMessage="A newer version of [ProductName] is already installed." AllowSameVersionUpgrades="yes" /

    MajorUpgrade AllowDowngrades =“no”DowngradeErrorMessage =“已经安装了[ProductName]的更新版本。” AllowSameVersionUpgrades =“是”/

So, every time you update your version(or your version is same, not less than current version), it reinstalls your product by removing the previous files and installing the product files. It will not downgrade your product.

因此,每次更新版本(或版本相同,不低于当前版本)时,都会通过删除以前的文件并安装产品文件来重新安装产品。它不会降级您的产品。

#5


Just put this element under the Product element:

只需将此元素放在Product元素下:

<MajorUpgrade AllowDowngrades="yes" />

More info in this HowTo

更多信息在这个HowTo