【问题标题】:Problem with Wix uninstall using CustomAction使用 CustomAction 卸载 Wix 的问题
【发布时间】:2019-08-07 21:01:07
【问题描述】:

我创建了一个非常简单的 MSI,它将一些文件复制到 ProgramFiles 目录,并在安装时调用在用 C# 编写的二进制文件中找到的自定义操作。

在安装时,我可以轻松调用任何我想要的自定义操作。例如,我创建了一个安装步骤,用户应在其中输入许可证,并在确认许可证后,使用 C# 自定义操作中编写的逻辑对服务器进行检查。

但是,在卸载时,每次我添加自定义操作(即使它只返回 Success),我都会收到安装失败的错误。

这是我使用卸载步骤的方式:

<InstallExecuteSequence>
  <Custom Action='TestUninstallation' After='MsiUnpublishAssemblies'>REMOVE="ALL"</Custom>
</InstallExecuteSequence>

其中 TestUninstallation 定义如下:

<CustomAction Id="TestUninstallation" Return="check" Execute="deferred" Impersonate="no" BinaryKey="TestCustomAction" DllEntry="Uninstall" />

属性 DllEntry 等于 Uninstall,这是一个仅返回成功的 C# 方法。

安装完成后,我正在尝试卸载,我得到了在 AdminUISequence 中定义的 UserExit 对话框,并带有 OnExit 属性。

知道我错过了什么吗?

【问题讨论】:

  • 现在没时间看这个,但是please skim this answer。请生成一个日志文件以检查该自定义操作的实际情况。您知道如何使用调试器单步执行代码吗?我在 SO 上有一个答案。
  • 那么安装程序日志显示了什么?

标签: installation wix windows-installer wix3.7


【解决方案1】:

调试:托管代码相对容易调试(原生代码实际上更容易)。这里有一些提示:


建议:我认为您只有一个 broken reference to the dll export function - 换句话说,一个错误的 dll 函数名称/引用:

<CustomAction Id="TestUninstallation" Return="check" Execute="deferred" Impersonate="no"
              BinaryKey="CustomActions" DllEntry="__ERRONEOUS FUNCTION REFERENCE__" />

只需检查 dll 实际导出的内容并像这样匹配:

<CustomAction Id="CustomAction1" BinaryKey="CustomActions" DllEntry="CustomAction1"/>

与往常一样,真正的 McCoy 是检查 dll 本身以查看您是否拥有正确的函数名称 (the below screen shot from this prior answer, recommended read)。

This is a native code C++ dll

This is a DTF-packaged managed code dll

请注意,这是一个嵌入了托管代码的本机 dll。它产生了一个非常不同的函数列表,但您仍然必须在其中找到您引用的函数名称。

This is a straight-up managed code dll (no native wrapping)

最后:这是直接托管代码 DLL,没有包装在本机 dll shell 中。


Un-Uninstallable Setup:当自定义操作在卸载过程中崩溃或失败时,您将无法摆脱安装(它只是回滚并且您正在坚持安装它)。有几个修复或解决方法。

在我看来,总体解决方法是在卸载时不使自定义操作失败,或者至少调整它们以便您可以通过命令行设置属性来强制卸载

在 MSI 属性表中设置:SUPPRESSERROR = 0。然后 - 需要时 - 在命令行设置:

msiexec.exe /x {PRODUCT-GUID} SUPPRESSERROR="1"

在 MSI 中,您可以使用以下条件来调整卸载自定义操作:

REMOVE="ALL" AND SUPPRESSERROR="0"

现在如果 SUPPRESSERROR 不是 0,自定义操作将不会运行。

有一个较旧的答案,还有几个选项:I screwed up, how can I uninstall my program?(由Wim Coenen 提供,我把他的答案弄乱了,提供了更多建议)。


样板:为了快速使用,让我在这里转储样板即席自定义动作测试项目。这假设在同一个 Visual Studio 解决方案中有一个名为 "CustomAction1" 的 C# 托管代码自定义操作项目,并在您的 WiX 源代码中添加了一个引用 - 就像您显然已经拥有的那样(这是为了稍后我们有都忘记了问题是什么,需要再次测试):

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*" Name="WiXCustomActionsTesting" Language="1033" Version="1.0.0.0"
           Manufacturer="test" UpgradeCode="PUT-GUID-HERE">
        <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

    <UIRef Id="WixUI_Mondo" />
    <Property Id="SUPPRESSERROR" Value="0" Secure="yes" />

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

    <Feature Id="ProductFeature" Title="WiXCustomActionsTesting" Level="1">
      <ComponentGroupRef Id="ProductComponents" />
    </Feature>

    <!--BEGIN CUSTOM ACTION SECTION-->

      <Binary Id="CustomActions" SourceFile="$(var.CustomAction1.TargetDir)\$(var.CustomAction1.TargetName).CA.dll" />
      <CustomAction Id="TestUninstallation" Return="check" Execute="deferred" Impersonate="no" BinaryKey="CustomActions" DllEntry="CustomAction1" />

      <InstallUISequence></InstallUISequence>

      <InstallExecuteSequence>
        <Custom Action='TestUninstallation' After='InstallInitialize'></Custom>
      </InstallExecuteSequence>

    <!--END CUSTOM ACTION SECTION-->

  </Product>

    <Fragment>
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="INSTALLFOLDER" Name="WiXCustomActionsTesting" />
            </Directory>
        </Directory>
    </Fragment>

  <Fragment>

    <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">

      <Component>
        <File Source="C:\Projects\MySetup\MyApp.exe">
        </File>
      </Component>

    </ComponentGroup>

  </Fragment>
</Wix>
  1. 创建 WiX 项目
  2. 复制粘贴代码,设置新的升级GUID
  3. 创建 CustomAction 项目,默认名称
  4. 从 wix 项目添加对自定义操作项目的引用
  5. 添加对 WiXUIExtension.dll 的引用
  6. 在组件中调整文件路径
  7. 编译

【讨论】:

  • 这取决于 screnshot 是 C++ CA 的样子。 C# DTF 不会看起来像那样。
  • 是的,是的。我把它从链接的答案中拿出来。我会更新的。
  • 添加了更多截图,不是最好的解释,也不是我的舒适区,但至少概述是存在的。您使用包装器 dll 还是普通的 .NET dll?我不喜欢后者。
  • 这完全在我的舒适区。日志文件可能会显示 .net 异常。如果他们甚至没有看过日志文件,就很难帮助他们。
  • 同样对于 DTF 打包的 DLL,您首先必须将 .DLL 重命名为 ZIP 并提取其中的程序集。然后,您还可以使用 Reflector 对其进行反编译,进行所需的任何更改,重新编译并将其注入回 MSI。 :) 我已经为损坏的第三方安装做过很多次了。
猜你喜欢
  • 1970-01-01
  • 2013-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-27
  • 2015-01-25
  • 1970-01-01
相关资源
最近更新 更多