mirror of
https://github.com/narrrl/proton-stream.git
synced 2026-11-04 08:56:59 +01:00
An MSI upgrade left the app without libmpv-2.dll until it was installed a second time (B62). Costing runs before RemoveExistingProducts, saw the old DLL at the same version and skipped the copy, and removing the old product then deleted it. Both installer definitions now set REINSTALLMODE=amus; every file is private to the install directory. A taskbar pin lost its icon after a while (B63). The exe carried no icon resource, and the Start Menu shortcut's icon lived in the per-ProductCode installer cache that each upgrade deletes. build.rs now compiles the .ico into proton-stream.exe, and the shortcut has no Icon of its own (and in the WiX build is no longer advertised), so both show the exe's icon.
170 lines
8.4 KiB
XML
170 lines
8.4 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!--
|
|
The Linux-hosted .msi definition, built by scripts/build-windows.sh with
|
|
msitools' wixl:
|
|
|
|
wixl -a x64 -o dist/proton-stream-0.1.0-x64.msi packaging/windows/proton-stream.wixl.wxs \
|
|
-D Version=0.1.0 -D BinDir=... -D MpvDll=... -D IconFile=...
|
|
|
|
Why a second file at all, next to proton-stream.wxs
|
|
===================================================
|
|
The WiX toolset cannot build an .msi on Linux. Not "is unsupported" — it
|
|
fails outright, in WixToolset.Core's BundleValidator.GetCanonicalRelativePath,
|
|
which validates every Directory/@Name by prepending a drive letter and asking
|
|
.NET to canonicalise it:
|
|
|
|
Path.GetFullPath("C:\\" + name) // on Linux: "/cwd/C:\name"
|
|
if (fullPath.StartsWith("C:\\")) // never true off Windows
|
|
|
|
so every <Directory Name="..."> in any .wxs is rejected with WIX0389. That is
|
|
true of WiX v5 and v6; v7 additionally requires accepting the Open Source
|
|
Maintenance Fee EULA. There is no workaround in the XML, because the check
|
|
runs before anything the document can influence.
|
|
|
|
wixl (from GNOME's msitools) writes the MSI tables directly and needs no
|
|
Windows anything, but it speaks the WiX **v3** schema and implements a subset
|
|
of it — hence this file rather than a preprocessor branch inside the v4 one.
|
|
|
|
What this loses against the WiX build
|
|
=====================================
|
|
The dialog UI. WixUI_InstallDir, and with it the license page and the
|
|
"choose a folder" page, is a WiX extension with no wixl equivalent, so this
|
|
.msi installs with the plain Windows Installer progress UI and always lands in
|
|
Program Files. Everything that matters after that — per-machine install,
|
|
major-upgrade replacement, Add/Remove Programs entry with the icon, the PATH
|
|
entry, clean uninstall — is authored here and identical.
|
|
|
|
Keep in sync with proton-stream.wxs
|
|
===================================
|
|
One attribute deliberately disagrees — Environment/@Permanent, because wixl
|
|
reads it backwards; see the comment on that element. UpgradeCode and every
|
|
Component Guid are shared with that file, deliberately.
|
|
They are what lets an .msi built here upgrade one built on Windows (and the
|
|
reverse) instead of the two stacking up or corrupting each other's component
|
|
reference counts. Never regenerate them; a new *payload file* gets a new
|
|
Component with a new Guid, in both files.
|
|
-->
|
|
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
|
|
|
<Product Id="*"
|
|
Name="Proton Stream"
|
|
Language="1033"
|
|
Version="$(var.Version)"
|
|
Manufacturer="Nils Pukropp"
|
|
UpgradeCode="0a5c3818-3401-469c-a2ac-a3172cef1938">
|
|
|
|
<Package InstallerVersion="500"
|
|
Compressed="yes"
|
|
InstallScope="perMachine"
|
|
Manufacturer="Nils Pukropp"
|
|
Description="Netflix-style desktop client for Proton Drive public links" />
|
|
|
|
<!-- Replace an older install rather than sitting beside it. Scheduled after
|
|
InstallInitialize so the old product is torn down before the new files
|
|
land: the reverse order leaves the uninstall of 0.1.0 deleting files
|
|
0.2.0 just wrote. -->
|
|
<Upgrade Id="0a5c3818-3401-469c-a2ac-a3172cef1938">
|
|
<UpgradeVersion Minimum="0.0.0" IncludeMinimum="yes"
|
|
Maximum="$(var.Version)" IncludeMaximum="yes"
|
|
Property="OLDERVERSIONBEINGUPGRADED" />
|
|
<UpgradeVersion Minimum="$(var.Version)" IncludeMinimum="no"
|
|
OnlyDetect="yes"
|
|
Property="NEWERVERSIONDETECTED" />
|
|
</Upgrade>
|
|
<Condition Message="A newer version of Proton Stream is already installed.">
|
|
NOT NEWERVERSIONDETECTED
|
|
</Condition>
|
|
<InstallExecuteSequence>
|
|
<RemoveExistingProducts After="InstallInitialize" />
|
|
</InstallExecuteSequence>
|
|
|
|
<!-- Copy every file on an upgrade, whatever is on disk. Costing runs
|
|
before RemoveExistingProducts, so it sees the old libmpv-2.dll — the
|
|
same version, since mpv is pinned — and decides not to copy it. The
|
|
removal of the old product then deletes it, and the upgrade ends with
|
|
no DLL: "mpv missing" until a second install, which finds nothing on
|
|
disk and copies it. Every file here is private to INSTALLDIR, so
|
|
overwriting unconditionally downgrades nothing shared. -->
|
|
<Property Id="REINSTALLMODE" Value="amus" />
|
|
|
|
<Media Id="1" Cabinet="proton_stream.cab" EmbedCab="yes" />
|
|
|
|
<Icon Id="proton-stream.ico" SourceFile="$(var.IconFile)" />
|
|
<Property Id="ARPPRODUCTICON" Value="proton-stream.ico" />
|
|
<Property Id="ARPURLINFOABOUT" Value="https://github.com/narrrl/proton-stream" />
|
|
<Property Id="ARPNOREPAIR" Value="1" />
|
|
|
|
<Directory Id="TARGETDIR" Name="SourceDir">
|
|
<Directory Id="ProgramFiles64Folder">
|
|
<Directory Id="INSTALLDIR" Name="Proton Stream">
|
|
|
|
<Component Id="AppExe" Guid="623c8cb8-b826-4d57-a054-e5be56f24c19" Win64="yes">
|
|
<File Id="AppExe" Source="$(var.BinDir)/proton-stream.exe"
|
|
Name="proton-stream.exe" KeyPath="yes" />
|
|
<!-- Not advertised: an advertised shortcut needs the feature state
|
|
machine that the dialog-less install does not drive. wixl has
|
|
no Advertise attribute — it logs "builder.vala: unimplemented"
|
|
and writes the advertised form anyway, with the feature name in
|
|
Shortcut/Target. What selects the non-advertised form is being
|
|
a child of the Component rather than of the File, plus an
|
|
explicit formatted Target. Keep it out of the <File>.
|
|
|
|
No Icon either. A shortcut's Icon is copied to
|
|
C:\Windows\Installer\{ProductCode}, and every upgrade has a
|
|
new ProductCode and deletes the old folder — taking the icon
|
|
of every taskbar pin made from the shortcut with it. Without
|
|
one, the shortcut shows the exe's own icon resource. -->
|
|
<Shortcut Id="StartMenuShortcut"
|
|
Directory="ProgramMenuFolder"
|
|
Name="Proton Stream"
|
|
Description="Browse and stream a Proton Drive public link"
|
|
Target="[INSTALLDIR]proton-stream.exe"
|
|
WorkingDirectory="INSTALLDIR" />
|
|
</Component>
|
|
|
|
<!-- The CLI, and the PATH entry that makes it worth installing. Tied
|
|
to the same component so uninstalling takes the PATH edit with
|
|
it.
|
|
|
|
Permanent="yes" here against Permanent="no" in the WiX file, and
|
|
the two mean the same thing. wixl has the attribute inverted: it
|
|
appends the Environment table's "-" prefix — "remove this value
|
|
on uninstall" — when Permanent is *true*, so Permanent="no"
|
|
builds an .msi whose uninstall leaves the PATH entry behind.
|
|
Verify with `msiinfo export out.msi Environment`; the Name must
|
|
come out "=-*PATH".
|
|
|
|
<Environment> itself needs msitools >= 0.105. Older wixl aborts
|
|
on this element with a core dump rather than an error, which is
|
|
why scripts/build-windows.sh checks the version first. -->
|
|
<Component Id="CliExe" Guid="6440650e-281f-4842-a75a-4cbea8be0d71" Win64="yes">
|
|
<File Id="CliExe" Source="$(var.BinDir)/pstr.exe" Name="pstr.exe" KeyPath="yes" />
|
|
<Environment Id="PstrPath" Name="PATH" Value="[INSTALLDIR]"
|
|
Part="last" Action="set" System="yes" Permanent="yes" />
|
|
</Component>
|
|
|
|
<!-- libmpv does the demuxing and decoding. There is no static build
|
|
of it worth shipping, so the DLL sits beside the exe. -->
|
|
<Component Id="MpvDll" Guid="ff74fc79-78e3-4ed8-881d-f322ed6ff6b4" Win64="yes">
|
|
<File Id="MpvDll" Source="$(var.MpvDll)" Name="libmpv-2.dll" KeyPath="yes" />
|
|
</Component>
|
|
|
|
<Component Id="ReadMe" Guid="5bb65b44-f5df-423b-8dcc-a753d7aef565" Win64="yes">
|
|
<File Id="ReadMe" Source="$(var.ReadMe)" Name="README.md" KeyPath="yes" />
|
|
</Component>
|
|
|
|
</Directory>
|
|
</Directory>
|
|
<Directory Id="ProgramMenuFolder" />
|
|
</Directory>
|
|
|
|
<Feature Id="Main" Title="Proton Stream" Level="1">
|
|
<ComponentRef Id="AppExe" />
|
|
<ComponentRef Id="CliExe" />
|
|
<ComponentRef Id="MpvDll" />
|
|
<ComponentRef Id="ReadMe" />
|
|
</Feature>
|
|
|
|
</Product>
|
|
</Wix>
|