【问题标题】:Wix 3.11 "This action is only valid for projects that are currently installed" after rebuilding the project重建项目后,Wix 3.11“此操作仅对当前安装的项目有效”
【发布时间】:2018-01-15 12:09:45
【问题描述】:

我有一个 WiX 3 安装项目,使用 VS 2017 社区和 Wix 工具集 v3.11,安装输出使用:

msiexec /i cient.setup.msi /lv output.log

一切都很好。使用

卸载

msiexec /x cient.setup.msi /lv output.log

也不错。 但是如果我重建 WiS 安装项目,然后尝试使用上述命令卸载,我会从 MSI 输出中收到错误 1602。即“此操作仅对当前安装的项目有效

这是我的Product.wxs文件的内容:

<?xml version="1.0" encoding="UTF-8"?>
<!-- The name of the product -->
<?define Name = "Notification Client" ?>
<!-- The manufacturer, for setup package publisher and folder info -->
<?define Manufacturer = "MyCompanies IT" ?>
<!-- The version number of this setup package-->
<?define Version = "1.0.1" ?>
<!-- UpgradeCode must be unique and not changed once the first version of the program is installed. -->
<?define UpgradeCode = "{GUID-HERE}" ?>

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
  <?define ClientService_TargetDir=$(var.ClientService.TargetDir)?>
  <Product Id="*" Name="$(var.Name)" Manufacturer="$(var.Manufacturer)" Language="1033" Version="$(var.Version)" UpgradeCode="$(var.UpgradeCode)">
    <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

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

    <Feature Id="ProductFeature" Title="Client.Setup" Level="1">
      <ComponentGroupRef Id="ProductComponents" />
      <ComponentRef Id="ApplicationShortcut" />
    </Feature>
  </Product>

  <Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="ROOTDIRECTORY" Name="$(var.Manufacturer)">
          <Directory Id="INSTALLFOLDER" Name="$(var.Name)" />
          <Component Feature="ProductFeature" Id="SetFolderPermissions" Guid="*">
            <CreateFolder>
              <util:PermissionEx User="Users" GenericAll="yes" />
            </CreateFolder>
          </Component>
        </Directory>
      </Directory>
      <Directory Id="StartupFolder" SourceName="Startup"/>
    </Directory>
  </Fragment>

  <Fragment>
    <DirectoryRef Id="StartupFolder">
            <Component Id="ApplicationShortcut" Guid="*">
              <Shortcut Id="StartupShortcut"
                   Directory="StartupFolder"
                   Name="Notification Client"
                   Target="[INSTALLFOLDER]\NotificationClient.exe"
                   WorkingDirectory="INSTALLFOLDER"
           />
              <RemoveFolder Id="CleanUpShortCut" Directory="StartupFolder" On="uninstall"/>
              <RegistryValue Root="HKCU" Key="Software\Microsoft\NotificationClient" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
            </Component>
    </DirectoryRef>
  </Fragment>

  <Fragment>
    <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
      <!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
      <!-- <Component Id="ProductComponent"> -->
      <!-- TODO: Insert files, registry keys, and other resources here. -->
      <!-- </Component> -->
      <Component Id="NotificationClient.exe" Guid="*">
        <File Id="NotificationClient.exe" Name="NotificationClient.exe" Source="$(var.ClientService_TargetDir)NotificationClient.exe" DiskId="1" KeyPath="yes" />
      </Component>
      <Component Id="NotificationClient.exe.config" Guid="*">
        <File Id="NotificationClient.exe.config" Name="NotificationClient.exe.config" Source="$(var.ClientService_TargetDir)NotificationClient.exe.config" KeyPath="no" />
      </Component>
      <Component Id="Newtonsoft.Json.dll" Guid="*">
        <File Id="Newtonsoft.Json.dll" Name="Newtonsoft.Json.dll" Source="$(var.ClientService_TargetDir)Newtonsoft.Json.dll" KeyPath="no" />
      </Component>
      <Component Id="Notifications.dll" Guid="*">
        <File Id="Notifications.dll" Name="Notifications.dll" Source="$(var.ClientService_TargetDir)Notifications.dll" KeyPath="no" />
      </Component>
      <Component Id="OHR_StdFunctions.dll" Guid="*">
        <File Id="OHR_StdFunctions.dll" Name="OHR_StdFunctions.dll" Source="$(var.ClientService_TargetDir)OHR_StdFunctions.dll" KeyPath="no" />
      </Component>
      <Component Id="OHR_MSGraph.dll" Guid="*">
        <File Id="OHR_MSGraph.dll" Name="OHR_MSGraph.dll" Source="$(var.ClientService_TargetDir)OHR_MSGraph.dll" KeyPath="no" />
      </Component>
      <Component Id="ServiceInstallation" Guid="*">
        <!-- Remove all files from the INSTALLFOLDER on uninstall -->
        <RemoveFile Id="ALLFILES" Name="*.*" On="both" />
      </Component>
    </ComponentGroup>
  </Fragment>
</Wix>

我感觉这与 GUID 问题有关,但我已遵循其他帖子中关于大写 GUID 和每次重新生成产品 ID 的指南,以确保可以顺利推出升级。

我是 Wix 的新手(这是我的第一个项目),因此请善待! :)

【问题讨论】:

  • 您只能卸载已安装的版本。如果您使用 Product Id="*" 重建项目,则它是不同的安装,因此未安装。

标签: wix windows-installer setup-project wix3.11


【解决方案1】:

您已将产品 GUID 设置为自动生成(这很好)。这意味着您编译的每个 MSI 都会有一个新的产品 G​​UID - 自然而然。您可以通过指定的 MSI 文件或通过指定要卸载的产品 G​​UID 来调用 MSI 卸载。有关这方面的信息,请参阅这个小“参考”,您的部分将是 第 3 部分Uninstalling an MSI file from the command line without using msiexec(这个答案有点长,请只关注第 3 部分) .

您在命令中指定要卸载的 MSI 文件不是当前安装在盒子上的 MSI - 因此嵌入在 MSI 中的产品代码对于当前卸载是错误的(什么安装的是您以前的版本之一 - 具有不同的产品 G​​UID)。

您可以在盒子上找到用于安装的原始 MSI(如果您还有的话),然后您的命令 msiexec /x cient.setup.msi /lv output.log 将起作用,或者您可以找出已安装产品的产品代码到底是什么,然后像这样卸载:msiexec /x {PRODUCT-GUID} /lv output.log。一旦您找到正确的产品 G​​UID,这将始终有效。此卸载从 %SystemRoot%\Installer(超级隐藏文件夹)中的原始 MSI 的缓存副本运行。

这是查找已安装产品的产品 G​​UID 的一种方法:How can I find the product GUID of an installed MSI setup?(这个答案也有点长,只需查找 PowerShell 命令即可)。


升级:如果您不为每个设置创建新的产品 G​​UID,则无法使用主要升级。你得到的是一个小的升级。这必须以不同于主要升级的方式安装。大多数人使用重大升级,因为它们更灵活。您需要进行重大升级,以使您的最新安装程序在安装现有安装程序时静默卸载,否则您会在添加/删除程序中获得两个条目。

设置重大升级:How To: Implement a Major Upgrade In Your Installer

我会添加你自己建议的链接:How to implement WiX installer upgrade?

【讨论】:

  • 感谢您的快速响应,我以为是这种情况,所以我将ProductID更改为修复,现在我在执行相同的过程时遇到了不同的错误......“另一个该产品的版本已经安装...”这没有意义,因为我现在有一个固定的产品 ID,我的版本和 UpgradeCode 仍然相同。这不是问题,但是如果将 ProductID 保持为自动,并且我推出更新,它只会在程序和功能中添加另一个条目,而不是更新现有条目。我明白为什么产品 ID 不同。
  • 我可以环顾四周,我发现这篇文章here 详细介绍了如何在更新之前卸载旧版本,以及不可避免地重建 msi 包。这解决了我的问题。所以我会将您的回复标记为答案。
  • 附注如果您认为我的问题对其他新的 Wix 用户有用,请支持我的问题 :)
  • 是的,您的问题的格式很好,但我已经对其进行了一些修复以消除 GUID(否则它们可能会被复制并且您可能会遇到问题 - GUID 不应该被其他人重新使用) .永远记得从您在线发布的来源中删除任何此类“sensitive data”。另外,请考虑对所有有用的答案进行投票。
【解决方案2】:

升级代码用于枚举潜在的候选者,以代替挂起的安装。当您重建时,/Wix/Product[@Id] 会重新生成,因此它会显示为一个新产品,它可以简单地使用您维护的现有升级代码“升级”任何东西。

【讨论】:

    猜你喜欢
    • 2021-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多