This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/release/windows/msix/create_msix_package.py
Eric Bickle 55c56f1ffb Fix T79356: Improved icons for MSIX builds
Fixed an issue that was causing the app icon to render with a
'plated' background color in the taskbar and other areas of Windows.

Updated all app icons in Microsoft Store package to match Microsoft's
design recommendations.

Added multiple scales for app icons for high resolution displays.

Added high contrast app icons.

Reviewed By: pablovazquez, jmonteath

Maniphest Tasks: T79356

Differential Revision: https://developer.blender.org/D9681
2021-01-13 14:42:05 +01:00

198 lines
6.2 KiB
Python

#!/usr/bin/env python3
import argparse
import os
import pathlib
import requests
import shutil
import subprocess
import zipfile
parser = argparse.ArgumentParser()
parser.add_argument(
"--version",
required=True,
help="Version string in the form of 2.83.3.0",
)
parser.add_argument(
"--url",
required=True,
help="Location of the release ZIP archive to download",
)
parser.add_argument(
"--publisher",
required=True,
help="A string in the form of 'CN=PUBLISHER'",
)
parser.add_argument(
"--pfx",
required=False,
help="Absolute path to the PFX file used for signing the resulting MSIX package",
)
parser.add_argument(
"--password",
required=False,
default="blender",
help="Password for the PFX file",
)
parser.add_argument(
"--lts",
required=False,
help="If set this MSIX is for an LTS release",
action='store_const',
const=1,
)
parser.add_argument(
"--skipdl",
required=False,
help="If set skip downloading of the specified URL as blender.zip. The tool assumes blender.zip exists",
action='store_const',
const=1,
)
parser.add_argument(
"--leavezip",
required=False,
help="If set don't clean up the downloaded blender.zip",
action='store_const',
const=1,
)
parser.add_argument(
"--overwrite",
required=False,
help="If set remove Content folder if it already exists",
action='store_const',
const=1,
)
args = parser.parse_args()
def execute_command(cmd: list, name: str, errcode: int):
"""
Execute given command in cmd. Output is captured. If an error
occurs name is used to print ERROR message, along with stderr and
stdout of the process if either was captured.
"""
cmd_process = subprocess.run(cmd, capture_output=True, encoding="UTF-8")
if cmd_process.returncode != 0:
print(f"ERROR: {name} failed.")
if cmd_process.stdout:
print(cmd_process.stdout)
if cmd_process.stderr:
print(cmd_process.stderr)
exit(errcode)
LTSORNOT = ""
PACKAGETYPE = ""
if args.lts:
versionparts = args.version.split(".")
LTSORNOT = f" {versionparts[0]}.{versionparts[1]} LTS"
PACKAGETYPE = f"{versionparts[0]}.{versionparts[1]}LTS"
blender_package_msix = pathlib.Path(".", f"blender-{args.version}-windows64.msix").absolute()
content_folder = pathlib.Path(".", "Content")
content_blender_folder = pathlib.Path(content_folder, "Blender").absolute()
content_assets_folder = pathlib.Path(content_folder, "Assets")
assets_original_folder = pathlib.Path(".", "Assets")
pri_config_file = pathlib.Path(".", "priconfig.xml")
pri_resources_file = pathlib.Path(content_folder, "resources.pri")
local_blender_zip = pathlib.Path(".", "blender.zip")
if args.pfx:
pfx_path = pathlib.Path(args.pfx)
if not pfx_path.exists():
print("ERROR: PFX file not found. Please ensure you give the correct path to the PFX file on the command-line.")
exit(1)
print(f"Creating MSIX package with signing using PFX file at {pfx_path}")
else:
pfx_path = None
print("Creating MSIX package without signing.")
pri_command = ["makepri",
"new",
"/pr", f"{content_folder.absolute()}",
"/cf", f"{pri_config_file.absolute()}",
"/of", f"{pri_resources_file.absolute()}"
]
msix_command = ["makeappx",
"pack",
"/h", "SHA256",
"/d", f"{content_folder.absolute()}",
"/p", f"{blender_package_msix}"
]
if pfx_path:
sign_command = ["signtool",
"sign",
"/fd", "sha256",
"/a", "/f", f"{pfx_path.absolute()}",
"/p", f"{args.password}",
f"{blender_package_msix}"
]
if args.overwrite:
if content_folder.joinpath("Assets").exists():
shutil.rmtree(content_folder)
content_folder.mkdir(exist_ok=True)
shutil.copytree(assets_original_folder, content_assets_folder)
manifest_text = pathlib.Path("AppxManifest.xml.template").read_text()
manifest_text = manifest_text.replace("[VERSION]", args.version)
manifest_text = manifest_text.replace("[PUBLISHER]", args.publisher)
manifest_text = manifest_text.replace("[LTSORNOT]", LTSORNOT)
manifest_text = manifest_text.replace("[PACKAGETYPE]", PACKAGETYPE)
pathlib.Path(content_folder, "AppxManifest.xml").write_text(manifest_text)
if not args.skipdl:
print(f"Downloading blender archive {args.url} to {local_blender_zip}...")
with open(local_blender_zip, "wb") as download_zip:
response = requests.get(args.url)
download_zip.write(response.content)
print("... download complete.")
else:
print("Skipping download")
print(f"Extracting files from ZIP to {content_blender_folder}...")
# Extract the files from the ZIP archive, but skip the leading part of paths
# in the ZIP. We want to write the files to the content_blender_folder where
# blender.exe ends up as ./Content/Blender/blender.exe, and not
# ./Content/Blender/blender-2.83.3-windows64/blender.exe
with zipfile.ZipFile(local_blender_zip, "r") as blender_zip:
for entry in blender_zip.infolist():
if entry.is_dir():
continue
entry_location = pathlib.Path(entry.filename)
target_location = content_blender_folder.joinpath(*entry_location.parts[1:])
pathlib.Path(target_location.parent).mkdir(parents=True, exist_ok=True)
extracted_entry = blender_zip.read(entry)
target_location.write_bytes(extracted_entry)
print("... extraction complete.")
print(f"Generating Package Resource Index (PRI) file using command: {' '.join(pri_command)}")
execute_command(pri_command, "MakePri", 4)
print(f"Creating MSIX package using command: {' '.join(msix_command)}")
# Remove MSIX file if it already exists. Otherwise the MakeAppX tool
# will hang.
if blender_package_msix.exists():
os.remove(blender_package_msix)
execute_command(msix_command, "MakeAppX", 2)
if args.pfx:
print(f"Signing MSIX package using command: {' '.join(sign_command)}")
execute_command(sign_command, "SignTool", 3)
if not args.leavezip:
os.remove(local_blender_zip)
shutil.rmtree(content_folder)
print("Done.")