Merge pull request #2560 from benandez/feat/39-per-user-msi

#39: per-user Windows installer that needs no administrator rights
This commit is contained in:
Dylan M. Taylor authored and GitHub committed 2026-10-25 20:37:35 -04:00
commit d7530233cc
5 files changed
+88 -65

No files matched your search

+9 -6
View File
@@ -221,13 +221,16 @@ closer pagination fidelity, a stability sweep and native printing. Details and e
### Windows
| Build | Installer | Portable |
|---|---|---|
| x64 (64-bit Intel/AMD) | `wordcraft-<ver>-windows-x64.msi` | `wordcraft-<ver>-windows-x64-portable.zip` |
| arm64 (Snapdragon and other ARM PCs) | `wordcraft-<ver>-windows-arm64.msi` | `wordcraft-<ver>-windows-arm64-portable.zip` |
| x86 (32-bit) | `wordcraft-<ver>-windows-x86.msi` | `wordcraft-<ver>-windows-x86-portable.zip` |
| Build | Installer (all users) | Installer (just me) | Portable |
|---|---|---|---|
| x64 (64-bit Intel/AMD) | `wordcraft-<ver>-windows-x64.msi` | `wordcraft-<ver>-windows-user-x64.msi` | `wordcraft-<ver>-windows-x64-portable.zip` |
| arm64 (Snapdragon and other ARM PCs) | `wordcraft-<ver>-windows-arm64.msi` | `wordcraft-<ver>-windows-user-arm64.msi` | `wordcraft-<ver>-windows-arm64-portable.zip` |
| x86 (32-bit) | `wordcraft-<ver>-windows-x86.msi` | `wordcraft-<ver>-windows-user-x86.msi` | `wordcraft-<ver>-windows-x86-portable.zip` |
Installers and executables are code-signed.
The all-users installer puts WordCraft in Program Files and needs administrator rights. The
just-me installer needs none: it installs into `%LOCALAPPDATA%\Programs\WordCraft` for your
account only. Choose one: installing both gives two WordCraft entries in Settings › Apps and two
in the Start menu. Installers and executables are code-signed.
**If the app doesn't open on Windows:** the desktop app initializes only DirectX 12 by default.
Letting wgpu also create an OpenGL instance can crash some graphics drivers (AMD's
+1
View File
@@ -210,6 +210,7 @@ Imported Word 97–2003 `.doc`/`.dot` files now ask for a supported DOCX target
| 2026-10-20 | Restrict Editing holds for the file commands too: the privacy options, the properties and the inspector's removals are refused on a protected document, and restoring a stored version keeps the protection and its password instead of the snapshot's stale ones |
| 2026-10-17 | Ribbon hints' reasons for a greyed-out control are translated in every interface language; a test fails if a reason it finds in the command sources, or the "Open a document first" hint, has no translation (#2678). |
| 2026-10-17 | Ribbon hover hints: a disabled control says why (the command's own reason), split-button arrows, menu buttons and the font, size and outline boxes have hints, and hints show on keyboard focus (#1086). |
| 2026-10-16 | Windows per-user installer (#39): each release also ships `wordcraft-<ver>-windows-user-<arch>.msi`, built from the same WiX source as a dual-purpose package, so it installs into `%LOCALAPPDATA%\Programs` for the current user with no administrator rights; registry keys moved to HKMU so both installers share one set of components |
| 2026-10-14 | DOCX row table border exceptions render and survive saving. Explicit cell borders win; a row exception does not change other rows. |
| 2026-10-14 | Tab stops edited on the ruler: the corner selector picks Left/Center/Right/Decimal/Bar, a click sets a stop (Alt skips the snap), dragging moves it with a guide line and position tooltip, dragging off the ruler clears it; markers draw per kind and mirror for RTL; one `para.tabs` call and one undo step per gesture |
| 2026-10-12 | Fields keep `w:dirty` through DOCX saves (#877): a begin marker flagged by a generator that couldn't compute a result (pandoc-style TOC placeholders) keeps the flag on open/save — as a buffered field or a range field — so Word still refreshes it on open; computing a result (Update Field, Update Table) clears it, like Word's F9 |
+1 -1
View File
@@ -11,7 +11,7 @@ this file has the WordCraft specifics.
| Platform | Artifacts | Signing |
|---|---|---|
| macOS | universal `WordCraft.app` in a `.dmg`, universal CLI zip | Developer ID + notarization (`APPLE_*` secrets) |
| Windows | x64, x86 and arm64 `.msi` + portable `.zip` | Azure Trusted Signing (`AZURE_*` secrets) |
| Windows | x64, x86 and arm64 `.msi` (per-machine, and a per-user `-windows-user-<arch>.msi` that needs no admin rights) + portable `.zip` | Azure Trusted Signing (`AZURE_*` secrets) |
| Linux | x86_64 and aarch64 `.AppImage` (+ `.zsync` for AppImageUpdate), `.flatpak` bundle, `.deb`, `.rpm`, `.tar.gz`; Flathub manifest | checksums |
| Linux riscv64 | `.tar.gz` (cross-compiled on `ubuntu-24.04`, glibc >= 2.39; CLI smoke-tested under QEMU) | checksums |
| FreeBSD | x86_64 `.tar.gz` | checksums |
+20 -11
View File
@@ -5,6 +5,7 @@
.DESCRIPTION
Produces, in $env:DIST (default: dist/release):
wordcraft-<version>-windows-<arch>.msi per-machine installer (WiX v5)
wordcraft-<version>-windows-user-<arch>.msi per-user installer, no admin rights (#39)
wordcraft-<version>-windows-<arch>-portable.zip wordcraft.exe + wordcraft-cli.exe
The binaries link the C runtime statically (+crt-static), so neither the MSI nor the portable
@@ -142,18 +143,26 @@ $rtf = '{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss\fcharset0 Tahoma;}}\vi
($paragraphs -join "\par`r`n") + "\par`r`n}`r`n"
[System.IO.File]::WriteAllText($LicenseRtf, $rtf, [System.Text.Encoding]::ASCII)
# Two MSIs from one source: per-machine (Program Files, needs admin) and per-user (#39: no admin,
# into %LOCALAPPDATA%\Programs; see wordcraft.wxs). The per-user name puts "user" before the arch
# so the per-machine MSI sorts first: the shared windows-arm64 workflow installs the first *.msi
# it finds and checks Program Files.
$Msi = Join-Path $Dist "wordcraft-$Version-windows-$Arch.msi"
Invoke-Native 'wix build' {
wix build (Join-Path $PSScriptRoot 'wordcraft.wxs') -arch $Arch `
-ext WixToolset.UI.wixext -ext WixToolset.Util.wixext `
-d "Version=$MsiVersion" -d "BinDir=$Stage" -d "IconPath=$(Join-Path $Root 'assets\app-icon\wordcraft.ico')" `
-d "LicenseRtf=$LicenseRtf" `
-d "AppNoticesDir=$AppNotices" -d "DocsDir=$Docs" -d "HasCraftFontLicences=$HasCraftFontLicences" `
-o $Msi
$UserMsi = Join-Path $Dist "wordcraft-$Version-windows-user-$Arch.msi"
foreach ($build in @(@($Msi, 'perMachine'), @($UserMsi, 'perUserOrMachine'))) {
$out = $build[0]
Invoke-Native "wix build ($($build[1]))" {
wix build (Join-Path $PSScriptRoot 'wordcraft.wxs') -arch $Arch `
-ext WixToolset.UI.wixext -ext WixToolset.Util.wixext `
-d "Version=$MsiVersion" -d "BinDir=$Stage" -d "IconPath=$(Join-Path $Root 'assets\app-icon\wordcraft.ico')" `
-d "LicenseRtf=$LicenseRtf" `
-d "AppNoticesDir=$AppNotices" -d "DocsDir=$Docs" -d "HasCraftFontLicences=$HasCraftFontLicences" -d "Scope=$($build[1])" `
-o $out
}
# wix writes its debug symbols (.wixpdb) next to the MSI; keep them out of the release assets.
Remove-Item -Force -ErrorAction SilentlyContinue ([IO.Path]::ChangeExtension($out, '.wixpdb'))
& (Join-Path $PSScriptRoot 'sign.ps1') $out
}
# wix writes its debug symbols (.wixpdb) next to the MSI; keep them out of the release assets.
Remove-Item -Force -ErrorAction SilentlyContinue ([IO.Path]::ChangeExtension($Msi, '.wixpdb'))
& (Join-Path $PSScriptRoot 'sign.ps1') $Msi
# ---- portable zip ------------------------------------------------------------------------------
$Portable = Join-Path $TargetDir "windows-package\wordcraft-$Version-windows-$Arch-portable"
@@ -182,4 +191,4 @@ if ($Arch -ne 'arm64' -or $HostArch -eq 'arm64') {
} else {
Write-Output "skipping wordcraft-cli --version: an $Arch build doesn't run on this $HostArch machine"
}
Get-Item $Msi, $Zip | Format-Table Name, Length
Get-Item $Msi, $UserMsi, $Zip | Format-Table Name, Length
+57 -47
View File
@@ -5,16 +5,26 @@
Built by package.ps1:
wix build wordcraft.wxs -arch x64 -ext WixToolset.UI.wixext -ext WixToolset.Util.wixext
-d Version=1.2.3 -d BinDir=... -d IconPath=... -d LicenseRtf=... -o out.msi
-d Version=1.2.3 -d BinDir=... -d IconPath=... -d LicenseRtf=... [-d Scope=perUserOrMachine] -o out.msi
Per-machine install into Program Files with a Start Menu shortcut. The installer shows the
standard WiX dialogs: welcome + license, progress, and a finish page.
Built a second time with -d Scope=perUserOrMachine for people without administrator rights
(#39): a dual-purpose package that WiX gives ALLUSERS=2 and MSIINSTALLPERUSER=1, so it installs
for the current user with no UAC prompt. Windows then redirects Program Files to
%LOCALAPPDATA%\Programs, the Start Menu to the user's own, and HKMU to HKCU, so the same
components work in both packages. Both share the UpgradeCode: each upgrades its own earlier
versions (Windows Installer only matches products installed in the same context).
UpgradeCode and the component GUIDs below belong to WordCraft alone. Never copy them from (or
into) a sibling Craft app: Windows Installer treats every package sharing an UpgradeCode as one
product, so a shared code makes one app's installer refuse to install ("a newer version is
already installed") or silently uninstall the other. packaging-lint.yml checks this.
-->
<?ifndef Scope?>
<?define Scope = perMachine?>
<?endif?>
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
<?ifndef HasCraftFontLicences ?>
<?define HasCraftFontLicences=0 ?>
@@ -24,7 +34,7 @@
Manufacturer="Learning Machines LLC"
Version="$(var.Version)"
UpgradeCode="075497F9-E861-45D0-9C7F-A74F8C34E6BA"
Scope="perMachine"
Scope="$(var.Scope)"
Compressed="yes"
Language="1033">
<SummaryInformation Description="WordCraft word processor" Manufacturer="Learning Machines LLC" />
@@ -88,7 +98,7 @@
Icon="WordcraftIcon.ico" IconIndex="0" />
</File>
<RegistryValue Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\App Paths\wordcraft.exe" Value="[#WordcraftExe]" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Microsoft\Windows\CurrentVersion\App Paths\wordcraft.exe" Value="[#WordcraftExe]" Type="string" />
</Component>
<!-- File associations (#295). Each document type gets a WordCraft ProgId (name, icon, open
@@ -99,70 +109,70 @@
extension's default: the installer never takes over .docx from another app. Markdown and
plain text are only "Open with" candidates. Removed again on uninstall. -->
<Component Id="WordcraftFileTypes" Guid="EFF89E6A-F9B8-49F9-B3AE-E243347484B4">
<RegistryValue Root="HKLM" Key="Software\RegisteredApplications" Name="WordCraft" Value="Software\WordCraft\Capabilities" Type="string" KeyPath="yes" />
<RegistryValue Root="HKLM" Key="Software\WordCraft\Capabilities" Name="ApplicationName" Value="WordCraft" Type="string" />
<RegistryValue Root="HKLM" Key="Software\WordCraft\Capabilities" Name="ApplicationDescription" Value="Write and design documents; open and save Word files." Type="string" />
<RegistryValue Root="HKLM" Key="Software\WordCraft\Capabilities" Name="ApplicationIcon" Value="&quot;[#WordcraftExe]&quot;,0" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\wordcraft.exe" Name="FriendlyAppName" Value="WordCraft" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\wordcraft.exe\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKMU" Key="Software\RegisteredApplications" Name="WordCraft" Value="Software\WordCraft\Capabilities" Type="string" KeyPath="yes" />
<RegistryValue Root="HKMU" Key="Software\WordCraft\Capabilities" Name="ApplicationName" Value="WordCraft" Type="string" />
<RegistryValue Root="HKMU" Key="Software\WordCraft\Capabilities" Name="ApplicationDescription" Value="Write and design documents; open and save Word files." Type="string" />
<RegistryValue Root="HKMU" Key="Software\WordCraft\Capabilities" Name="ApplicationIcon" Value="&quot;[#WordcraftExe]&quot;,0" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\Applications\wordcraft.exe" Name="FriendlyAppName" Value="WordCraft" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\Applications\wordcraft.exe\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<ProgId Id="WordCraft.Document" Description="Word Document" Icon="WordcraftExe" IconIndex="0" />
<RegistryValue Root="HKLM" Key="Software\Classes\WordCraft.Document\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\.docx\OpenWithProgids" Name="WordCraft.Document" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".docx" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\WordCraft\Capabilities\FileAssociations" Name=".docx" Value="WordCraft.Document" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\WordCraft.Document\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\.docx\OpenWithProgids" Name="WordCraft.Document" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".docx" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\WordCraft\Capabilities\FileAssociations" Name=".docx" Value="WordCraft.Document" Type="string" />
<ProgId Id="WordCraft.DocumentMacroEnabled" Description="Word Macro-Enabled Document" Icon="WordcraftExe" IconIndex="0" />
<RegistryValue Root="HKLM" Key="Software\Classes\WordCraft.DocumentMacroEnabled\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\.docm\OpenWithProgids" Name="WordCraft.DocumentMacroEnabled" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".docm" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\WordCraft\Capabilities\FileAssociations" Name=".docm" Value="WordCraft.DocumentMacroEnabled" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\WordCraft.DocumentMacroEnabled\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\.docm\OpenWithProgids" Name="WordCraft.DocumentMacroEnabled" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".docm" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\WordCraft\Capabilities\FileAssociations" Name=".docm" Value="WordCraft.DocumentMacroEnabled" Type="string" />
<ProgId Id="WordCraft.Template" Description="Word Template" Icon="WordcraftExe" IconIndex="0" />
<RegistryValue Root="HKLM" Key="Software\Classes\WordCraft.Template\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\.dotx\OpenWithProgids" Name="WordCraft.Template" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".dotx" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\WordCraft\Capabilities\FileAssociations" Name=".dotx" Value="WordCraft.Template" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\WordCraft.Template\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\.dotx\OpenWithProgids" Name="WordCraft.Template" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".dotx" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\WordCraft\Capabilities\FileAssociations" Name=".dotx" Value="WordCraft.Template" Type="string" />
<ProgId Id="WordCraft.TemplateMacroEnabled" Description="Word Macro-Enabled Template" Icon="WordcraftExe" IconIndex="0" />
<RegistryValue Root="HKLM" Key="Software\Classes\WordCraft.TemplateMacroEnabled\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\.dotm\OpenWithProgids" Name="WordCraft.TemplateMacroEnabled" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".dotm" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\WordCraft\Capabilities\FileAssociations" Name=".dotm" Value="WordCraft.TemplateMacroEnabled" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\WordCraft.TemplateMacroEnabled\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\.dotm\OpenWithProgids" Name="WordCraft.TemplateMacroEnabled" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".dotm" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\WordCraft\Capabilities\FileAssociations" Name=".dotm" Value="WordCraft.TemplateMacroEnabled" Type="string" />
<ProgId Id="WordCraft.LegacyDocument" Description="Legacy Word Document" Icon="WordcraftExe" IconIndex="0" />
<RegistryValue Root="HKLM" Key="Software\Classes\WordCraft.LegacyDocument\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\.doc\OpenWithProgids" Name="WordCraft.LegacyDocument" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".doc" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\WordCraft\Capabilities\FileAssociations" Name=".doc" Value="WordCraft.LegacyDocument" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\WordCraft.LegacyDocument\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\.doc\OpenWithProgids" Name="WordCraft.LegacyDocument" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".doc" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\WordCraft\Capabilities\FileAssociations" Name=".doc" Value="WordCraft.LegacyDocument" Type="string" />
<ProgId Id="WordCraft.LegacyTemplate" Description="Legacy Word Template" Icon="WordcraftExe" IconIndex="0" />
<RegistryValue Root="HKLM" Key="Software\Classes\WordCraft.LegacyTemplate\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\.dot\OpenWithProgids" Name="WordCraft.LegacyTemplate" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".dot" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\WordCraft\Capabilities\FileAssociations" Name=".dot" Value="WordCraft.LegacyTemplate" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\WordCraft.LegacyTemplate\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\.dot\OpenWithProgids" Name="WordCraft.LegacyTemplate" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".dot" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\WordCraft\Capabilities\FileAssociations" Name=".dot" Value="WordCraft.LegacyTemplate" Type="string" />
<ProgId Id="WordCraft.RichText" Description="Rich Text Document" Icon="WordcraftExe" IconIndex="0" />
<RegistryValue Root="HKLM" Key="Software\Classes\WordCraft.RichText\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\.rtf\OpenWithProgids" Name="WordCraft.RichText" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".rtf" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\WordCraft\Capabilities\FileAssociations" Name=".rtf" Value="WordCraft.RichText" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\WordCraft.RichText\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\.rtf\OpenWithProgids" Name="WordCraft.RichText" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".rtf" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\WordCraft\Capabilities\FileAssociations" Name=".rtf" Value="WordCraft.RichText" Type="string" />
<ProgId Id="WordCraft.OpenDocumentText" Description="OpenDocument Text" Icon="WordcraftExe" IconIndex="0" />
<RegistryValue Root="HKLM" Key="Software\Classes\WordCraft.OpenDocumentText\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\.odt\OpenWithProgids" Name="WordCraft.OpenDocumentText" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".odt" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\WordCraft\Capabilities\FileAssociations" Name=".odt" Value="WordCraft.OpenDocumentText" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\WordCraft.OpenDocumentText\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\.odt\OpenWithProgids" Name="WordCraft.OpenDocumentText" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".odt" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\WordCraft\Capabilities\FileAssociations" Name=".odt" Value="WordCraft.OpenDocumentText" Type="string" />
<ProgId Id="WordCraft.Markdown" Description="Markdown Document" Icon="WordcraftExe" IconIndex="0" />
<RegistryValue Root="HKLM" Key="Software\Classes\WordCraft.Markdown\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\.md\OpenWithProgids" Name="WordCraft.Markdown" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".md" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\WordCraft.Markdown\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\.md\OpenWithProgids" Name="WordCraft.Markdown" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".md" Value="" Type="string" />
<ProgId Id="WordCraft.PlainText" Description="Text Document" Icon="WordcraftExe" IconIndex="0" />
<RegistryValue Root="HKLM" Key="Software\Classes\WordCraft.PlainText\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\.txt\OpenWithProgids" Name="WordCraft.PlainText" Value="" Type="string" />
<RegistryValue Root="HKLM" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".txt" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\WordCraft.PlainText\shell\open\command" Value="&quot;[#WordcraftExe]&quot; &quot;%1&quot;" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\.txt\OpenWithProgids" Name="WordCraft.PlainText" Value="" Type="string" />
<RegistryValue Root="HKMU" Key="Software\Classes\Applications\wordcraft.exe\SupportedTypes" Name=".txt" Value="" Type="string" />
</Component>
<Component Id="WordcraftCli">