1

我有一个问题,我使用 wix 创建了一个 cub 文件,它工作正常,但是当我尝试针对使用 InstallShield 创建的 MSI 运行它时,我收到以下错误:

CUB 文件和数据库之间的致命架构冲突。无法进行评估。

我查看了 installshield msi 和 cub 中的架构,它似乎与 cub 中的长整数 (4) 和 msi 中的短整数 (2) 的几列有关。

有没有办法改变 wix 在标准表(如媒体、文件、CustomActions 等)上设置模式的方式?

或者,是否有一种自动化方式可以像通过脚本一样调整 MSI 的架构?

4

2 回答 2

1

我编写了一个 C#/DTF ICE 框架,并在博客上写了一篇关于它的文章:

MSI 提示:使用 C#/DTF 创作 ICE

实际源代码可在以下位置下载:

使用 C#/DTF 编写 ICE

WiX 没有每个说的“CUB”元素,但我能够让它“足够接近”。我记得与 Rob 的电子邮件交流,要求在 WiX 中提供官方支持,但回复充其量是中立的。

以下是可用源代码的片段:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="c3252df2-a757-4874-8dc6-0e235f130818" Name="Cub" Version="1.0.0.0" Language="1033" Manufacturer="Cub">
    <Package InstallerVersion="200" Compressed="yes"/>

    <Binary Id="ICE" SourceFile="$(var.Tests.TargetDir)$(var.Tests.TargetName).CA.dll"></Binary>

    <CustomAction Id="ICE_DE_10" BinaryKey="ICE" DllEntry="ICE_DE_10"/>
    <CustomAction Id="ICE_DE_20" BinaryKey="ICE" DllEntry="ICE_DE_20"/>

    <CustomTable Id="_ICESequence">
      <Column Id="Action" PrimaryKey="yes" Type="string" Width="72" Category="Identifier" Description="Name of ICE action to invoke" Modularize="Column" />
      <Column Id="Condition" Type="string" Width="255" Nullable="yes" Category="Condition" Description="Optional expression which skips the ICE action if evaluates to expFalse."/>
      <Column Id="Sequence" Type="int" Width="2" Nullable="yes" MinValue="0" MaxValue="32767" Description="Number that determines the sort order in which the ICE actions are to be executed." />
      <Row>
        <Data Column="Action">ICE_DE_10</Data>
        <Data Column="Condition"></Data>
        <Data Column="Sequence">10</Data>
      </Row>
      <Row>
        <Data Column="Action">ICE_DE_20</Data>
        <Data Column="Condition"></Data>
        <Data Column="Sequence">20</Data>
      </Row>
    </CustomTable>

    <AdminUISequence>
      <CostInitialize Suppress="yes"/>
      <FileCost Suppress="yes"/>
      <CostFinalize Suppress="yes"/>
      <ExecuteAction Suppress="yes"/>
    </AdminUISequence>

    <AdminExecuteSequence >
      <CostInitialize Suppress="yes"/>
      <FileCost Suppress="yes"/>
      <CostFinalize Suppress="yes"/>
      <InstallValidate Suppress="yes"/>
      <InstallInitialize Suppress="yes"/>
      <InstallAdminPackage Suppress="yes"/>
      <InstallFiles Suppress="yes"/>
      <InstallFinalize Suppress="yes"/>
    </AdminExecuteSequence>

    <AdvertiseExecuteSequence>
      <CostInitialize Suppress="yes"/>
      <CostFinalize Suppress="yes"/>
      <InstallValidate Suppress="yes"/>
      <InstallInitialize Suppress="yes"/>
      <PublishFeatures Suppress="yes"/>
      <PublishProduct Suppress="yes"/>
      <InstallFinalize Suppress="yes"/>
    </AdvertiseExecuteSequence>

    <InstallUISequence>
      <CostInitialize Suppress="yes"/>
      <FileCost Suppress="yes"/>
      <CostFinalize Suppress="yes"/>
      <ValidateProductID Suppress="yes"/>
      <ExecuteAction Suppress="yes"/>
    </InstallUISequence>

    <InstallExecuteSequence>
      <CostInitialize Suppress="yes"/>
      <FileCost Suppress="yes"/>
      <CostFinalize Suppress="yes"/>
      <ValidateProductID Suppress="yes"/>
      <InstallValidate Suppress="yes"/>
      <InstallInitialize Suppress="yes"/>
      <InstallFinalize Suppress="yes"/>
      <PublishFeatures Suppress="yes"/>
      <PublishProduct Suppress="yes"/>
      <ProcessComponents Suppress="yes"/>
      <UnpublishFeatures Suppress="yes"/>
      <RegisterUser Suppress="yes"/>
      <RegisterProduct Suppress="yes"/>
    </InstallExecuteSequence>

  </Product>
</Wix>

我还执行以下操作作为构建后事件(将 MSI 复制到 CUB)

    <PostBuildEvent>copy "$(TargetPath)" "$(TargetDir)$(TargetName).cub"
del "$(TargetPath)"</PostBuildEvent>
于 2011-02-17T13:26:53.053 回答
0

以下脚本解决了该问题。如果架构不同,Wix 似乎会创建一个 Windows 安装程序不喜欢的媒体和文件表。如此简单的解决方案是在 wix 创建 cub 文件作为构建后操作之后删除两个表。

Const msiOpenDatabaseModeTransact = 1

Dim installer
Dim db
Dim view
Set installer = CreateObject("WindowsInstaller.Installer")
Set db = installer.OpenDatabase("Wix\Release\UnitTest.cub", msiOpenDatabaseModeTransact)
Set view = db.OpenView("DROP TABLE `File`")
view.Execute
view.close

Set view = db.OpenView("DROP TABLE `Media`")
view.Execute
view.close

Set view = nothing
db.commit
Set db = nothing
于 2011-02-18T00:58:43.163 回答