在MSI安装程序中更新服务名称并重新安装/升级时出错

时间:2017-08-15 19:41:50

标签: wix windows-installer

我有一个MSI可以安装一些服务。我更改了其中一个的名称并更新了Wix文件中的引用。

当我将它安装为新的MSI时,它工作正常。但是,如果存在升级方案(使用旧服务名称安装MSI并尝试安装此新服务名称已更改的MSI),则会出现以下错误:

ERROR

这里有任何提示吗?我只是在.wxs文件中重命名。我是否必须使用现有组件ID卸载旧组件并使用新组件ID命名新组件?

目前,使用具有新名称的旧组件ID。

旧代码的一部分:

<Directory Id="dirxxx" Name="oldname">
                <!-- oldname service-->
              <Component Id="cmpOldNameService" Guid="bbb"
                  SharedDllRefCount="no" KeyPath="no" NeverOverwrite="no" Permanent="no" Transitive="no"
                  Win64="no" Location="either">
              <RemoveFile Id="ccc" On="uninstall" Name="z.dll"/>
              <File Id="ccc" KeyPath="no" Source="$(var.xSource)\OldNameService\a.dll"/>
              <File Id="ddd" KeyPath="no" Source="$(var.xSource)\OldNameService\b.dll"/>
              <File Id="eee" KeyPath="no" Source="$(var.xSource)\OldNameService\c.dll"/>
              <File Id="fff" KeyPath="no" Source="$(var.xSource)\OldNameService\d.dll"/>
              <File Id="ggg" KeyPath="no" Source="$(var.xSource)\OldNameService\e.dll"/>
              <File Id="hhh" KeyPath="no" Source="$(var.xSource)\OldNameService\f.dll"/>
              <File Id="iii" KeyPath="yes" Source="$(var.xSource)\OldNameService\g.exe"/>
              <File Id="jjj" KeyPath="no" Source="$(var.xSource)\OldNameService\h.dll"/>
              <File Id="kkk" KeyPath="no" Source="$(var.xSource)\OldNameService\i.dll"/>
              <ServiceInstall Id="OldNameService" DisplayName="OldName Service" Name="NewName"
                ErrorControl="normal" Start="auto" Type="ownProcess" Vital="yes" Description="OldName Service">
                <ServiceConfig DelayedAutoStart="yes" OnInstall="yes" OnReinstall="yes"/>
              </ServiceInstall>

              <ServiceControl Id="OldNameServiceControl" Name="NewName"
                Start="install" Stop="uninstall" Remove="uninstall" Wait="no"/>

            </Component>

              <Component Id="lll" Guid="mmm" NeverOverwrite="yes">
                <File Id="nnn" KeyPath="yes" Source="$(var.xSource)\OldNameService\OldName.exe.config"/>
                <util:XmlFile Id="UpdateOldNamelogFileName"
                              File="[#nnn]"
                              Action="setValue"
                              ElementPath="/configuration/appSettings/add[\[]@key='logFile'[\]]/@value"
                              Value="[ooo]oldname_YYYYMM.log" />
              </Component>

替换为新代码:

<Directory Id="dirxxx" Name="newname">
                <!-- newname service-->
              <Component Id="cmpNewNameService" Guid="bbb"
                  SharedDllRefCount="no" KeyPath="no" NeverOverwrite="no" Permanent="no" Transitive="no"
                  Win64="no" Location="either">
              <RemoveFile Id="ccc" On="uninstall" Name="z.dll"/>
              <File Id="ccc" KeyPath="no" Source="$(var.xSource)\NewNameService\a.dll"/>
              <File Id="ddd" KeyPath="no" Source="$(var.xSource)\NewNameService\b.dll"/>
              <File Id="eee" KeyPath="no" Source="$(var.xSource)\NewNameService\c.dll"/>
              <File Id="fff" KeyPath="no" Source="$(var.xSource)\NewNameService\d.dll"/>
              <File Id="ggg" KeyPath="no" Source="$(var.xSource)\NewNameService\e.dll"/>
              <File Id="hhh" KeyPath="no" Source="$(var.xSource)\NewNameService\f.dll"/>
              <File Id="iii" KeyPath="yes" Source="$(var.xSource)\NewNameService\g.exe"/>
              <File Id="jjj" KeyPath="no" Source="$(var.xSource)\NewNameService\h.dll"/>
              <File Id="kkk" KeyPath="no" Source="$(var.xSource)\NewNameService\i.dll"/>
              <ServiceInstall Id="NewNameService" DisplayName="NewName Service" Name="NewName"
                ErrorControl="normal" Start="auto" Type="ownProcess" Vital="yes" Description="New Name Service">
                <ServiceConfig DelayedAutoStart="yes" OnInstall="yes" OnReinstall="yes"/>
              </ServiceInstall>

              <ServiceControl Id="NewNameServiceControl" Name="NewName"
                Start="install" Stop="uninstall" Remove="uninstall" Wait="no"/>

            </Component>

              <Component Id="lll" Guid="mmm" NeverOverwrite="yes">
                <File Id="nnn" KeyPath="yes" Source="$(var.xSource)\NewNameService\NewName.exe.config"/>
                <util:XmlFile Id="UpdateNewNamelogFileName"
                              File="[#nnn]"
                              Action="setValue"
                              ElementPath="/configuration/appSettings/add[\[]@key='logFile'[\]]/@value"
                              Value="[ooo]newservice_YYYYMM.log" />
              </Component>

2 个答案:

答案 0 :(得分:2)

这已经太长了,无法作为评论添加,我添加这个作为答案虽然它可能不会为你回答:

  • 最明显的“错误”或至少是非标准问题是您在单个组件中有很多二进制文件。这是不是最佳实践(事实上非常糟糕的做法)。
  • 在您执行任何其他操作之前,请将您的组件拆分为为每个文件创建一个组件。我总是每个组件使用一个文件,即使对于非二进制文件也是如此,但最佳实践表明,您应该始终为二进制文件使用单独的组件。实质上,这是正确部署的要求。
  • 要保持简短:如果在同一个组件中保留多个文件,则其中只有一个是密钥文件。如果该文件的版本号没有增加(对于二进制文件),则所有其他文件也不会更新 - 即使它们的版本增加了。只有密钥文件才能确定是否安装了组件。并且组件仅作为整体安装或根本不安装。
  • 对于非版本化文件,事情以类似的方式工作,但它不是检查的版本,而是文件是否已被修改。如果磁盘上的文件已被修改,则组件安装。阅读MSDN文章File Versioning Rules中的更多内容。您还可以在同一问题上查看this Symantec article。这个问题的答案值得一读(以及Chris Painter的评论):File Versioning Rules When Neither Components Has a Key File
  • 如果您的应用程序有“实时版”,我将使用主要升级,并在InstallExecuteSequence的早期安排RemoveExistingProducts。简单来说,这意味着您将在安装新版本之前完全卸载以前的版本。这应该消除组件创建错误或其他任何错误后的任何错误。我没有太详细地阅读它,但是这个答案(第一个)似乎是如何安排主要升级的正确解释:How to get WiX major upgrade working?。或者直接查看来源和check the WiX 3 documentation for how to implement a major upgrade,只是为了更好地衡量我添加此链接:How to implement WiX installer upgrade?
  • 除此之外,我还建议您“简化”您的WiX XML,如本答案中所述:Syntax for guids in WIX?。您定义的属性越少,读取文件内容就越容易,并且可以隐藏的错误越少(以后XML格式的升级可能会更容易)。
  • 请首先尝试此“组件修复”和主要升级调整,看看这是否可以解决您的问题。并尝试 source simplification

答案 1 :(得分:0)

所以我能在这里解决我的问题。我想进行小幅升级,并在Account ServiceInstall中添加Network Service属性。{/ p>

<ServiceInstall Id="Service1" DisplayName="My Service" Name="MyService"
                    ErrorControl="normal" Start="auto" Type="ownProcess" Vital="yes" Description="My Service" Account="NT Authority\NetworkService">