feat(installer): unify Windows setup and completion screens (INSTALLER-UI)

This commit is contained in:
skylartaylor
2026-10-16 03:46:50 +02:00
parent d78e657e4c
commit 6aa0b68186
6 changed files with 312 additions and 4 deletions
+25 -1
View File
@@ -2,7 +2,7 @@
**Stage: alpha** · next: beta, ~20 points and ~120–210 h away
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-10 · **Change:** minor (hours to ~95% per audience added; ready 56% → 55%; stage stays alpha; previous: major, full re-measure against PowerPoint for Mac 16.113.4; restructured to the craftrules progress-docs standard) · **Target:** Microsoft PowerPoint for Mac 16.113 (Microsoft 365)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-12 · **Change:** minor (shared Windows installer UI; existing folder/shortcut/launch options retained; install and uninstall completion) · **Target:** Microsoft PowerPoint for Mac 16.113 (Microsoft 365)
DeckCraft aims at full PowerPoint parity, and to be better: faster, open (a documented zip+JSON
format plus PPTX), scriptable by agents (CLI, JSON control channel, MCP), and available everywhere
@@ -158,3 +158,27 @@ app's JSON control channel (`deckcraft --control PORT`).
| 2026-10-10 | minor | Stage checked against the new core-workflow gate: passes, stays alpha |
| 2026-10-10 | major | Restructured to craftrules `standards/progress-docs.md`: stage, two numbers, dimensions, features, languages; parity estimate moved to docs/target-app-parity.md, "Working today" to its evidence section, the alpha checklist to docs/roadmap.md |
| 2026-10-07 | major | Alpha checklist (~80% to a self-defined alpha), breadth ~80%, overall ~62%, ~190 h to full parity |
## Packaging update — 2026-10-10
Windows setup now uses the shared `craft-installer` native UI source, with install/repair/remove
completion, cancellation and failure screens. Existing MSI ownership and upgrade identities are
preserved; unattended modes remain unattended. Source/generator checks pass; native Windows
installer acceptance with real release payloads is still pending. See [setup validation](packaging/windows/README.md).
## Packaging update (2026-10-11)
Windows setup now uses the suite's shared `craft-installer` UI, preserving existing folder,
shortcut and launch options and app-owned installation policy. Install, uninstall and repair
have explicit completion screens; cancellation and failure have separate endings. Source/profile
checks, WiX UI library compilation for x64/x86/ARM64, PowerShell parsing and package identity
comparisons pass. Native fixture MSI linking/UI tables pass on all three architectures, and
Windows full UI install/repair/uninstall, x86 install/remove, folder upgrades, desktop choices
and launch checks pass with fixtures. Native evidence and real-release acceptance limits
are linked from
[Windows packaging](packaging/windows/README.md).
Windows Settings removal now opens the shared completion screen. Quiet install/removal
remains unattended; Settings labels preserve compatibility with existing Launchers, and
previous Modify policy is retained. Windows 11 fixture verification covers both installation
scopes and x64/x86 removal, with full MSI validation on x64/x86/ARM64.
+17 -1
View File
@@ -1,6 +1,6 @@
# DeckCraft roadmap: milestones and what's next
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-10 · **Change:** minor (core-workflow alpha gate added; stage stays alpha; previous: major, created; milestones carried from the local execution plan, the beta plan built from gaps.md) · **Target:** Microsoft PowerPoint for Mac 16.113 (Microsoft 365)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (shared Windows installer UI; existing folder/shortcut/launch options retained; install and uninstall completion) · **Target:** Microsoft PowerPoint for Mac 16.113 (Microsoft 365)
Forward-looking: where DeckCraft is going and in what order. The one-page summary is
[ROADMAP.md](../ROADMAP.md); every shortfall is in [gaps.md](gaps.md); numbers are in
@@ -111,3 +111,19 @@ plan above.
|---|---|---|
| 2026-10-10 | minor | Added the alpha gate (six core workflows): all pass, two with partial depth; stage stays alpha |
| 2026-10-10 | major | Created: current focus, ranked beta plan with hours, milestones M0–M14 with status, the old alpha checklist as history |
## Packaging update — 2026-10-10
Windows setup now uses the shared `craft-installer` native UI source, with install/repair/remove
completion, cancellation and failure screens. Existing MSI ownership and upgrade identities are
preserved; unattended modes remain unattended. Source/generator checks pass; native Windows
installer acceptance is still pending. See [setup validation](../packaging/windows/README.md).
## Packaging update (2026-10-11)
Windows setup now uses the suite's shared `craft-installer` UI, preserving existing folder,
shortcut and launch options and app-owned installation policy. Install, uninstall and repair
have explicit completion screens; cancellation and failure have separate endings. Source/profile
checks, WiX UI library compilation for x64/x86/ARM64, PowerShell parsing and package identity
comparisons pass. Full MSI linking and interactive Windows acceptance remain pending; see
[Windows packaging](../packaging/windows/README.md).
+34
View File
@@ -0,0 +1,34 @@
# Windows installer UI
`installer-ui.wxs` is generated from the shared `craft-installer` crate in
[craft-libs](https://github.com/storytold/craft-libs/tree/main/crates/installer).
`package.ps1` compiles it with this app's package source. The common UI provides progress,
repair/remove, and explicit install/uninstall/repair success, cancellation and failure screens.
Regenerate or check from a sibling craft-libs checkout:
```sh
cargo run --locked -p craft-installer -- --write --app deckcraft ../deckcraft/packaging/windows/installer-ui.wxs
cargo run --locked -p craft-installer -- --check --app deckcraft ../deckcraft/packaging/windows/installer-ui.wxs
```
Edit the shared templates/profile and regenerate; avoid editing this snapshot by hand. The
profile retains this app's existing folder, shortcut and launch options; defaults, persistence,
components, associations and signing stay in the app-owned source. Release builds require no
sibling checkout, published crate or additional runtime dependency. `/qn`, `/qb` and `/passive`
remain unattended and do not launch the app.
Source/profile checks and native fixture MSI linking/UI table checks passed for x64, x86 and
ARM64. All 14 profiles passed full UI install, missing-file repair and cached uninstall, and
x86 silent install/removal. Folder upgrades, desktop choices and all six launch profiles also
passed their Windows fixture checks. See the
[Windows verification record](../../../craft-libs/docs/windows-installer-verification.md) for
interactive results, scope validation and remaining acceptance checks with real release payloads.
The shared crate includes reusable linking, full UI, option/upgrade/launch and x86 test runners.
Windows Settings now uses a separate MSI-owned entry whose uninstall command selects full UI,
including the completion screen. Its quiet command and direct `/qn`, `/qb`, `/passive` commands
remain unattended. The main feature references `CraftInstallerSettings`; the shared snapshot
owns this registration and hides the native MSI entry while retaining MSI repair/upgrade APIs.
The Settings display name appends `(Craft Apps)` for compatibility with older Launchers; the
hidden native MSI name stays unchanged. Existing ARP Modify policy is retained explicitly.
+6 -1
View File
@@ -2,7 +2,7 @@
<!--
DeckCraft MSI (WiX Toolset v5: `dotnet tool install -g wix`). Built by package.ps1:
wix build deckcraft.wxs -arch x64 -d Version=1.2.3 -d BinDir=... -d IconPath=... -o out.msi
wix build deckcraft.wxs installer-ui.wxs -arch x64 -d Version=1.2.3 -d BinDir=... -d IconPath=... -o out.msi
Per-machine install into Program Files, a Start Menu shortcut, `.deckcraft` owned by
DeckCraft, and DeckCraft offered under "Open with" for .pptx/.potx/.ppsx (without taking over
@@ -32,6 +32,8 @@
<Property Id="ARPURLUPDATEINFO" Value="https://getartcraft.com/apps/deckcraft" />
<Property Id="ARPHELPLINK" Value="https://discord.gg/artcraft" />
<!-- Shared native setup UI, including install/uninstall completion. -->
<StandardDirectory Id="ProgramFiles6432Folder">
<Directory Id="INSTALLFOLDER" Name="DeckCraft" />
</StandardDirectory>
@@ -39,7 +41,10 @@
<Feature Id="Main" Title="DeckCraft" Level="1">
<ComponentGroupRef Id="DeckcraftFiles" />
<ComponentGroupRef Id="CraftInstallerSettings" />
</Feature>
<!-- Shared full UI; app installation policy remains below. -->
<UIRef Id="CraftInstallerUI" />
</Package>
<Fragment>
+229
View File
@@ -0,0 +1,229 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generated by craft-installer for deckcraft. Edit the template in craft-libs, then regenerate. -->
<!-- Adapted from PdfCraft installer-ui.wxs (a6bc63a), GridCraft gridcraft.wxs (5b15827),
and EffectCraft installer-ui.wxs (1b4d47f).
Copyright (c) 2026 ArtCraft Team and the PdfCraft contributors.
Copyright (c) 2026 ArtCraft Team and the GridCraft contributors.
Copyright (c) 2026 ArtCraft Team and the EffectCraft contributors.
Licensed under MIT OR Apache-2.0; see the repository's LICENSE-MIT and LICENSE-APACHE. -->
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Fragment>
<!-- Windows Installer populates files-in-use lists at runtime. Keep their table even
though these dialogs have no static ListItem rows (the GridCraft UI does the same). -->
<EnsureTable Id="ListBox" />
<!-- Reuse the existing package icon as a fallback; MSI supplies its standard message icon. -->
<Binary Id="CraftInstallerErrorIcon" SourceFile="$(var.IconPath)" />
<UI Id="CraftInstallerUI">
<TextStyle Id="CraftInstallerNormal" FaceName="Segoe UI" Size="9" />
<TextStyle Id="CraftInstallerTitle" FaceName="Segoe UI" Size="12" Bold="yes" />
<Property Id="DefaultUIFont" Value="CraftInstallerNormal" />
<Property Id="ErrorDialog" Value="CraftInstallerErrorDlg" />
<Dialog Id="CraftInstallerErrorDlg" Width="320" Height="120" Title="[ProductName] Setup" ErrorDialog="yes" NoMinimize="yes">
<Control Id="ErrorText" Type="Text" X="60" Y="15" Width="245" Height="65" TabSkip="no" />
<Control Id="ErrorIcon" Type="Icon" X="15" Y="15" Width="32" Height="32" FixedSize="yes" IconSize="32" TabSkip="yes" Text="CraftInstallerErrorIcon" />
<Control Id="A" Type="PushButton" X="15" Y="90" Width="65" Height="20" Text="Abort" TabSkip="yes">
<Publish Event="EndDialog" Value="ErrorAbort" />
</Control>
<Control Id="C" Type="PushButton" X="15" Y="90" Width="65" Height="20" Text="Cancel" TabSkip="yes">
<Publish Event="EndDialog" Value="ErrorCancel" />
</Control>
<Control Id="I" Type="PushButton" X="15" Y="90" Width="65" Height="20" Text="Ignore" TabSkip="yes">
<Publish Event="EndDialog" Value="ErrorIgnore" />
</Control>
<Control Id="N" Type="PushButton" X="15" Y="90" Width="65" Height="20" Text="No" TabSkip="yes">
<Publish Event="EndDialog" Value="ErrorNo" />
</Control>
<Control Id="O" Type="PushButton" X="15" Y="90" Width="65" Height="20" Text="OK" TabSkip="yes">
<Publish Event="EndDialog" Value="ErrorOk" />
</Control>
<Control Id="R" Type="PushButton" X="15" Y="90" Width="65" Height="20" Text="Retry" TabSkip="yes">
<Publish Event="EndDialog" Value="ErrorRetry" />
</Control>
<Control Id="Y" Type="PushButton" X="15" Y="90" Width="65" Height="20" Text="Yes" TabSkip="yes">
<Publish Event="EndDialog" Value="ErrorYes" />
</Control>
</Dialog>
<Dialog Id="FilesInUse" Width="320" Height="190" Title="[ProductName] Setup" NoMinimize="yes">
<Control Id="Description" Type="Text" X="15" Y="15" Width="290" Height="35"
Text="Close the applications listed below, then choose Retry. Ignore may require a restart." />
<Control Id="Files" Type="ListBox" X="15" Y="55" Width="290" Height="85" Property="FileInUseProcess" />
<Control Id="Retry" Type="PushButton" X="95" Y="155" Width="65" Height="20" Default="yes" Text="Retry">
<Publish Event="EndDialog" Value="Retry" />
</Control>
<Control Id="Ignore" Type="PushButton" X="167" Y="155" Width="65" Height="20" Text="Ignore">
<Publish Event="EndDialog" Value="Ignore" />
</Control>
<Control Id="Cancel" Type="PushButton" X="240" Y="155" Width="65" Height="20" Cancel="yes" Text="Cancel">
<Publish Event="EndDialog" Value="Exit" />
</Control>
</Dialog>
<Dialog Id="InstallWelcome" Width="370" Height="270" Title="[ProductName] Setup">
<Control Id="Title" Type="Text" X="20" Y="20" Width="330" Height="25" Text="{\CraftInstallerTitle}Install [ProductName]" />
<Control Id="Description" Type="Text" X="20" Y="55" Width="330" Height="40"
Text="Setup will install [ProductName] for all users and add it to the Start menu. Click Install to continue." />
<Control Id="Install" Type="PushButton" X="195" Y="235" Width="75" Height="23" Default="yes" ElevationShield="yes" Text="&amp;Install">
<Publish Event="EndDialog" Value="Return" Order="99" />
</Control>
<Control Id="Cancel" Type="PushButton" X="280" Y="235" Width="70" Height="23" Cancel="yes" Text="Cancel">
<Publish Event="EndDialog" Value="Exit" />
</Control>
</Dialog>
<Dialog Id="InstallMaintenance" Width="370" Height="270" Title="[ProductName] Setup">
<Control Id="Title" Type="Text" X="20" Y="20" Width="330" Height="25" Text="{\CraftInstallerTitle}Maintain [ProductName]" />
<Control Id="Description" Type="Text" X="20" Y="55" Width="330" Height="70"
Text="[ProductName] is already installed. Choose Repair to restore missing files and shortcuts, or Remove to uninstall it." />
<Control Id="Repair" Type="PushButton" X="110" Y="235" Width="75" Height="23" Default="yes" ElevationShield="yes" Text="&amp;Repair">
<!-- Feature events do not retain REINSTALL/REMOVE in the client UI session. -->
<Publish Property="CraftInstallerOperation" Value="repair" Order="1" />
<Publish Event="ReinstallMode" Value="amus" Order="2" />
<Publish Event="Reinstall" Value="ALL" Order="3" />
<Publish Event="EndDialog" Value="Return" Order="4" />
</Control>
<Control Id="Remove" Type="PushButton" X="195" Y="235" Width="75" Height="23" ElevationShield="yes" Text="R&amp;emove">
<Publish Property="CraftInstallerOperation" Value="remove" Order="1" />
<Publish Event="Remove" Value="ALL" Order="2" />
<Publish Event="EndDialog" Value="Return" Order="3" />
</Control>
<Control Id="Cancel" Type="PushButton" X="280" Y="235" Width="70" Height="23" Cancel="yes" Text="Cancel">
<Publish Event="EndDialog" Value="Exit" />
</Control>
</Dialog>
<Dialog Id="InstallProgress" Width="370" Height="270" Title="[ProductName] Setup" Modeless="yes">
<Control Id="Title" Type="Text" X="20" Y="20" Width="330" Height="25" Text="{\CraftInstallerTitle}Setting up [ProductName]" />
<!-- No ActionText table is authored: subscribing would blank this message (#305). -->
<Control Id="Status" Type="Text" X="20" Y="60" Width="330" Height="40" Text="Please wait while setup completes." />
<Control Id="Progress" Type="ProgressBar" X="20" Y="110" Width="330" Height="15" ProgressBlocks="yes">
<Subscribe Event="SetProgress" Attribute="Progress" />
</Control>
<Control Id="Cancel" Type="PushButton" X="280" Y="235" Width="70" Height="23" Cancel="yes" Text="Cancel">
<Publish Event="SpawnDialog" Value="ConfirmCancel" />
</Control>
</Dialog>
<Dialog Id="ConfirmCancel" Width="300" Height="110" Title="Cancel setup">
<Control Id="Description" Type="Text" X="20" Y="20" Width="260" Height="35" Text="Cancel [ProductName] setup?" />
<Control Id="Yes" Type="PushButton" X="130" Y="70" Width="70" Height="23" Text="&amp;Yes">
<Publish Event="EndDialog" Value="Exit" />
</Control>
<Control Id="No" Type="PushButton" X="210" Y="70" Width="70" Height="23" Default="yes" Cancel="yes" Text="&amp;No">
<Publish Event="EndDialog" Value="Return" />
</Control>
</Dialog>
<Dialog Id="InstallComplete" Width="370" Height="270" Title="[ProductName] Setup">
<Control Id="Title" Type="Text" X="20" Y="20" Width="330" Height="25" Text="{\CraftInstallerTitle}Setup completed successfully" HideCondition="REMOVE = &quot;ALL&quot; OR CraftInstallerOperation = &quot;remove&quot;" />
<Control Id="RemovedTitle" Type="Text" X="20" Y="20" Width="330" Height="25" Text="{\CraftInstallerTitle}Uninstall completed successfully" Hidden="yes" ShowCondition="REMOVE = &quot;ALL&quot; OR CraftInstallerOperation = &quot;remove&quot;" />
<Control Id="Description" Type="Text" X="20" Y="55" Width="330" Height="70"
Text="[ProductName] is installed. Open it from the Start menu. Click Finish to close setup." HideCondition="REMOVE = &quot;ALL&quot; OR REINSTALL OR CraftInstallerOperation OR ACTION = &quot;ADMIN&quot;" />
<Control Id="Removed" Type="Text" X="20" Y="55" Width="330" Height="70" Hidden="yes"
Text="[ProductName] was uninstalled. Your documents and settings were kept. Click Finish to close setup."
ShowCondition="REMOVE = &quot;ALL&quot; OR CraftInstallerOperation = &quot;remove&quot;" />
<Control Id="Repaired" Type="Text" X="20" Y="55" Width="330" Height="70" Hidden="yes"
Text="[ProductName] was repaired. Open it from the Start menu. Click Finish to close setup."
ShowCondition="(REINSTALL OR CraftInstallerOperation = &quot;repair&quot;) AND NOT REMOVE AND CraftInstallerOperation &lt;&gt; &quot;remove&quot; AND ACTION &lt;&gt; &quot;ADMIN&quot;" />
<Control Id="AdminComplete" Type="Text" X="20" Y="55" Width="330" Height="70" Hidden="yes"
Text="The administrative image was created. Click Finish to close setup." ShowCondition="ACTION = &quot;ADMIN&quot;" />
<Control Id="Finish" Type="PushButton" X="280" Y="235" Width="70" Height="23" Default="yes" Cancel="yes" Text="&amp;Finish">
<Publish Event="EndDialog" Value="Return" Order="999" />
</Control>
</Dialog>
<Dialog Id="InstallFailed" Width="370" Height="270" Title="[ProductName] Setup">
<Control Id="Title" Type="Text" X="20" Y="20" Width="330" Height="25" Text="{\CraftInstallerTitle}Setup failed" />
<Control Id="Description" Type="Text" X="20" Y="55" Width="330" Height="70"
Text="[ProductName] setup could not be completed. Resolve the reported error and run setup again." />
<Control Id="Finish" Type="PushButton" X="280" Y="235" Width="70" Height="23" Default="yes" Cancel="yes" Text="&amp;Finish">
<Publish Event="EndDialog" Value="Return" />
</Control>
</Dialog>
<Dialog Id="InstallCancelled" Width="370" Height="270" Title="[ProductName] Setup">
<Control Id="Title" Type="Text" X="20" Y="20" Width="330" Height="25" Text="{\CraftInstallerTitle}Setup cancelled" />
<Control Id="Description" Type="Text" X="20" Y="55" Width="330" Height="70"
Text="[ProductName] setup was cancelled. Run setup again when you are ready." />
<Control Id="Finish" Type="PushButton" X="280" Y="235" Width="70" Height="23" Default="yes" Cancel="yes" Text="&amp;Finish">
<Publish Event="EndDialog" Value="Return" />
</Control>
</Dialog>
<!-- Shown by Windows Installer (Restart Manager) when an upgrade or repair must replace files
that a running app holds open. OK closes those programs (MSIRMSHUTDOWN=2) and
continues; Cancel ends setup. -->
<Dialog Id="MsiRMFilesInUse" Width="370" Height="200" Title="[ProductName] Setup" KeepModeless="yes">
<Control Id="Title" Type="Text" X="20" Y="15" Width="330" Height="25" Text="{\CraftInstallerTitle}Files in use" />
<Control Id="Description" Type="Text" X="20" Y="45" Width="330" Height="30"
Text="These programs are using files that setup needs to update. Click OK to close them and continue, or Cancel to stop setup." />
<Control Id="List" Type="ListBox" X="20" Y="80" Width="330" Height="55" Property="FileInUseProcess" Sunken="yes" TabSkip="yes" />
<Control Id="OK" Type="PushButton" X="195" Y="165" Width="75" Height="23" Default="yes" Text="OK">
<Publish Property="MSIRMSHUTDOWN" Value="2" Order="1" />
<Publish Event="EndDialog" Value="Return" Order="2" />
</Control>
<Control Id="Cancel" Type="PushButton" X="280" Y="165" Width="70" Height="23" Cancel="yes" Text="Cancel">
<Publish Event="EndDialog" Value="Exit" />
</Control>
</Dialog>
<InstallUISequence>
<Show Dialog="InstallWelcome" Before="CostInitialize" Condition="UILevel = 5 AND NOT Installed AND NOT REMOVE AND NOT REINSTALL" />
<!-- Reinstall/Remove control events require the selection manager initialized by costing. -->
<Show Dialog="InstallMaintenance" After="CostFinalize" Condition="UILevel = 5 AND Installed AND NOT REMOVE AND NOT REINSTALL" />
<Show Dialog="InstallProgress" Before="ExecuteAction" Condition="UILevel = 5" />
<Show Dialog="InstallComplete" OnExit="success" Condition="UILevel = 5" />
<Show Dialog="InstallFailed" OnExit="error" Condition="UILevel = 5" />
<Show Dialog="InstallCancelled" OnExit="cancel" Condition="UILevel = 5" />
</InstallUISequence>
<AdminUISequence>
<Show Dialog="InstallProgress" Before="ExecuteAction" Condition="UILevel = 5" />
<Show Dialog="InstallComplete" OnExit="success" Condition="UILevel = 5" />
<Show Dialog="InstallFailed" OnExit="error" Condition="UILevel = 5" />
<Show Dialog="InstallCancelled" OnExit="cancel" Condition="UILevel = 5" />
</AdminUISequence>
</UI>
</Fragment>
<Fragment>
<!-- Keep MSI registration for repair, upgrades and managed removal, but let Settings
invoke our explicit UI command instead of Windows Installer's basic-UI ARP path. -->
<Property Id="ARPSYSTEMCOMPONENT" Value="1" />
<?if $(sys.BUILDARCH) = x86 ?>
<?define CraftMsiSystemFolder = SystemFolder ?>
<?else ?>
<?define CraftMsiSystemFolder = System64Folder ?>
<?endif ?>
<ComponentGroup Id="CraftInstallerSettings" Directory="INSTALLFOLDER">
<Component Id="CraftInstallerSettingsEntry" Guid="*">
<RegistryKey Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\Craft.deckcraft" ForceDeleteOnUninstall="yes">
<!-- Legacy Launchers match the canonical MSI name exactly; keep this alias distinct. -->
<RegistryValue Name="DisplayName" Type="string" Value="[ProductName] (Craft Apps)" KeyPath="yes" />
<RegistryValue Name="DisplayVersion" Type="string" Value="[ProductVersion]" />
<RegistryValue Name="Publisher" Type="string" Value="[Manufacturer]" />
<RegistryValue Name="DisplayIcon" Type="string" Value="&quot;[INSTALLFOLDER]deckcraft.exe&quot;,0" />
<RegistryValue Name="InstallLocation" Type="string" Value="[INSTALLFOLDER]" />
<RegistryValue Name="URLInfoAbout" Type="string" Value="[ARPURLINFOABOUT]" />
<RegistryValue Name="URLUpdateInfo" Type="string" Value="[ARPURLUPDATEINFO]" />
<RegistryValue Name="HelpLink" Type="string" Value="[ARPHELPLINK]" />
<!-- Deliberately omit WindowsInstaller: Settings must honor UninstallString. -->
<RegistryValue Name="UninstallString" Type="string" Value="&quot;[$(var.CraftMsiSystemFolder)]msiexec.exe&quot; /x [ProductCode] /qf /norestart" />
<RegistryValue Name="QuietUninstallString" Type="string" Value="&quot;[$(var.CraftMsiSystemFolder)]msiexec.exe&quot; /x [ProductCode] /qn /norestart" />
<RegistryValue Name="ModifyPath" Type="string" Value="&quot;[$(var.CraftMsiSystemFolder)]msiexec.exe&quot; /i [ProductCode] /qf /norestart" />
</RegistryKey>
</Component>
<!-- Preserve the app-owned ARPNOMODIFY policy instead of inventing a new default. -->
<Component Id="CraftInstallerSettingsNoModify" Guid="*" Condition="ARPNOMODIFY = &quot;1&quot;">
<RegistryValue Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\Craft.deckcraft"
Name="NoModify" Type="integer" Value="1" KeyPath="yes" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
+1 -1
View File
@@ -93,7 +93,7 @@ Copy-Item (Join-Path $Bin 'deckcraft.exe'), (Join-Path $Bin 'deckcraft-cli.exe')
# ---- MSI ---------------------------------------------------------------------------------------
$Msi = Join-Path $Dist "deckcraft-$Version-windows-$Arch.msi"
Invoke-Native 'wix build' {
wix build (Join-Path $PSScriptRoot 'deckcraft.wxs') -arch $Arch `
wix build (Join-Path $PSScriptRoot 'deckcraft.wxs') (Join-Path $PSScriptRoot 'installer-ui.wxs') -arch $Arch `
-d "Version=$MsiVersion" -d "BinDir=$Stage" -d "IconPath=$(Join-Path $Root 'assets\app-icon\deckcraft.ico')" `
-o $Msi
}