mirror of
https://github.com/narrrl/proton-stream.git
synced 2026-11-03 16:41:26 +01:00
- Desktop shows Proton's CAPTCHA instead of failing the sign-in: a wry webview in a child process of the app (`pstr-app::verify`), confined to https://*.proton.me, hands the token back and the sign-in is retried. Linux packages and CI gain WebKitGTK 4.1; the Windows zip and MSI ship WebView2Loader.dll, without which a -gnu build does not start. - The desktop keyring splits a secret too long for one entry across several, so a Proton session with many key salts survives Windows' 1280-unit cap. Short secrets stay one entry, so every existing secret still reads. - `WatchSync` runs against a small `HistoryDrive` trait and is tested end to end against an in-memory Drive: two devices, newer wins, no re-upload of an unchanged history, a missing file written again, an unreadable own file never overwritten, a newer-format file left alone. - An installation's file unwritten for 90 days is retired by the next device to sync, after its entries are merged and carried in that device's file. - Removing a share keeps its watch state: sync would bring it back from the other devices anyway, and re-adding the share picks up where it left off. - Watch history syncs once more on desktop exit (bounded to 3 s) and, on Android, through a WorkManager job enqueued when the app leaves the screen. - The second-factor prompts say security keys are not supported.
178 lines
8.9 KiB
XML
178 lines
8.9 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>
|
|
|
|
<!-- Loads WebView2 for the CAPTCHA window Proton sometimes puts
|
|
in front of a sign-in. A -gnu build links it as a DLL; the
|
|
WebView2 runtime itself comes with Windows. -->
|
|
<Component Id="WebViewLoader" Guid="3e8a89cf-cf3e-4cc7-b1c6-9d272b3210c3" Win64="yes">
|
|
<File Id="WebViewLoader" Source="$(var.WebViewLoader)" Name="WebView2Loader.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="WebViewLoader" />
|
|
<ComponentRef Id="ReadMe" />
|
|
</Feature>
|
|
|
|
</Product>
|
|
</Wix>
|