在使用 WiX 卸载应用程序之前未执行批处理文件

Batch file is not executing before application uninstalled using WiX

当需要卸载 Excel 插件时,我试图 运行 的批处理文件没有执行。我正在使用以下自定义操作来执行 post 安装和卸载产品。以下代码:

  <CustomAction Id="registeraddin" ExeCommand="[INSTALLFOLDER]RegisterMilerAddIn.bat" Directory="INSTALLFOLDER" Impersonate="no" Execute="deferred" Return="asyncWait" />
  <CustomAction Id="unregisteraddinpostinstall" ExeCommand="[INSTALLFOLDER]UnRegisterMilerAddIn.bat" Directory="INSTALLFOLDER" Impersonate="no" Execute="deferred" Return="asyncWait" />

  <InstallExecuteSequence>
    <Custom Action="registeraddin" After="InstallFiles">NOT Installed</Custom>
    <Custom Action="unregisteraddinpostinstall" After="InstallFiles">Installed AND (REMOVE = "ALL")</Custom>
  </InstallExecuteSequence>

在日志中产生此错误:

MSI (s) (44:04) [11:29:00:437]: Executing op: ActionStart(Name=unregisteraddinpostinstall,,)

MSI (s) (44:04) [11:29:00:437]: Executing op: CustomActionSchedule(Action=unregisteraddinpostinstall,ActionType=1058,Source=C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin\,Target=C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin\UnRegisterMilerAddIn.bat,)

MSI (s) (44:04) [11:29:00:846]: Note: 1: 1722 2: unregisteraddinpostinstall 3: C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin\ 4: C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin\UnRegisterMilerAddIn.bat

MSI (s) (44:04) [11:29:00:846]: Note: 1: 2205 2: 3: Error MSI (s) (44:04) [11:29:00:846]: Note: 1: 2228 2: 3: Error 4: SELECT Message FROM Error WHERE Error = 1722 CustomAction unregisteraddinpostinstall returned actual error code 100 (note this may not be 100% accurate if translation happened inside sandbox)

MSI (s) (44:04) [11:29:10:900]: Note: 1: 2205 2: 3: Error MSI (s) (44:04) [11:29:10:900]: Note: 1: 2228 2: 3: Error 4: SELECT Message FROM Error WHERE Error = 1709

MSI (s) (44:04) [11:29:10:900]: Product: WebMiles_Addin_Installer -- Error 1722. There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action unregisteraddinpostinstall, location: C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin\, command: C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin\UnRegisterMilerAddIn.bat

这个错误对我来说是模糊的。我也没有在我的批处理文件中做真正花哨的事情。 安装 Excel 插件 works 很好(这是本申请的前提)。但是我显然无法以相同的方式卸载插件,因此日志中出现了上述错误。

为了完整起见,这是我注册批次的内容 (RegisterMilerAddIn.bat):

SET WorkFolder= "C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin"

SET _NET_4_Folder= %WinDir%"\Microsoft.NET\Framework\v4.0.30319"

%_NET_4_Folder%\regasm.exe %WorkFolder%\Miler.ExcelAddin.dll /Codebase /tlb:%WorkFolder%\Miler.ExcelAddin.tlb >> C:\temp\log.txt

并注销批次(UnRegisterMilerAddIn.bat):

SET WorkFolder= "C:\Program Files (x86)\Werner Enterprises\Web Miles Excel Addin"

SET _NET_4_Folder= %WinDir%"\Microsoft.NET\Framework\v4.0.30319"

%_NET_4_Folder%\regasm.exe /unregister %WorkFolder%\Miler.ExcelAddin.dll /Codebase /tlb:%WorkFolder%\Miler.ExcelAddin.tlb >> C:\temp\log.txt

Heat.exe

UPDATE:我不喜欢下面的建议(使用自定义操作),Bob Arnson (WiX coder) reminded me that heat.exe(WiX 的通用 "harvester" / XML 标记生成器工具)可能会完成这项工作:

heat.exe file MyLib.dll -sfrag -suid -ag -out ComInterop.wxs

如果这有效——你应该测试——你已经从你的 WiX 安装程序中删除了很多 "clunk"。

您需要将生成的 COM/注册表信息整合到主 WiX 源文件中托管 COM Interop 文件的组件中。这需要一些小心和精确,并且不是很微不足道,但您可以避免很多笨拙的自定义操作风险。

您还可以heat.exe tlb 文件:

heat file MyFile.tlb -sfrag -suid -ag -out ComInterop2.wxs

似乎heat.exe跳过了接口信息。


批处理文件被认为是有害的

恕我直言,并试图提供帮助:批处理文件在部署时极易出错。它们几乎没有错误控制或处理意外情况的能力。我认为它们不适合现代部署,我认为这是共识意见。

您应该能够通过 EXE 自定义操作直接调用 regasm.exe - 消除所有批处理文件的笨拙和复杂性。郑重声明:不过我也不喜欢 EXE CA。

足够的意见。这是用于插入成熟的 WiX 源 (What characters do I need to escape in XML documents?) 的 EXE CA 的基本模型示例:

<..>

    <!-- AppSearch to find regasm.exe -->

    <Property Id="REGASM4" Secure="yes">
        <DirectorySearch Id="RegAsmPathx86" Path="[WindowsFolder]Microsoft.NET\Framework\v4.0.30319">
            <FileSearch Name="regasm.exe" />
         </DirectorySearch>
    </Property>

<..>

    <!-- Run regasm.exe CAs -->

    <CustomAction Id="Install" Directory="SystemFolder"
                  ExeCommand="&quot;[REGASM4]&quot; &quot;[MyAPP]ClassLib.dll&quot; /Codebase /silent /tlb:&quot;[MyAPP]ClassLib.tlb&quot;"
                  Execute="deferred" Impersonate="no" />

    <CustomAction Id="Uninstall" Directory="SystemFolder"
                  ExeCommand="&quot;[REGASM4]&quot; /unregister &quot;[MyAPP]ClassLib.dll&quot; /Codebase /silent /tlb:&quot;[MyAPP]ClassLib.tlb&quot;"
                  Execute="deferred" Impersonate="no" />
 <..>

   <!-- Sequenced And Conditioned CAs -->

    <InstallExecuteSequence>
        <Custom Action="Install" After="InstallFiles">Not Installed</Custom>
        <Custom Action="Uninstall" Before="RemoveFiles">REMOVE~="ALL"</Custom>
    </InstallExecuteSequence>

在研究并尝试了许多不同的属性之后,我找到了解决问题的方法。所以我在这里发布它可能会帮助其他人。我发现我的批处理文件在我可以 运行 插件卸载过程之前被删除,正如 Brian Sutherland 所逃避的那样。我终于在删除所有文件之前的卸载中找到了以下代码。

<InstallExecuteSequence>
    <Custom Action="unregisteraddinpostinstall" After="InstallInitialize">REMOVE="ALL"</Custom>
  </InstallExecuteSequence>

所以我仍将使用上面的代码,但我将实施 Stein Asmul 的建议来清理我的过程而不使用批处理文件。我仍在使用 After="InstallInitialize" 的原因是我的 ExcelAddin.dll 也是删除类型 Class 库的 regasm.exe /unregister 过程的一部分。在我 运行 脚本之前它也被删除了。在我实施 After="InstallInitialize">REMOVE="ALL" 后,脚本按预期运行。再次感谢 Brian 和 Stein!