Use WiX 5 (#66)
authorChristian Ullrich <chris@chrullrich.net>
Mon, 14 Oct 2024 14:05:02 +0000 (16:05 +0200)
committerGitHub <noreply@github.com>
Mon, 14 Oct 2024 14:05:02 +0000 (10:05 -0400)
* Make product code automatically random

Instead of externally generating it and using it explicitly.

* Componentize the merge module

This prevents upgrades from leaving files from the previous version
behind that are not in the new version.

* Configure drivers on x64 The Way It Should Be Done

Use the ODBCDriver element only, without additional Registry settings.
This works, although it does not solve the file name issue and therefore
still requires removing the short file names from the File table.

It also works for installing the x86 driver on an x64 system. Whether it
works on an x86 system remains unknown.

* Configure drivers on x86 In The Exact Same Way

Tested on Windows 10 x86; the driver installs correctly and works
at first glance (in Access, to be precise). Registry and file system
look good.

The comment saying it "probably would be safe" is probably correct.

* Use candle's -arch option to select build platform

According to docs, using Package/@Platform "is discouraged". The -arch
option also provides the default bitness for components, making the
Component/@Win64 attribute unnecessary in single-architecture packages.

* Reindent

* Save some attributes

* Replace upgrade logic with MajorUpgrade element

This element compiles into approximately the same entries in the
Upgrade, CustomAction, and InstallExecuteSequence tables.

* Remove unused GUID

I think this was the product code, a long time ago.

* Make MSI file smaller

By about 20 percent.

* Better select where to remove short file names

Use the FileName column itself instead of the file ID. This is less
susceptible to changes in file IDs (and component IDs) that may happen
when relying more on default behaviors in future WiX versions.

* Build with WiX 5

This is a preview. It appears to build a working x64 installer; I have
tested nothing else yet.

* Clean up modify_msi.vbs

Also, put blame where it belongs, which is Windows Installer. If this
was a bug in WiX, then the fix would be to enforce 8.3 file names for
ODBC drivers, and we wouldn't like that very much either, would we?

* Increase WiX-5-ness

- Remove most Component elements in favor of naked files
- Replace PGFOLDER variable with ProgramFiles6432Folder

The Condition element on Component has become an attribute in WiX 5, and
the combination of preprocessor and component condition (i.e. include
a non-x64 condition only in a non-x64 package) to install PGXA only from
a package native to the underlying OS does not work anymore. Replace it
with a pure component condition that includes the package architecture.

The Template summary property has this information already, but it is
not available from within the installation, and I'm not about to start
writing custom actions.

* Update build workflow for WiX 5

.github/workflows/main.yml
installer/README.txt
installer/buildInstallers.ps1
installer/modify_msi.vbs
installer/psqlodbc_cpu.wxs
installer/psqlodbcm_cpu.wxs

index ca452049e0570edb889de2ddc05f3f0463e3ea7b..8d3db77b883134e8776d7e15d85abab45c99ac22 100644 (file)
@@ -275,6 +275,12 @@ jobs:
       with: 
         arch: x86
 
+    - name: Install WiX
+      shell: cmd
+      run: |
+        dotnet tool install --global wix
+        wix extension add --global WixToolset.UI.wixext
+
     - name: build psqlodbc standard
       shell: powershell      
       working-directory: psqlodbc
index 3a1b1872afebe1eff473bb84cba55fe96eb1416d..ffaaee4e99f2cdb689b25c1c15614b2d4489b55b 100644 (file)
@@ -1,11 +1,15 @@
 This directory contains the psqlODBC installer for Windows. To build the
-installer, you will need a copy of WiX installed somewhere in your system
-path. The installer has been tested with WiX version 3.0.2420 and WiX 3.8 at
-the time writing.
+installer, you will need a copy of WiX installed. The installer has been
+tested with WiX version 5.0.2 at the time of writing.
 
 WiX may be downloaded from:
 
-  http://wix.codeplex.com/
+  http://wixtoolset.org/
+
+In addition to the base package, the UI extension is required:
+
+  dotnet tool install --global wix
+  wix extension add --global WixToolset.UI.wixext
 
 
 HOW TO BUILD
index 6373db61072b2a4ca035bdf229b1fa6bb7495151..20e15ef078b2ddd900f9eb7877eaa7dcef483e10 100644 (file)
@@ -256,46 +256,31 @@ function buildInstaller([string]$CPUTYPE)
 
    [string []]$libpqRelArgs=@()
    for ($i=0; $i -lt $maxmem; $i++) {
-       $libpqRelArgs += ("-dLIBPQMEM$i=" + $libpqmem[$i])
+       $libpqRelArgs += "-d", ("LIBPQMEM$i=" + $libpqmem[$i])
    }
 
    if (-not(Test-Path -Path $CPUTYPE)) {
        New-Item -ItemType directory -Path $CPUTYPE | Out-Null
    }
 
-   $PRODUCTCODE = [GUID]::NewGuid()
-   Write-Host "PRODUCTCODE: $PRODUCTCODE"
-
    try {
        pushd "$scriptPath"
 
        Write-Host ".`nBuilding psqlODBC/$SUBLOC merge module..."
        $BINBASE = GetObjbase ".."
        $INSTBASE = GetObjbase ".\$CPUTYPE" "installer\$CPUTYPE"
-       candle -nologo $libpqRelArgs "-dPlatform=$CPUTYPE" "-dVERSION=$VERSION" "-dSUBLOC=$SUBLOC" "-dLIBPQBINDIR=$LIBPQBINDIR" "-dLIBPQMSVCDLL=$LIBPQMSVCDLL" "-dLIBPQMSVCSYS=$LIBPQMSVCSYS" "-dPODBCMSVCDLL=$PODBCMSVCDLL" "-dPODBCMSVPDLL=$PODBCMSVPDLL" "-dPODBCMSVCSYS=$PODBCMSVCSYS" "-dPODBCMSVPSYS=$PODBCMSVPSYS" "-dNoPDB=$NoPDB" "-dBINBASE=$BINBASE" -o $INSTBASE\psqlodbcm.wixobj psqlodbcm_cpu.wxs
+       wix build --nologo -arch $CPUTYPE $libpqRelArgs -d "VERSION=$VERSION" -d "SUBLOC=$SUBLOC" -d "LIBPQBINDIR=$LIBPQBINDIR" -d "LIBPQMSVCDLL=$LIBPQMSVCDLL" -d "LIBPQMSVCSYS=$LIBPQMSVCSYS" -d "PODBCMSVCDLL=$PODBCMSVCDLL" -d "PODBCMSVPDLL=$PODBCMSVPDLL" -d "PODBCMSVCSYS=$PODBCMSVCSYS" -d "PODBCMSVPSYS=$PODBCMSVPSYS" -d "NoPDB=$NoPDB" -d "BINBASE=$BINBASE" -o $INSTBASE\psqlodbc_$CPUTYPE.msm psqlodbcm_cpu.wxs
        if ($LASTEXITCODE -ne 0) {
            throw "Failed to build merge module"
        }
 
-       Write-Host ".`nLinking psqlODBC merge module..."
-       light -sval -nologo -o $INSTBASE\psqlodbc_$CPUTYPE.msm $INSTBASE\psqlodbcm.wixobj
-       if ($LASTEXITCODE -ne 0) {
-           throw "Failed to link merge module"
-       }
-
        Write-Host ".`nBuilding psqlODBC installer database..."
 
-       candle -nologo "-dPlatform=$CPUTYPE" "-dVERSION=$VERSION" "-dSUBLOC=$SUBLOC" "-dPRODUCTCODE=$PRODUCTCODE" "-dINSTBASE=$INSTBASE" -o $INSTBASE\psqlodbc.wixobj psqlodbc_cpu.wxs
+       wix build --nologo -arch $CPUTYPE -ext WixToolset.UI.wixext -d "VERSION=$VERSION" -d "SUBLOC=$SUBLOC" -d "INSTBASE=$INSTBASE" -o $INSTBASE\psqlodbc_$CPUTYPE.msi psqlodbc_cpu.wxs
        if ($LASTEXITCODE -ne 0) {
            throw "Failed to build installer database"
        }
 
-       Write-Host ".`nLinking psqlODBC installer database..."
-       light -sval -nologo -ext WixUIExtension -cultures:en-us -o $INSTBASE\psqlodbc_$CPUTYPE.msi $INSTBASE\psqlodbc.wixobj
-       if ($LASTEXITCODE -ne 0) {
-           throw "Failed to link installer database"
-       }
-
        Write-Host ".`nModifying psqlODBC installer database..."
        cscript modify_msi.vbs $INSTBASE\psqlodbc_$CPUTYPE.msi
        if ($LASTEXITCODE -ne 0) {
index c1353fc894250533b862cf89e26c5eb620631f66..8934411c4f16396b42cdcdafb8ca6768bc238bd9 100755 (executable)
@@ -2,7 +2,7 @@
 '  When the dll name of the driver is not of 8.3-format
 '      the modification of the FileName is needed
 '
-' This is to work-around a bug in the WiX Toolset, see
+' This is to work-around an oversight in Windows Installer, see
 ' http://wixtoolset.org/issues/1422/
 '
 ' We remove the short name from the filename field in the File-table
 ' speaking, that makes the contents of the table invalid, because a short
 ' name is mandatory, but Windows Installer seems nevertheless install it
 ' just fine.
-'
-option Explicit
 
-Const msiOpenDatabaseModeTransact = 1
+Option Explicit
 
+Const msiOpenDatabaseModeTransact = 1
 Const msiViewModifyInsert = 1
 Const msiViewModifyUpdate = 2
+Const query = "SELECT * FROM File"
 
-Dim msiPath : msiPath = Wscript.Arguments(0)
+Dim installer, database
+Dim view, record
+Dim pos, filename
 
-Dim installer
 Set installer = Wscript.CreateObject("WindowsInstaller.Installer")
-Dim database
-Set database = installer.OpenDatabase(msiPath, msiOpenDatabaseModeTransact)
-
-Dim query
-query = "Select * FROM File"
-Dim view
+Set database = installer.OpenDatabase(WScript.Arguments(0), _
+                                      msiOpenDatabaseModeTransact)
 Set view = database.OpenView(query)
 view.Execute
-Dim record
+
 Set record = view.Fetch
-Dim gFile, pos
-Do While not record Is Nothing
-gFile = record.StringData(1)
-If Left(gFile, 8) = "psqlodbc" Then
-   gFile = record.StringData(3)
-   ' Check if the FileName field is ShortName|LongName
-   pos = InStr(record.StringData(3), "|")
-   If pos > 0 Then
-       ' Omit the ShortName part
-       gFile = Mid(record.StringData(3), pos + 1)
-       WScript.echo record.StringData(3) & " -> " & gFile
-       ' And update the field
-       record.StringData(3) = gFile
+Do While Not record Is Nothing
+
+   filename = record.StringData(3)
+   pos = InStr(filename, "|psqlodbc")
+
+   If (pos > 0) Then
+
+       ' Remove the ShortName part
+       filename = Mid(filename, pos + 1)
+       WScript.echo record.StringData(3) & " -> " & filename
+
+       record.StringData(3) = filename
        view.Modify msiViewModifyUpdate, record
+
    End If
-End If
-Set record = view.Fetch
+
+   Set record = view.Fetch
+
 Loop
 
 database.Commit
index b49b92c1536447897ed454d484f040b0f9a7db65..60075cfd8c97af8b0a4a0e6b97717299776aa819 100644 (file)
 <?xml version="1.0" encoding="utf-8"?>
-<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
+     xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
 
-<!-- Default to x86 platform -->
-<?ifndef var.Platform ?>
-  <?define Platform = "x86" ?>
-<?else?>
-  <?if $(var.Platform) != x64 and $(var.Platform) != x86 ?>
-    <?error Invalid Platform variable ?>
-  <?endif?>
-<?endif?>
-
-<?ifndef var.INSTBASE ?>
-  <?define INSTBASE = $(var.Platform) ?>
-<?endif?>
-
-<?if $(var.Platform) = x64 ?>
+<?if $(sys.BUILDARCH) = x64 ?>
+  <?define Platform = "x64" ?>
   <?define PKGNAME = "psqlODBC_x64" ?>
-  <?define BIT64 = "yes" ?>
-  <?define PGFOLDER = "ProgramFiles64Folder" ?>
-  <?define PRODID = "3E42F836-9204-4c42-B3C3-8680A0434875" ?>
   <?define CIDREG = "4D361F28-8F75-4c86-9A37-6C279967413D" ?>
   <?define CIDDOC = "0C745A85-4E55-4bab-BBF1-DCF51D92FCC5" ?>
   <?define CIDSMD = "{E6410EE8-96DC-4d84-8D07-94F8093BF3EF}" ?>
   <?define UPGCOD = "BBD29DF5-89F6-4b8b-BDC9-C3EA3A4AFDBB" ?>
   <?define ALLUSERS = "1" ?>
-<?else?>
+<?elseif $(sys.BUILDARCH) = x86 ?>
+  <?define Platform = "x86" ?>
   <?define PKGNAME = "psqlODBC" ?>
-  <?define BIT64 = "no" ?>
-  <?define PGFOLDER = "ProgramFilesFolder" ?>
-  <?define PRODID = "838E187D-8B7A-473d-B93C-C8E970B15D2B" ?>
   <?define CIDREG = "4F0C04EB-ADCB-4fa8-B6A3-E9F74EA693F8" ?>
   <?define CIDDOC = "89DDBC52-9F0D-4846-91DC-09EECC87E42E" ?>
   <?define CIDSMD = "{22288E09-B3B6-4181-907F-676099C20125}" ?>
   <?define UPGCOD = "24BCA538-75A2-4a7f-B236-C99EFC2145DE" ?>
   <?define ALLUSERS = "1" ?>
+<?else?><!-- sys.BUILDARCH -->
+  <?error Invalid build architecture ?>
+<?endif?>
+
+<?ifndef var.INSTBASE ?>
+  <?define INSTBASE = $(Platform) ?>
 <?endif?>
 
-<?define MERGEM = "$(var.INSTBASE)\psqlodbc_$(var.Platform).msm" ?>
+<?define MERGEM = "$(INSTBASE)\psqlodbc_$(Platform).msm" ?>
 
 <!-- Product details -->
 
-  <Product
+  <Package
     Manufacturer="PostgreSQL Global Development Group"
-    Id="$(var.PRODUCTCODE)"
-    UpgradeCode="$(var.UPGCOD)"
-    Name="$(var.PKGNAME)"
-    Version="$(var.VERSION)"
+    UpgradeCode="$(UPGCOD)"
+    Name="$(PKGNAME)"
+    Version="$(VERSION)"
+    Codepage="1252"
+    InstallerVersion="300"
+    Compressed="yes"
     Language="1033">
 
 <!-- Package details -->
 
-    <Package
+    <SummaryInformation
+      Codepage="1252"
       Keywords="PostgreSQL, ODBC"
-      Comments="PostgreSQL ODBC Driver"
-      Manufacturer="PostgreSQL Global Development Group"
-      InstallerVersion="300"
-      Platform="$(var.Platform)"
-      Languages="1033"
-      Compressed="yes"
-      SummaryCodepage="1252" />
+      Comments="PostgreSQL ODBC Driver" />
 
 <!-- Directories -->
 
-    <Directory Id="TARGETDIR" Name="SourceDir">
-      <Directory Id="$(var.PGFOLDER)" Name="PFiles">
-        <Directory Id="BASEDIR" Name="psqlODBC">
-          <Directory Id="SUBLOC" Name="$(var.SUBLOC)">
-            <Directory Id="BINDIR" Name="bin">
-              <Component Id="registration" Guid="$(var.CIDREG)" Win64="$(var.BIT64)">
-                <RegistryValue KeyPath="yes" Type="string" Root="HKLM" Key="Software\$(var.PKGNAME)" Name="Version" Value="$(var.VERSION)" />
-              </Component>
-              <Merge Id="psqlodbcm" DiskId="1" Language="1033" SourceFile="$(var.MERGEM)" />
-            </Directory>
-            <Directory Id="DOCSDIR" Name="docs">
-              <Component Id="docs" Guid="$(var.CIDDOC)" Win64="$(var.BIT64)">
-                <File Id="docs.README.txt" Name="README.txt" DiskId="1" Source="../docs/README.txt" KeyPath="yes" />
-                <File Id="docs.config.html" Name="config.html" DiskId="1" Source="../docs/config.html" />
-                <File Id="docs.config_opt.html" Name="config-opt.html" DiskId="1" Source="../docs/config-opt.html" />
-                <File Id="docs.release.html" Name="release.html" DiskId="1" Source="../docs/release.html" />
-                <File Id="docs.release_7.3.html" Name="release-7.3.html" DiskId="1" Source="../docs/release-7.3.html" />
-                <File Id="docs.unix_compilation.html" Name="unix-compilation.html" DiskId="1" Source="../docs/unix-compilation.html" />
-                <File Id="docs.win32_compilation.html" Name="win32-compilation.html" DiskId="1" Source="../docs/win32-compilation.html" />
-                <File Id="docs.editConfiguration.jpg" Name="editConfiguration.jpg" DiskId="1" Source="../docs/editConfiguration.jpg" />
-
-                <!-- <Shortcut Id="docs.index.html" Directory="SMDir" Name="Documentation index" Description="psqlODBC documentation, HOWTOs and FAQs" Advertise="yes" Show="normal" /> -->
-              </Component>
-            </Directory>
+    <StandardDirectory Id="ProgramFiles6432Folder">
+      <Directory Id="BASEDIR" Name="psqlODBC">
+        <Directory Id="SUBLOC" Name="$(SUBLOC)">
+          <Directory Id="BINDIR" Name="bin">
+            <Component Id="registration" Guid="$(CIDREG)">
+              <RegistryValue KeyPath="yes" Type="string" Root="HKLM" Key="Software\$(PKGNAME)" Name="Version" Value="$(VERSION)" />
+            </Component>
+            <Merge Id="psqlodbcm" DiskId="1" Language="1033" SourceFile="$(MERGEM)" />
           </Directory>
-        </Directory>
-      </Directory>
-      <Directory Id="ProgramMenuFolder" Name="." SourceName="Programs">
-        <Directory Id="SMDir" Name="$(var.PKGNAME)">
-            <Component Id="smdir" Guid="$(var.CIDSMD)" Win64="$(var.BIT64)">
-                <RegistryValue KeyPath="yes" Type="string" Root="HKCU" Key="Software\$(var.PKGNAME)\SMDir Created" Value="y" />
-                <RemoveFolder Id="SMDir" On="uninstall" />
+          <Directory Id="DOCSDIR" Name="docs" FileSource="../docs">
+            <Component Id="docs" Guid="$(CIDDOC)">
+              <File Name="README.txt" KeyPath="yes" />
+              <File Name="config.html" />
+              <File Name="config-opt.html" />
+              <File Name="release.html" />
+              <File Name="release-7.3.html" />
+              <File Name="unix-compilation.html" />
+              <File Name="win32-compilation.html" />
+              <File Name="editConfiguration.jpg" />
+
+              <!-- <Shortcut Id="docs.index.html" Directory="SMDir" Name="Documentation index" Description="psqlODBC documentation, HOWTOs and FAQs" Advertise="yes" Show="normal" /> -->
             </Component>
+          </Directory>
         </Directory>
       </Directory>
-    </Directory>
+    </StandardDirectory>
+    <StandardDirectory Id="ProgramMenuFolder">
+      <Directory Id="SMDir" Name="$(PKGNAME)">
+        <Component Id="smdir" Guid="$(CIDSMD)">
+          <RegistryValue KeyPath="yes" Type="string" Root="HKCU" Key="Software\$(PKGNAME)\SMDir Created" Value="y" />
+          <RemoveFolder Id="SMDir" On="uninstall" />
+        </Component>
+      </Directory>
+    </StandardDirectory>
 
 <!-- Features -->
 
-    <Feature Id="psqlodbc" Title="$(var.PKGNAME)" Level="1" Description="psqlODBC - The PostgreSQL ODBC Driver" ConfigurableDirectory="BASEDIR" Display="expand">
+    <Feature Id="psqlodbc" Title="$(PKGNAME)" Level="1" Description="psqlODBC - The PostgreSQL ODBC Driver" ConfigurableDirectory="BASEDIR" Display="expand">
       <Feature Id="binaries" Title="ODBC Driver" Level="1" Description="The ODBC driver and supporting libraries.">
         <ComponentRef Id="registration" />
         <MergeRef Id="psqlodbcm" />
       </Feature>
 
     </Feature>
-    <Media Id="1" EmbedCab="yes" Cabinet="psqlodbc.cab"/>
-
-<!-- Properties -->
-
-    <Property Id="ALLUSERS">$(var.ALLUSERS)</Property>
-    <Property Id="WIXUI_INSTALLDIR" Value="BASEDIR" />
+    <Media Id="1" EmbedCab="yes" Cabinet="psqlodbc.cab" CompressionLevel="high"/>
 
 <!-- UI -->
 
-     <UIRef Id="WixUI_FeatureTree" />
-     <WixVariable Id="WixUILicenseRtf" Value="lgpl.rtf" />
-     <WixVariable Id="WixUIDialogBmp" Value="background.bmp" />
-     <WixVariable Id="WixUIBannerBmp" Value="banner.bmp" />
+    <ui:WixUI Id="WixUI_FeatureTree" InstallDirectory="BASEDIR" />
+    <WixVariable Id="WixUILicenseRtf" Value="lgpl.rtf" />
+    <WixVariable Id="WixUIDialogBmp" Value="background.bmp" />
+    <WixVariable Id="WixUIBannerBmp" Value="banner.bmp" />
 
 <!-- Upgrade -->
-    <Upgrade Id="$(var.UPGCOD)">
-      <UpgradeVersion OnlyDetect='yes' Property='SELFFOUND'
-               Minimum="$(var.VERSION)" IncludeMinimum='yes'
-               Maximum="$(var.VERSION)" IncludeMaximum='yes' />
-      <UpgradeVersion OnlyDetect='yes' Property='NEWERFOUND'
-               Minimum="$(var.VERSION)" IncludeMinimum='no' />
-      <UpgradeVersion OnlyDetect='no' Property='UPGRADEFOUND'
-                    Minimum='8.3.0' IncludeMinimum='yes'
-               Maximum="$(var.VERSION)" IncludeMaximum='no' />
-    </Upgrade>
-
-    <CustomAction Id='AlreadyUpdated'
-                Error="the same version of [ProductName] is already installed" />
-    <CustomAction Id='NoDowngrade'
-                Error="a new version of [ProductName] is already installed" />
-    <CustomAction Id='NoMinorUpgrade'
-                Error="REINSTALL unavailable. Major upgrade is needed." />
-    <CustomAction Id='NoReinstall'
-                Error="REINSTALL unavailable. Install the package first." />
-
-  <InstallExecuteSequence>
-    <Custom Action='AlreadyUpdated' After='FindRelatedProducts'>SELFFOUND AND NOT Installed</Custom>
-    <Custom Action='NoDowngrade' After='FindRelatedProducts'>NEWERFOUND AND NOT Installed</Custom>
-    <Custom Action='NoReinstall' Before='ValidateProductID'>REINSTALLMODE AND NOT Installed</Custom>
-    <Custom Action='NoMinorUpgrade' After='FindRelatedProducts'>UPGRADEFOUND AND REINSTALLMODE</Custom>
-    <RemoveExistingProducts After='InstallFinalize'>UPGRADEFOUND AND NOT Installed</RemoveExistingProducts>
-  </InstallExecuteSequence>
-  </Product>
-</Wix>
+
+    <MajorUpgrade
+      DowngradeErrorMessage="A newer version of [ProductName] is already installed"
+      Schedule="afterInstallInitialize" />
+  </Package>
+</Wix>
\ No newline at end of file
index 1edbf1e43f5b42f32c2ed005108a1e1c70a95744..f2cd82ea4ba8dae9dec628b04315af24a42dfc5d 100644 (file)
 <?xml version="1.0" encoding="utf-8"?>
-<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
-
-<!-- Default to x86 platform -->
-<?ifndef var.Platform ?>
-  <?define Platform = "x86" ?>
-<?else?>
-  <?if $(var.Platform) != x64 and $(var.Platform) != x86 ?>
-    <?error Invalid Platform variable ?>
-  <?endif?>
-<?endif?>
+<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
 
 <?ifndef var.BINBASE ?>
   <?define BINBASE = ".." ?>
 <?endif?>
 
-<?if $(var.Platform) = x64 ?>
-  <?define ModuleName = "psqlODBC_$(var.Platform)" ?>
+<?if $(sys.BUILDARCH) = x64 ?>
+  <?define Platform = "x64" ?>
+  <?define ModuleName = "psqlODBC_x64" ?>
   <?define BIT64 = "yes" ?>
   <?define ANSIFOLDER = "x64_ANSI_Release" ?>
   <?define UNICODEFOLDER = "x64_Unicode_Release" ?>
   <?define Module_PackageId = "970B6E07-7105-4d66-80FA-9E208952FB96" ?>
-  <?define CIDPFILES = "5C9A19B5-D7C6-4bb4-BBBC-88C2A67A59B0" ?>
-  <?define CIDXFILES = "121A6C41-2B8F-463D-BA84-6BF36701428A" ?>
   <?define InstallerVersion = "300" ?>
 <?if $(env.PROCESSOR_ARCHITECTURE) = "AMD64" ?>
   <?define SysFolder = "$(env.SystemRoot)\system32" ?>
 <?else?>
   <?define SysFolder = "$(env.SystemRoot)\sysnative" ?>
 <?endif?>
-<?else?>
+<?elseif $(sys.BUILDARCH) = x86 ?>
+  <?define Platform = "x86" ?>
   <?define ModuleName = "psqlODBC" ?>
   <?define BIT64 = "no" ?>
   <?define ANSIFOLDER = "x86_ANSI_Release" ?>
   <?define UNICODEFOLDER = "x86_Unicode_Release" ?>
   <?define Module_PackageId = "ACF10866-5C01-46f0-90F0-D5618638CA48" ?>
-  <?define CIDPFILES = "00A1ACE3-B7C2-41b8-A1F1-DB565990DA4E" ?>
-  <?define CIDXFILES = "49933A1E-4350-437C-B8D5-E96AA5D61139" ?>
   <?define InstallerVersion = "150" ?>
 <?if $(env.PROCESSOR_ARCHITECTURE) = "AMD64" ?>
   <?define SysFolder = "$(env.SystemRoot)\syswow64" ?>
 <?else?>
   <?define SysFolder = "$(env.SystemRoot)\system32" ?>
 <?endif?>
+<?else?><!-- sys.BUILDARCH -->
+  <?error Invalid build architecture ?>
 <?endif?>
 
   <Module
-    Id="$(var.ModuleName)"
-    Version="$(var.VERSION)"
+    Id="$(ModuleName)"
+    Guid="$(Module_PackageId)"
+    Version="$(VERSION)"
+    InstallerVersion="$(InstallerVersion)"
     Language="1033">
 
-    <Package
-      Id="$(var.Module_PackageId)"
+    <SummaryInformation
       Description="PostgreSQL ODBC Driver"
       Keywords="PostgreSQL, ODBC"
       Manufacturer="PostgreSQL Global Development Group"
-      InstallerVersion="$(var.InstallerVersion)"
-      Platform="$(var.Platform)"
-      Languages="1033"
-      SummaryCodepage="1252" />
+      Codepage="1252" />
 
-    <Directory Id="TARGETDIR" Name="SourceDir">
-      <Directory Id="BINDIR" Name=".">
-        <Component Id="psqlodbc.files" Guid="$(var.CIDPFILES)" Win64="$(var.BIT64)">
+    <!-- Avoid WIX0267 with naked files in a merge module -->
+    <Directory Id="INSTALLFOLDER" />
 
-          <!-- PostgreSQL -->
-          <File Id="psqlodbc30a.dll" Name="psqlodbc30a.dll" Source="$(var.BINBASE)/$(var.ANSIFOLDER)/psqlodbc30a.dll" />
-<?if $(var.NoPDB) != True ?>
-          <File Id="psqlodbc30a.pdb" Name="psqlodbc30a.pdb" Source="$(var.BINBASE)/$(var.ANSIFOLDER)/psqlodbc30a.pdb" />
-<?endif?>
-          <File Id="psqlodbc35w.dll" Name="psqlodbc35w.dll" Source="$(var.BINBASE)/$(var.UNICODEFOLDER)/psqlodbc35w.dll" />
-<?if $(var.NoPDB) != True ?>
-          <File Id="psqlodbc35w.pdb" Name="psqlodbc35w.pdb" Source="$(var.BINBASE)/$(var.UNICODEFOLDER)/psqlodbc35w.pdb" />
-<?endif?>
-          <File Id="pgenlist.dll" Name="pgenlist.dll" Source="$(var.BINBASE)/$(var.UNICODEFOLDER)/pgenlist.dll" />
-<?if $(var.NoPDB) != True ?>
-          <File Id="pgenlist.pdb" Name="pgenlist.pdb" Source="$(var.BINBASE)/$(var.UNICODEFOLDER)/pgenlist.pdb" />
-<?endif?>
-          <File Id="pgenlista.dll" Name="pgenlista.dll" Source="$(var.BINBASE)/$(var.ANSIFOLDER)/pgenlista.dll" />
-<?if $(var.NoPDB) != True ?>
-          <File Id="pgenlista.pdb" Name="pgenlista.pdb" Source="$(var.BINBASE)/$(var.ANSIFOLDER)/pgenlista.pdb" />
-<?endif?>
-   <!-- MSVC Runtime -->
-<?if "$(var.PODBCMSVCDLL)" != "" ?>
-          <File Source="$(var.PODBCMSVCDLL)" />
-<?endif?>
-<?if "$(var.PODBCMSVPDLL)" != "" ?>
-          <File Source="$(var.PODBCMSVPDLL)" />
-<?endif?>
-<?if "$(var.PODBCMSVCSYS)" != "" ?>
-          <File Source="$(var.SysFolder)\$(var.PODBCMSVCSYS)" />
-<?endif?>
-<?if "$(var.PODBCMSVPSYS)" != "" ?>
-          <File Source="$(var.SysFolder)\$(var.PODBCMSVPSYS)" />
-<?endif?>
-<?if "$(var.LIBPQMSVCDLL)" != "" ?>
-          <File Source="$(var.LIBPQMSVCDLL)" />
-<?endif?>
-<?if "$(var.LIBPQMSVCSYS)" != "" ?>
-          <File Source="$(var.SysFolder)\$(var.LIBPQMSVCSYS)" />
-<?endif?>
+    <!-- PostgreSQL -->
+    <File Name="psqlodbc30a.dll" Source="$(BINBASE)\$(ANSIFOLDER)\psqlodbc30a.dll">
+      <ODBCDriver Id="Psqlodbc_9.0_Driver_ANSI" Name="PostgreSQL ANSI($(Platform))">
+        <Property Id="CPTimeout" Value="60" />
+      </ODBCDriver>
+      <ODBCDriver Id="Psqlodbc_11_newid_Driver_ANSI" Name="PostgreSQL ANSI">
+        <Property Id="CPTimeout" Value="60" />
+      </ODBCDriver>
+    </File>
+    <File Name="pgenlista.dll" Source="$(BINBASE)\$(ANSIFOLDER)\pgenlista.dll" />
+<?if $(NoPDB) != True ?>
+    <File Name="psqlodbc30a.pdb" Source="$(BINBASE)\$(ANSIFOLDER)\psqlodbc30a.pdb" />
+    <File Name="pgenlista.pdb" Source="$(BINBASE)\$(ANSIFOLDER)\pgenlista.pdb" />
+<?endif ?>
+    <File Name="psqlodbc35w.dll" Source="$(BINBASE)\$(UNICODEFOLDER)\psqlodbc35w.dll">
+      <ODBCDriver Id="Psqlodbc_9.0_Driver" Name="PostgreSQL Unicode($(Platform))">
+        <Property Id="CPTimeout" Value="60" />
+      </ODBCDriver>
+      <ODBCDriver Id="Psqlodbc_11_newid_Driver" Name="PostgreSQL Unicode">
+        <Property Id="CPTimeout" Value="60" />
+      </ODBCDriver>
+    </File>
+    <File Name="pgenlist.dll" Source="$(BINBASE)\$(UNICODEFOLDER)\pgenlist.dll" />
+<?if $(NoPDB) != True ?>
+    <File Name="psqlodbc35w.pdb" Source="$(BINBASE)\$(UNICODEFOLDER)\psqlodbc35w.pdb" />
+    <File Name="pgenlist.pdb" Source="$(BINBASE)\$(UNICODEFOLDER)\pgenlist.pdb" />
+<?endif ?>
 
-          <File Id="libpq.dll" Name="libpq.dll" Source="$(var.LIBPQBINDIR)\libpq.dll" KeyPath="yes" />
+    <!-- MSVC Runtime -->
+<?if "$(PODBCMSVCDLL)" != "" ?>
+    <File Source="$(PODBCMSVCDLL)" />
+<?endif ?>
+<?if "$(PODBCMSVPDLL)" != "" ?>
+    <File Source="$(PODBCMSVPDLL)" />
+<?endif ?>
+<?if "$(PODBCMSVCSYS)" != "" ?>
+    <File Source="$(SysFolder)\$(PODBCMSVCSYS)" />
+<?endif ?>
+<?if "$(PODBCMSVPSYS)" != "" ?>
+    <File Source="$(SysFolder)\$(PODBCMSVPSYS)" />
+<?endif ?>
+<?if "$(LIBPQMSVCDLL)" != "" ?>
+    <File Source="$(LIBPQMSVCDLL)" />
+<?endif ?>
+<?if "$(LIBPQMSVCSYS)" != "" ?>
+    <File Source="$(SysFolder)\$(LIBPQMSVCSYS)" />
+<?endif ?>
 
-          <!-- libpq related -->
-<?if "$(var.LIBPQMEM0)" != "" ?>
-          <File Source="$(var.LIBPQBINDIR)\$(var.LIBPQMEM0)" />
+    <!-- libpq -->
+    <File Source="$(LIBPQBINDIR)\libpq.dll" />
+<?if "$(LIBPQMEM0)" != "" ?>
+    <File Source="$(LIBPQBINDIR)\$(LIBPQMEM0)" />
 <?endif ?>
-<?if "$(var.LIBPQMEM1)" != "" ?>
-          <File Source="$(var.LIBPQBINDIR)\$(var.LIBPQMEM1)" />
+<?if "$(LIBPQMEM1)" != "" ?>
+    <File Source="$(LIBPQBINDIR)\$(LIBPQMEM1)" />
 <?endif ?>
-<?if "$(var.LIBPQMEM2)" != "" ?>
-          <File Source="$(var.LIBPQBINDIR)\$(var.LIBPQMEM2)" />
+<?if "$(LIBPQMEM2)" != "" ?>
+    <File Source="$(LIBPQBINDIR)\$(LIBPQMEM2)" />
 <?endif ?>
-<?if "$(var.LIBPQMEM3)" != "" ?>
-          <File Source="$(var.LIBPQBINDIR)\$(var.LIBPQMEM3)" />
+<?if "$(LIBPQMEM3)" != "" ?>
+    <File Source="$(LIBPQBINDIR)\$(LIBPQMEM3)" />
 <?endif ?>
-<?if "$(var.LIBPQMEM4)" != "" ?>
-          <File Source="$(var.LIBPQBINDIR)\$(var.LIBPQMEM4)" />
+<?if "$(LIBPQMEM4)" != "" ?>
+    <File Source="$(LIBPQBINDIR)\$(LIBPQMEM4)" />
 <?endif ?>
-<?if "$(var.LIBPQMEM5)" != "" ?>
-          <File Source="$(var.LIBPQBINDIR)\$(var.LIBPQMEM5)" />
+<?if "$(LIBPQMEM5)" != "" ?>
+    <File Source="$(LIBPQBINDIR)\$(LIBPQMEM5)" />
 <?endif ?>
-<?if "$(var.LIBPQMEM6)" != "" ?>
-          <File Source="$(var.LIBPQBINDIR)\$(var.LIBPQMEM6)" />
+<?if "$(LIBPQMEM6)" != "" ?>
+    <File Source="$(LIBPQBINDIR)\$(LIBPQMEM6)" />
 <?endif ?>
-<?if "$(var.LIBPQMEM7)" != "" ?>
-          <File Source="$(var.LIBPQBINDIR)\$(var.LIBPQMEM7)" />
+<?if "$(LIBPQMEM7)" != "" ?>
+    <File Source="$(LIBPQBINDIR)\$(LIBPQMEM7)" />
 <?endif ?>
-<?if "$(var.LIBPQMEM8)" != "" ?>
-          <File Source="$(var.LIBPQBINDIR)\$(var.LIBPQMEM8)" />
+<?if "$(LIBPQMEM8)" != "" ?>
+    <File Source="$(LIBPQBINDIR)\$(LIBPQMEM8)" />
 <?endif ?>
-<?if "$(var.LIBPQMEM9)" != "" ?>
-          <File Source="$(var.LIBPQBINDIR)\$(var.LIBPQMEM9)" />
+<?if "$(LIBPQMEM9)" != "" ?>
+    <File Source="$(LIBPQBINDIR)\$(LIBPQMEM9)" />
 <?endif ?>
 
-          <!-- Note, installing the driver properly (IE, using ODBCDriver) has
-               proven unreliable, so we install the registry keys manually
-               ourselves. On 64-bit Windows, however, we trust that ODBCDriver
-               works. Nowadays, it probably would be safe to use ODBCDriver on
-               all platforms, but no-one's gotten around to revisit this
-          -->
-<?if $(var.Platform) = x64 ?>
-          <ODBCDriver Id="Psqlodbc_9.0_Driver_ANSI" Name="PostgreSQL ANSI($(var.Platform))" File="psqlodbc30a.dll" />
-          <ODBCDriver Id="Psqlodbc_9.0_Driver" Name="PostgreSQL Unicode($(var.Platform))" File="psqlodbc35w.dll" />
-          <ODBCDriver Id="Psqlodbc_11_newid_Driver_ANSI" Name="PostgreSQL ANSI" File="psqlodbc30a.dll" />
-          <ODBCDriver Id="Psqlodbc_11_newid_Driver" Name="PostgreSQL Unicode" File="psqlodbc35w.dll" />
-          <RegistryValue Id="psqlodbc30a.reg.1" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL ANSI" Name="CPTimeout" Type="string" Value="60" />
-          <RegistryValue Id="psqlodbc35w.reg.1" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL Unicode" Name="CPTimeout" Type="string" Value="60" />
-          <RegistryValue Id="psqlodbc30a.reg.2" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL ANSI($(var.Platform))" Name="CPTimeout" Type="string" Value="60" />
-          <RegistryValue Id="psqlodbc35w.reg.2" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL Unicode($(var.Platform))" Name="CPTimeout" Type="string" Value="60" />
-<?else?>
-          <RegistryValue Id="psqlodbc30a.reg.1" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers" Name="PostgreSQL ANSI" Type="string" Value="Installed" />
-          <RegistryValue Id="psqlodbc30a.reg.2" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL ANSI" Name="APILevel" Type="string" Value="1" />
-          <RegistryValue Id="psqlodbc30a.reg.3" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL ANSI" Name="ConnectFunctions" Type="string" Value="YYN" />
-          <RegistryValue Id="psqlodbc30a.reg.4" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL ANSI" Name="Driver" Type="string" Value="[#psqlodbc30a.dll]" />
-          <RegistryValue Id="psqlodbc30a.reg.5" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL ANSI" Name="DriverODBCVer" Type="string" Value="03.50" />
-          <RegistryValue Id="psqlodbc30a.reg.6" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL ANSI" Name="FileUsage" Type="string" Value="0" />
-          <RegistryValue Id="psqlodbc30a.reg.7" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL ANSI" Name="Setup" Type="string" Value="[#psqlodbc30a.dll]" />
-          <RegistryValue Id="psqlodbc30a.reg.8" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL ANSI" Name="SQLLevel" Type="string" Value="1" />
-          <RegistryValue Id="psqlodbc30a.reg.9" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL ANSI" Name="UsageCount" Type="integer" Value="1" />
-          <RegistryValue Id="psqlodbc30a.reg.10" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL ANSI" Name="CPTimeout" Type="string" Value="60" />
-
-          <RegistryValue Id="psqlodbc35w.reg.1" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers" Name="PostgreSQL Unicode" Type="string" Value="Installed" />
-          <RegistryValue Id="psqlodbc35w.reg.2" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL Unicode" Name="APILevel" Type="string" Value="1" />
-          <RegistryValue Id="psqlodbc35w.reg.3" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL Unicode" Name="ConnectFunctions" Type="string" Value="YYN" />
-          <RegistryValue Id="psqlodbc35w.reg.4" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL Unicode" Name="Driver" Type="string" Value="[#psqlodbc35w.dll]" />
-          <RegistryValue Id="psqlodbc35w.reg.5" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL Unicode" Name="DriverODBCVer" Type="string" Value="03.51" />
-          <RegistryValue Id="psqlodbc35w.reg.6" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL Unicode" Name="FileUsage" Type="string" Value="0" />
-          <RegistryValue Id="psqlodbc35w.reg.7" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL Unicode" Name="Setup" Type="string" Value="[#psqlodbc35w.dll]" />
-          <RegistryValue Id="psqlodbc35w.reg.8" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL Unicode" Name="SQLLevel" Type="string" Value="1" />
-          <RegistryValue Id="psqlodbc35w.reg.9" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL Unicode" Name="UsageCount" Type="integer" Value="1" />
-          <RegistryValue Id="psqlodbc35w.reg.10" Root="HKLM" Key="SOFTWARE\ODBC\ODBCINST.INI\PostgreSQL Unicode" Name="CPTimeout" Type="string" Value="60" />
-<?endif?>
-        </Component>
-   <!--
-       MSDTC runs in 64bit mode on 64bit machines and 32bit mode on
-       32bit machines. We had better register the XA DLL on 
-       installation.
-   --> 
-        <Component Id="pgxalib.files" Guid="$(var.CIDXFILES)" Win64="$(var.BIT64)">
-<?if $(var.BIT64) = no ?>
-     <Condition>
-       <![CDATA[NOT VersionNT64]]>
-     </Condition>
-<?endif?>
-          <File Id="pgxalib.dll" Name="pgxalib.dll" Source="$(var.BINBASE)/$(var.UNICODEFOLDER)/pgxalib.dll" />
-          <RegistryValue Id="pgxalib.reg.1" Root="HKLM" Key="SOFTWARE\Microsoft\MSDTC\XADLL" Name="pgxalib.dll" Type="string" Value="[#pgxalib.dll]" />
-   </Component>
-      </Directory>
-    </Directory>
+    <!-- MSDTC runs in 64bit mode on 64bit machines and 32bit mode on
+         32bit machines. Install the XA DLL only from a native package.
+    -->
+    <Component Id="pgxalib.files" Condition='"$(sys.BUILDARCHSHORT)"="X64" OR NOT VersionNT64'>
+      <File Name="pgxalib.dll" Source="$(BINBASE)/$(UNICODEFOLDER)/pgxalib.dll" />
+      <RegistryValue Id="pgxalib.reg.1" Root="HKLM" Key="SOFTWARE\Microsoft\MSDTC\XADLL" Name="pgxalib.dll" Type="string" Value="[#pgxalib.dll]" />
+    </Component>
 
   </Module>
-</Wix>
+</Wix>
\ No newline at end of file