1

I have a problem where I create a cub file using wix which works fine however when I try and run it against a MSI created with InstallShield I get the following error:

Fatal schema conflict between CUB file and database. Unable to perform evaluation.

I have had a look at the schema in both the installshield msi and in the cub and it appears to be related to a few columns being long ints (4) in the cub and short ints (2) in the msi.

Is there a way to change how wix sets the schema on standard tables like media, file, CustomActions etc?

Or alternatively is there an automated way I can adjust the schema of an MSI like through a script?

Yan Sklyarenko
  • 31,557
  • 24
  • 104
  • 139
Wil
  • 534
  • 4
  • 18

2 Answers2

1

I've written a C#/DTF ICE framework and I blogged about it at:

MSI Tip: Authoring an ICE using C# / DTF

The actual source code is available for download at:

Authoring an ICE using C# / DTF

WiX doesn't have a "CUB" element per say but I was able to get it 'close enough'. I rememeber an email exchange with Rob asking for official support in WiX but the response was neutral at best.

Here's a snippet from the available source code:

<?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>

Also I do the following as a post build event ( copy the MSI to CUB )

    <PostBuildEvent>copy "$(TargetPath)" "$(TargetDir)$(TargetName).cub"
del "$(TargetPath)"</PostBuildEvent>
Christopher Painter
  • 54,556
  • 6
  • 63
  • 100
  • Thanks for getting back to me. Your blog post was where I started building the CUB from :). It works perfect except when I try to run the CUB file against an msi created by InstallShield because the schema of the msi appears to be slightly different. You don't happen to know how to change the schema itself do you? I have tried using customtable to define the inbuilt tables that are causing problems but it just reverts to the default. – Wil Feb 17 '11 at 23:18
  • Gave you credit for the answer since your blog post gave me most of the solution I was after in the first place :). Building a ICE validation script in wix. :) – Wil Feb 18 '11 at 00:59
0

The following script fixes the problem. It appears Wix creates a Media and File table which windows installer doesn't like if the schema is different on. So simple solution is to drop both tables after wix creates the cub file as a post build action.

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
Wil
  • 534
  • 4
  • 18
  • I guess it wasn't 'close enough' then. :-) I remember emailing Rob saying I wish I could get WiX to generate a CUB correctly but I never encountered the different schema problem. That would make sense though because remember when you run validation the CUB actually get's merged into an in memory copy of the database that you are validating. I suppose I should update my blog and post a new version to InstallSite. – Christopher Painter Feb 18 '11 at 02:57
  • Another trick is to use Orca to create a transform that deletes those two tables and then just use msitran.exe to apply the transform during the postbuild. It allows you to scale the changes made to the database while eliminating all of the scripting. – Christopher Painter Feb 18 '11 at 03:05
  • Thanks might have to look at that too. – Wil Feb 18 '11 at 05:41