用于2个组件的WiX安装程序

时间:2019-03-01 20:01:38

标签: wix windows-installer chaining

已完成WiX新手的任务,不知道如何解决它,甚至不确定。我有两个可执行文件,它们将位于供应商目录下的自己的文件夹中,如下所示:

C:\Program Files (x86)\My Company
 |
 +---Program A
 |    |
 |    +---config.txt
 |    +---program_A.exe
 |
 +---Program B
 |    |
 |    +---config.txt
 |    +---program_B.exe

程序A和程序B将始终打包在一起,并且都作为Windows服务安装。程序A的更新时间可能会比程序B的更新频率更高,并且发生这种情况时,我需要程序B保持运行,因为它正在将程序A的状态报告给另一台计算机。

我设法实现的任务是在同一个WiX文件中包含两个组件,但是显然在product元素中只有一个升级代码,因此即使程序B不变,它们都卸载并重新安装。

我尝试了链接(使用刻录)两个单独的MSI的路线,但被告知我们只能以MSI的形式分发产品,而不能像刻录产生的exe一样分发邮件。

是否有可能实现我想要的目标,如果需要,我需要研究什么才能做到?

修改  我尝试创建两个模块并使用合并,但这似乎也不起作用。这是我的模块之一:

MergeModule1.wxs

<?xml version='1.0'?>

<?define version = "!(bind.fileVersion.Program1_Exe)"?>
<?define language = 1033?>
<?define company_name = "ABC Soft"?>
<?define codename = program1?>
<?define product_name = Program1?>
<?define full_product_name = '$(var.company_name) $(var.product_name)'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'
 xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">

<Module Id="MergeModule1ID" Language='$(var.language)' Version='$(var.version)'>

    <Package Id="3a281d57-33fd-4601-8aee-9e6349701b4b"
        Description='$(var.full_product_name)'
        Manufacturer='$(var.company_name)'
        InstallScope='perMachine'
        InstallerVersion='200'
        Comments='Version: $(var.version)'>
    </Package>

    <Directory Id='TARGETDIR' Name='SourceDir'>
        <Directory Id='ProgramFilesFolder' Name='PFiles'>
            <Directory Id='VendorDir' Name='$(var.company_name)'>
                <Directory Id='TheProgramDir' Name='$(var.product_name)'/>
            </Directory>
        </Directory>
    </Directory>

    <DirectoryRef Id="TheProgramDir">
        <Component Id='Program1_Exe' Guid='d6fdaf52-16aa-42f8-9790-4287510f53f5'>
            <File Id='Program1_Exe'
                Name='Program1.exe'
                Source='Program1.exe'
                KeyPath='yes' />

            <ServiceInstall Id='InstallService'
                Name='$(var.codename)'
                DisplayName='$(var.full_product_name)'
                Description='$(var.full_product_name)'
                Type='ownProcess'
                Vital='yes'
                Start='auto'
                ErrorControl='ignore'
                Interactive='no'>   

                <util:ServiceConfig
                    FirstFailureActionType="restart"
                    SecondFailureActionType="restart"
                    ThirdFailureActionType="restart"
                    ResetPeriodInDays="1"
                    RestartServiceDelayInSeconds="60" />
            </ServiceInstall>

            <ServiceControl Id='StartService'
                Start='install'
                Stop='both'
                Remove='uninstall'
                Wait='yes'
                Name='$(var.codename)' />
        </Component>
    </DirectoryRef>

</Module>

我也有一个MergeModule2.wxs,其中包含对Program2 exe和其他GUID的相关更改。 Program1 exe的版本为2.0.0.1,而Program2 exe的版本为1.0.2.1,因此将相应地设置模块中的版本号。在合并wix文件中,我有:

MergeInstallers.wxs

<?xml version='1.0' encoding='windows-1252'?>

<?define version = "0.1.0.0"?>
<?define language = 1033?>
<?define company_name = "ABC Soft"?>
<?define codename = program?>
<?define product_name = Program?>
<?define full_product_name = '$(var.company_name) $(var.product_name)'?>
<?define upgrade_code = eaf3891c-cd16-4239-b8bc-1b2cd7816c16?>

<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>

<Product Id='*'
  UpgradeCode='$(var.upgrade_code)'
  Name='$(var.full_product_name)'  
  Language='$(var.language)'
  Version='$(var.version)' 
  Manufacturer='$(var.company_name)'>

  <Package Description='$(var.full_product_name)'
      Manufacturer='$(var.company_name)'
      InstallScope='perMachine'
      InstallerVersion='200'
      Compressed='yes'
      Comments='Version: $(var.version)'>
  </Package>  

  <Upgrade Id='$(var.upgrade_code)'>

      <UpgradeVersion OnlyDetect='no' Property='NEWPRODUCTFOUND'
          Minimum='$(var.version)' IncludeMinimum='no'
          Language='$(var.language)' />
      <UpgradeVersion OnlyDetect='no' Property='OLDPRODUCTFOUND'
          Maximum='$(var.version)' IncludeMaximum='no'
          Language='$(var.language)' />
      <UpgradeVersion OnlyDetect='no' Property='CURRENTPRODUCTFOUND'
          Minimum='$(var.version)' IncludeMinimum='yes'
          Maximum='$(var.version)' IncludeMaximum='yes'
          Language='$(var.language)' />
  </Upgrade>

  <Media Id='1' Cabinet='$(var.codename).cab' EmbedCab='yes'></Media>

  <Directory Id='TARGETDIR' Name='SourceDir'>
      <Directory Id='ProgramFilesFolder' Name='PFiles'>
          <Directory Id='VendorDir' Name='$(var.company_name)'>
              <Merge Id="Mod1" Language='$(var.language)' SourceFile="Program1\MergeModule1.msm" DiskId="1" />
              <Merge Id="Mod2" Language='$(var.language)' SourceFile="Program2\MergeModule2.msm" DiskId="1" />
          </Directory>
      </Directory>
  </Directory>

  <Feature Id="Msm" Title="Msm" Level="1">
      <MergeRef Id="Mod1" />
      <MergeRef Id="Mod2" />
  </Feature>

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

</Product>

现在,在首次安装msi时,将安装两个服务并运行正常。现在,我对Program1.exe进行了更改,以便exe的版本从2.0.0.1更改为2.0.0.2,而Program2.exe仍保持1.0.2.1不变(随后,Program1的模块版本也将更改)。我重建了所有内容并运行了msi,并重新安装了两个程序并重新启动了两个服务。我期望发生的事情是由于版本更改而将替换Program1,并且Program2将继续运行。是我遗漏了明显的东西还是我的逻辑走了?

1 个答案:

答案 0 :(得分:0)

这非常容易。从本教程开始:

https://github.com/iswix-llc/iswix-tutorials

使用两个构建后的副本创建两个服务项目,并在合并模块中定义两个服务。

最后,在Product.wxs的MajorUpgrade元素中添加Schedule="afterInstallExecute"

http://wixtoolset.org/documentation/manual/v3/xsd/wix/majorupgrade.html

这是重要的部分。您必须确保版本和正确构建服务100%。实际更改后,仅包括更新的EXE。如果版本未更改,MSI不会重新安装该组件,因此该服务不会停止广告启动。如果版本已更改,它将升级组件,导致该服务在升级过程中停止和启动。