diff --git a/Buildscr b/Buildscr index 08be3ec6..12ff2fcf 100644 --- a/Buildscr +++ b/Buildscr @@ -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 diff --git a/windows/installer.wxs b/windows/installer.wxs index 47da2c9e..005d7e03 100644 --- a/windows/installer.wxs +++ b/windows/installer.wxs @@ -5,17 +5,20 @@ - - - + + + + + + diff --git a/windows/msiplatform.py b/windows/msiplatform.py new file mode 100755 index 00000000..eea4272f --- /dev/null +++ b/windows/msiplatform.py @@ -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()