1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 09:27:59 +00:00

Fix platform field in Windows on Arm installers.

I had previously left the platform field (in line 7 of the installer
database's SummaryInformation table) set at "x86" instead of any value
you might expect such as "Arm" or "Arm64", because I found that an MSI
file with either of the latter values was rejected by WoA's msiexec as
invalid.

It turns out this is because I _also_ needed to upgrade the installer
database schema version to a higher value than I even knew existed:
apparently the problem is that those platform fields aren't present in
the older schema. A test confirms that this works.

Unfortunately, WiX 3 doesn't actually know _how_ to write MSIs with
those platform values. But that's OK, because diffing the x86 and x64
MSIs against each other suggested that there were basically no other
changes in the database tables - so I can just generate the installer
as if for x64, and then rewrite that one field after installer
construction using GNOME msitools to take apart the binary file
structure and put it back together. (Those are the same tools I'm
using as part of my system for running WiX on Linux in the first
place.)

This commit introduces a script to do that post-hoc bodging, and calls
it from Buildscr. I've also changed over the choice of Program Files
folder for the Arm installers so that it's ProgramFiles64Folder
instead of ProgramFilesFolder - so now the Windows on Arm installer
doesn't incongruously default to installing in C:\Program Files (x86)!
This commit is contained in:
Simon Tatham 2018-08-16 19:01:36 +01:00
parent 20a9bd5642
commit 9f6b59fa2e
3 changed files with 76 additions and 5 deletions

View File

@ -199,8 +199,13 @@ ifneq "$(cross_winsigncode)" "" in putty/windows do $(cross_winsigncode) -N -i h
# Build a WiX MSI installer, for each of build32 and build64.
in putty/windows with wixonlinux do candle -arch x86 -dRealPlatform=x86 -dDllOk=yes -dBuilddir=build32/ -dWinver="$(Winver)" -dPuttytextver="$(Puttytextver)" installer.wxs && light -ext WixUIExtension -ext WixUtilExtension -sval installer.wixobj -o installer32.msi -spdb
in putty/windows with wixonlinux do candle -arch x64 -dRealPlatform=x64 -dDllOk=yes -dBuilddir=build64/ -dWinver="$(Winver)" -dPuttytextver="$(Puttytextver)" installer.wxs && light -ext WixUIExtension -ext WixUtilExtension -sval installer.wixobj -o installer64.msi -spdb
in putty/windows with wixonlinux do candle -arch x86 -dRealPlatform=Arm -dDllOk=no -dBuilddir=abuild32/ -dWinver="$(Winver)" -dPuttytextver="$(Puttytextver)" installer.wxs && light -ext WixUIExtension -ext WixUtilExtension -sval installer.wixobj -o installera32.msi -spdb
in putty/windows with wixonlinux do candle -arch x86 -dRealPlatform=Arm64 -dDllOk=no -dBuilddir=abuild64/ -dWinver="$(Winver)" -dPuttytextver="$(Puttytextver)" installer.wxs && light -ext WixUIExtension -ext WixUtilExtension -sval installer.wixobj -o installera64.msi -spdb
in putty/windows with wixonlinux do candle -arch x64 -dRealPlatform=Arm -dDllOk=no -dBuilddir=abuild32/ -dWinver="$(Winver)" -dPuttytextver="$(Puttytextver)" installer.wxs && light -ext WixUIExtension -ext WixUtilExtension -sval installer.wixobj -o installera32.msi -spdb
in putty/windows with wixonlinux do candle -arch x64 -dRealPlatform=Arm64 -dDllOk=no -dBuilddir=abuild64/ -dWinver="$(Winver)" -dPuttytextver="$(Puttytextver)" installer.wxs && light -ext WixUIExtension -ext WixUtilExtension -sval installer.wixobj -o installera64.msi -spdb
# Bodge the platform fields for the Windows on Arm installers, since
# WiX 3 doesn't understand Arm platform names itself.
in putty/windows do ./msiplatform.py installera32.msi Arm
in putty/windows do ./msiplatform.py installera64.msi Arm64
# Sign the Windows installers.
ifneq "$(cross_winsigncode)" "" in putty/windows do $(cross_winsigncode) -i https://www.chiark.greenend.org.uk/~sgtatham/putty/ -n "PuTTY Installer" installer32.msi installer64.msi installera32.msi installera64.msi

View File

@ -5,17 +5,20 @@
<?if $(var.RealPlatform) = x64 ?>
<?define Bitness = " (64-bit)" ?>
<?define RegKeyPathLocation = "Software\SimonTatham\PuTTY64" ?>
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?else ?>
<?define Bitness = "" ?>
<?define RegKeyPathLocation = "Software\SimonTatham\PuTTY" ?>
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?endif ?>
<?if $(var.RealPlatform) = x86 ?>
<?define InstallerVersion = "100" ?>
<?else ?>
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?elseif $(var.RealPlatform) = x64 ?>
<?define InstallerVersion = "200" ?>
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?else ?>
<?define InstallerVersion = "500" ?>
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?endif ?>
<?if $(var.RealPlatform) = x64 ?>

63
windows/msiplatform.py Executable file
View File

@ -0,0 +1,63 @@
#!/usr/bin/env python
import argparse
import os
import tempfile
import shutil
import subprocess
import pipes
def run(command, verbose):
if verbose:
sys.stdout.write("$ {}\n".format(" ".join(
pipes.quote(word) for word in command)))
out = subprocess.check_output(command)
if verbose:
sys.stdout.write("".join(
"> {}\n".format(line) for line in out.splitlines()))
def set_platform(msi, platform, verbose):
run(["msidump", "-t", msi], verbose)
summary_stream = "_SummaryInformation.idt"
with open(summary_stream) as fh:
lines = [line.rstrip("\r\n").split("\t")
for line in iter(fh.readline, "")]
for line in lines[3:]:
if line[0] == "7":
line[1] = ";".join([platform] + line[1].split(";", 1)[1:])
with open(summary_stream, "w") as fh:
for line in lines:
fh.write("\t".join(line) + "\r\n")
run(["msibuild", msi, "-i", summary_stream], verbose)
def main():
parser = argparse.ArgumentParser(
description='Change the platform field of an MSI installer package.')
parser.add_argument("msi", help="MSI installer file.")
parser.add_argument("platform", help="New value for the platform field.")
parser.add_argument("-v", "--verbose", action="store_true",
help="Log what this script is doing.")
parser.add_argument("-k", "--keep", action="store_true",
help="Don't delete the temporary working directory.")
args = parser.parse_args()
msi = os.path.abspath(args.msi)
msidir = os.path.dirname(msi)
try:
tempdir = tempfile.mkdtemp(dir=msidir)
os.chdir(tempdir)
set_platform(msi, args.platform, args.verbose)
finally:
if args.keep:
sys.stdout.write(
"Retained temporary directory {}\n".format(tempdir))
else:
shutil.rmtree(tempdir)
if __name__ == '__main__':
main()