Skip to content

Commit 7da4711

Browse files
authored
Use WiX 5 (#66)
* 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
1 parent 62ef077 commit 7da4711

File tree

6 files changed

+200
-300
lines changed

6 files changed

+200
-300
lines changed

.github/workflows/main.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,12 @@ jobs:
275275
with:
276276
arch: x86
277277

278+
- name: Install WiX
279+
shell: cmd
280+
run: |
281+
dotnet tool install --global wix
282+
wix extension add --global WixToolset.UI.wixext
283+
278284
- name: build psqlodbc standard
279285
shell: powershell
280286
working-directory: psqlodbc

installer/README.txt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
This directory contains the psqlODBC installer for Windows. To build the
2-
installer, you will need a copy of WiX installed somewhere in your system
3-
path. The installer has been tested with WiX version 3.0.2420 and WiX 3.8 at
4-
the time writing.
2+
installer, you will need a copy of WiX installed. The installer has been
3+
tested with WiX version 5.0.2 at the time of writing.
54

65
WiX may be downloaded from:
76

8-
http://wix.codeplex.com/
7+
http://wixtoolset.org/
8+
9+
In addition to the base package, the UI extension is required:
10+
11+
dotnet tool install --global wix
12+
wix extension add --global WixToolset.UI.wixext
913

1014

1115
HOW TO BUILD

installer/buildInstallers.ps1

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -256,46 +256,31 @@ function buildInstaller([string]$CPUTYPE)
256256

257257
[string []]$libpqRelArgs=@()
258258
for ($i=0; $i -lt $maxmem; $i++) {
259-
$libpqRelArgs += ("-dLIBPQMEM$i=" + $libpqmem[$i])
259+
$libpqRelArgs += "-d", ("LIBPQMEM$i=" + $libpqmem[$i])
260260
}
261261

262262
if (-not(Test-Path -Path $CPUTYPE)) {
263263
New-Item -ItemType directory -Path $CPUTYPE | Out-Null
264264
}
265265

266-
$PRODUCTCODE = [GUID]::NewGuid()
267-
Write-Host "PRODUCTCODE: $PRODUCTCODE"
268-
269266
try {
270267
pushd "$scriptPath"
271268

272269
Write-Host ".`nBuilding psqlODBC/$SUBLOC merge module..."
273270
$BINBASE = GetObjbase ".."
274271
$INSTBASE = GetObjbase ".\$CPUTYPE" "installer\$CPUTYPE"
275-
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
272+
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
276273
if ($LASTEXITCODE -ne 0) {
277274
throw "Failed to build merge module"
278275
}
279276

280-
Write-Host ".`nLinking psqlODBC merge module..."
281-
light -sval -nologo -o $INSTBASE\psqlodbc_$CPUTYPE.msm $INSTBASE\psqlodbcm.wixobj
282-
if ($LASTEXITCODE -ne 0) {
283-
throw "Failed to link merge module"
284-
}
285-
286277
Write-Host ".`nBuilding psqlODBC installer database..."
287278

288-
candle -nologo "-dPlatform=$CPUTYPE" "-dVERSION=$VERSION" "-dSUBLOC=$SUBLOC" "-dPRODUCTCODE=$PRODUCTCODE" "-dINSTBASE=$INSTBASE" -o $INSTBASE\psqlodbc.wixobj psqlodbc_cpu.wxs
279+
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
289280
if ($LASTEXITCODE -ne 0) {
290281
throw "Failed to build installer database"
291282
}
292283

293-
Write-Host ".`nLinking psqlODBC installer database..."
294-
light -sval -nologo -ext WixUIExtension -cultures:en-us -o $INSTBASE\psqlodbc_$CPUTYPE.msi $INSTBASE\psqlodbc.wixobj
295-
if ($LASTEXITCODE -ne 0) {
296-
throw "Failed to link installer database"
297-
}
298-
299284
Write-Host ".`nModifying psqlODBC installer database..."
300285
cscript modify_msi.vbs $INSTBASE\psqlodbc_$CPUTYPE.msi
301286
if ($LASTEXITCODE -ne 0) {

installer/modify_msi.vbs

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,51 @@
22
' When the dll name of the driver is not of 8.3-format
33
' the modification of the FileName is needed
44
'
5-
' This is to work-around a bug in the WiX Toolset, see
5+
' This is to work-around an oversight in Windows Installer, see
66
' http://wixtoolset.org/issues/1422/
77
'
88
' We remove the short name from the filename field in the File-table
99
' of the two DLLs that need to be registered as ODBC drivers. Strictly
1010
' speaking, that makes the contents of the table invalid, because a short
1111
' name is mandatory, but Windows Installer seems nevertheless install it
1212
' just fine.
13-
'
14-
option Explicit
1513

16-
Const msiOpenDatabaseModeTransact = 1
14+
Option Explicit
1715

16+
Const msiOpenDatabaseModeTransact = 1
1817
Const msiViewModifyInsert = 1
1918
Const msiViewModifyUpdate = 2
19+
Const query = "SELECT * FROM File"
2020

21-
Dim msiPath : msiPath = Wscript.Arguments(0)
21+
Dim installer, database
22+
Dim view, record
23+
Dim pos, filename
2224

23-
Dim installer
2425
Set installer = Wscript.CreateObject("WindowsInstaller.Installer")
25-
Dim database
26-
Set database = installer.OpenDatabase(msiPath, msiOpenDatabaseModeTransact)
27-
28-
Dim query
29-
query = "Select * FROM File"
30-
Dim view
26+
Set database = installer.OpenDatabase(WScript.Arguments(0), _
27+
msiOpenDatabaseModeTransact)
3128
Set view = database.OpenView(query)
3229
view.Execute
33-
Dim record
30+
3431
Set record = view.Fetch
35-
Dim gFile, pos
36-
Do While not record Is Nothing
37-
gFile = record.StringData(1)
38-
If Left(gFile, 8) = "psqlodbc" Then
39-
gFile = record.StringData(3)
40-
' Check if the FileName field is ShortName|LongName
41-
pos = InStr(record.StringData(3), "|")
42-
If pos > 0 Then
43-
' Omit the ShortName part
44-
gFile = Mid(record.StringData(3), pos + 1)
45-
WScript.echo record.StringData(3) & " -> " & gFile
46-
' And update the field
47-
record.StringData(3) = gFile
32+
Do While Not record Is Nothing
33+
34+
filename = record.StringData(3)
35+
pos = InStr(filename, "|psqlodbc")
36+
37+
If (pos > 0) Then
38+
39+
' Remove the ShortName part
40+
filename = Mid(filename, pos + 1)
41+
WScript.echo record.StringData(3) & " -> " & filename
42+
43+
record.StringData(3) = filename
4844
view.Modify msiViewModifyUpdate, record
45+
4946
End If
50-
End If
51-
Set record = view.Fetch
47+
48+
Set record = view.Fetch
49+
5250
Loop
5351

5452
database.Commit

installer/psqlodbc_cpu.wxs

Lines changed: 65 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,92 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
2+
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"
3+
xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
34

4-
<!-- Default to x86 platform -->
5-
<?ifndef var.Platform ?>
6-
<?define Platform = "x86" ?>
7-
<?else?>
8-
<?if $(var.Platform) != x64 and $(var.Platform) != x86 ?>
9-
<?error Invalid Platform variable ?>
10-
<?endif?>
11-
<?endif?>
12-
13-
<?ifndef var.INSTBASE ?>
14-
<?define INSTBASE = $(var.Platform) ?>
15-
<?endif?>
16-
17-
<?if $(var.Platform) = x64 ?>
5+
<?if $(sys.BUILDARCH) = x64 ?>
6+
<?define Platform = "x64" ?>
187
<?define PKGNAME = "psqlODBC_x64" ?>
19-
<?define BIT64 = "yes" ?>
20-
<?define PGFOLDER = "ProgramFiles64Folder" ?>
21-
<?define PRODID = "3E42F836-9204-4c42-B3C3-8680A0434875" ?>
228
<?define CIDREG = "4D361F28-8F75-4c86-9A37-6C279967413D" ?>
239
<?define CIDDOC = "0C745A85-4E55-4bab-BBF1-DCF51D92FCC5" ?>
2410
<?define CIDSMD = "{E6410EE8-96DC-4d84-8D07-94F8093BF3EF}" ?>
2511
<?define UPGCOD = "BBD29DF5-89F6-4b8b-BDC9-C3EA3A4AFDBB" ?>
2612
<?define ALLUSERS = "1" ?>
27-
<?else?>
13+
<?elseif $(sys.BUILDARCH) = x86 ?>
14+
<?define Platform = "x86" ?>
2815
<?define PKGNAME = "psqlODBC" ?>
29-
<?define BIT64 = "no" ?>
30-
<?define PGFOLDER = "ProgramFilesFolder" ?>
31-
<?define PRODID = "838E187D-8B7A-473d-B93C-C8E970B15D2B" ?>
3216
<?define CIDREG = "4F0C04EB-ADCB-4fa8-B6A3-E9F74EA693F8" ?>
3317
<?define CIDDOC = "89DDBC52-9F0D-4846-91DC-09EECC87E42E" ?>
3418
<?define CIDSMD = "{22288E09-B3B6-4181-907F-676099C20125}" ?>
3519
<?define UPGCOD = "24BCA538-75A2-4a7f-B236-C99EFC2145DE" ?>
3620
<?define ALLUSERS = "1" ?>
21+
<?else?><!-- sys.BUILDARCH -->
22+
<?error Invalid build architecture ?>
23+
<?endif?>
24+
25+
<?ifndef var.INSTBASE ?>
26+
<?define INSTBASE = $(Platform) ?>
3727
<?endif?>
3828

39-
<?define MERGEM = "$(var.INSTBASE)\psqlodbc_$(var.Platform).msm" ?>
29+
<?define MERGEM = "$(INSTBASE)\psqlodbc_$(Platform).msm" ?>
4030

4131
<!-- Product details -->
4232

43-
<Product
33+
<Package
4434
Manufacturer="PostgreSQL Global Development Group"
45-
Id="$(var.PRODUCTCODE)"
46-
UpgradeCode="$(var.UPGCOD)"
47-
Name="$(var.PKGNAME)"
48-
Version="$(var.VERSION)"
35+
UpgradeCode="$(UPGCOD)"
36+
Name="$(PKGNAME)"
37+
Version="$(VERSION)"
38+
Codepage="1252"
39+
InstallerVersion="300"
40+
Compressed="yes"
4941
Language="1033">
5042

5143
<!-- Package details -->
5244

53-
<Package
45+
<SummaryInformation
46+
Codepage="1252"
5447
Keywords="PostgreSQL, ODBC"
55-
Comments="PostgreSQL ODBC Driver"
56-
Manufacturer="PostgreSQL Global Development Group"
57-
InstallerVersion="300"
58-
Platform="$(var.Platform)"
59-
Languages="1033"
60-
Compressed="yes"
61-
SummaryCodepage="1252" />
48+
Comments="PostgreSQL ODBC Driver" />
6249

6350
<!-- Directories -->
6451

65-
<Directory Id="TARGETDIR" Name="SourceDir">
66-
<Directory Id="$(var.PGFOLDER)" Name="PFiles">
67-
<Directory Id="BASEDIR" Name="psqlODBC">
68-
<Directory Id="SUBLOC" Name="$(var.SUBLOC)">
69-
<Directory Id="BINDIR" Name="bin">
70-
<Component Id="registration" Guid="$(var.CIDREG)" Win64="$(var.BIT64)">
71-
<RegistryValue KeyPath="yes" Type="string" Root="HKLM" Key="Software\$(var.PKGNAME)" Name="Version" Value="$(var.VERSION)" />
72-
</Component>
73-
<Merge Id="psqlodbcm" DiskId="1" Language="1033" SourceFile="$(var.MERGEM)" />
74-
</Directory>
75-
<Directory Id="DOCSDIR" Name="docs">
76-
<Component Id="docs" Guid="$(var.CIDDOC)" Win64="$(var.BIT64)">
77-
<File Id="docs.README.txt" Name="README.txt" DiskId="1" Source="../docs/README.txt" KeyPath="yes" />
78-
<File Id="docs.config.html" Name="config.html" DiskId="1" Source="../docs/config.html" />
79-
<File Id="docs.config_opt.html" Name="config-opt.html" DiskId="1" Source="../docs/config-opt.html" />
80-
<File Id="docs.release.html" Name="release.html" DiskId="1" Source="../docs/release.html" />
81-
<File Id="docs.release_7.3.html" Name="release-7.3.html" DiskId="1" Source="../docs/release-7.3.html" />
82-
<File Id="docs.unix_compilation.html" Name="unix-compilation.html" DiskId="1" Source="../docs/unix-compilation.html" />
83-
<File Id="docs.win32_compilation.html" Name="win32-compilation.html" DiskId="1" Source="../docs/win32-compilation.html" />
84-
<File Id="docs.editConfiguration.jpg" Name="editConfiguration.jpg" DiskId="1" Source="../docs/editConfiguration.jpg" />
85-
86-
<!-- <Shortcut Id="docs.index.html" Directory="SMDir" Name="Documentation index" Description="psqlODBC documentation, HOWTOs and FAQs" Advertise="yes" Show="normal" /> -->
87-
</Component>
88-
</Directory>
52+
<StandardDirectory Id="ProgramFiles6432Folder">
53+
<Directory Id="BASEDIR" Name="psqlODBC">
54+
<Directory Id="SUBLOC" Name="$(SUBLOC)">
55+
<Directory Id="BINDIR" Name="bin">
56+
<Component Id="registration" Guid="$(CIDREG)">
57+
<RegistryValue KeyPath="yes" Type="string" Root="HKLM" Key="Software\$(PKGNAME)" Name="Version" Value="$(VERSION)" />
58+
</Component>
59+
<Merge Id="psqlodbcm" DiskId="1" Language="1033" SourceFile="$(MERGEM)" />
8960
</Directory>
90-
</Directory>
91-
</Directory>
92-
<Directory Id="ProgramMenuFolder" Name="." SourceName="Programs">
93-
<Directory Id="SMDir" Name="$(var.PKGNAME)">
94-
<Component Id="smdir" Guid="$(var.CIDSMD)" Win64="$(var.BIT64)">
95-
<RegistryValue KeyPath="yes" Type="string" Root="HKCU" Key="Software\$(var.PKGNAME)\SMDir Created" Value="y" />
96-
<RemoveFolder Id="SMDir" On="uninstall" />
61+
<Directory Id="DOCSDIR" Name="docs" FileSource="../docs">
62+
<Component Id="docs" Guid="$(CIDDOC)">
63+
<File Name="README.txt" KeyPath="yes" />
64+
<File Name="config.html" />
65+
<File Name="config-opt.html" />
66+
<File Name="release.html" />
67+
<File Name="release-7.3.html" />
68+
<File Name="unix-compilation.html" />
69+
<File Name="win32-compilation.html" />
70+
<File Name="editConfiguration.jpg" />
71+
72+
<!-- <Shortcut Id="docs.index.html" Directory="SMDir" Name="Documentation index" Description="psqlODBC documentation, HOWTOs and FAQs" Advertise="yes" Show="normal" /> -->
9773
</Component>
74+
</Directory>
9875
</Directory>
9976
</Directory>
100-
</Directory>
77+
</StandardDirectory>
78+
<StandardDirectory Id="ProgramMenuFolder">
79+
<Directory Id="SMDir" Name="$(PKGNAME)">
80+
<Component Id="smdir" Guid="$(CIDSMD)">
81+
<RegistryValue KeyPath="yes" Type="string" Root="HKCU" Key="Software\$(PKGNAME)\SMDir Created" Value="y" />
82+
<RemoveFolder Id="SMDir" On="uninstall" />
83+
</Component>
84+
</Directory>
85+
</StandardDirectory>
10186

10287
<!-- Features -->
10388

104-
<Feature Id="psqlodbc" Title="$(var.PKGNAME)" Level="1" Description="psqlODBC - The PostgreSQL ODBC Driver" ConfigurableDirectory="BASEDIR" Display="expand">
89+
<Feature Id="psqlodbc" Title="$(PKGNAME)" Level="1" Description="psqlODBC - The PostgreSQL ODBC Driver" ConfigurableDirectory="BASEDIR" Display="expand">
10590
<Feature Id="binaries" Title="ODBC Driver" Level="1" Description="The ODBC driver and supporting libraries.">
10691
<ComponentRef Id="registration" />
10792
<MergeRef Id="psqlodbcm" />
@@ -113,47 +98,19 @@
11398
</Feature>
11499

115100
</Feature>
116-
<Media Id="1" EmbedCab="yes" Cabinet="psqlodbc.cab"/>
117-
118-
<!-- Properties -->
119-
120-
<Property Id="ALLUSERS">$(var.ALLUSERS)</Property>
121-
<Property Id="WIXUI_INSTALLDIR" Value="BASEDIR" />
101+
<Media Id="1" EmbedCab="yes" Cabinet="psqlodbc.cab" CompressionLevel="high"/>
122102

123103
<!-- UI -->
124104

125-
<UIRef Id="WixUI_FeatureTree" />
126-
<WixVariable Id="WixUILicenseRtf" Value="lgpl.rtf" />
127-
<WixVariable Id="WixUIDialogBmp" Value="background.bmp" />
128-
<WixVariable Id="WixUIBannerBmp" Value="banner.bmp" />
105+
<ui:WixUI Id="WixUI_FeatureTree" InstallDirectory="BASEDIR" />
106+
<WixVariable Id="WixUILicenseRtf" Value="lgpl.rtf" />
107+
<WixVariable Id="WixUIDialogBmp" Value="background.bmp" />
108+
<WixVariable Id="WixUIBannerBmp" Value="banner.bmp" />
129109

130110
<!-- Upgrade -->
131-
<Upgrade Id="$(var.UPGCOD)">
132-
<UpgradeVersion OnlyDetect='yes' Property='SELFFOUND'
133-
Minimum="$(var.VERSION)" IncludeMinimum='yes'
134-
Maximum="$(var.VERSION)" IncludeMaximum='yes' />
135-
<UpgradeVersion OnlyDetect='yes' Property='NEWERFOUND'
136-
Minimum="$(var.VERSION)" IncludeMinimum='no' />
137-
<UpgradeVersion OnlyDetect='no' Property='UPGRADEFOUND'
138-
Minimum='8.3.0' IncludeMinimum='yes'
139-
Maximum="$(var.VERSION)" IncludeMaximum='no' />
140-
</Upgrade>
141-
142-
<CustomAction Id='AlreadyUpdated'
143-
Error="the same version of [ProductName] is already installed" />
144-
<CustomAction Id='NoDowngrade'
145-
Error="a new version of [ProductName] is already installed" />
146-
<CustomAction Id='NoMinorUpgrade'
147-
Error="REINSTALL unavailable. Major upgrade is needed." />
148-
<CustomAction Id='NoReinstall'
149-
Error="REINSTALL unavailable. Install the package first." />
150-
151-
<InstallExecuteSequence>
152-
<Custom Action='AlreadyUpdated' After='FindRelatedProducts'>SELFFOUND AND NOT Installed</Custom>
153-
<Custom Action='NoDowngrade' After='FindRelatedProducts'>NEWERFOUND AND NOT Installed</Custom>
154-
<Custom Action='NoReinstall' Before='ValidateProductID'>REINSTALLMODE AND NOT Installed</Custom>
155-
<Custom Action='NoMinorUpgrade' After='FindRelatedProducts'>UPGRADEFOUND AND REINSTALLMODE</Custom>
156-
<RemoveExistingProducts After='InstallFinalize'>UPGRADEFOUND AND NOT Installed</RemoveExistingProducts>
157-
</InstallExecuteSequence>
158-
</Product>
159-
</Wix>
111+
112+
<MajorUpgrade
113+
DowngradeErrorMessage="A newer version of [ProductName] is already installed"
114+
Schedule="afterInstallInitialize" />
115+
</Package>
116+
</Wix>

0 commit comments

Comments
 (0)