tauri-bundler 2.0.4

Wrap rust executables in OS-specific app bundles for Tauri
Documentation
<?if $(sys.BUILDARCH)="x86"?>
    <?define Win64 = "no" ?>
    <?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?elseif $(sys.BUILDARCH)="x64"?>
    <?define Win64 = "yes" ?>
    <?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?elseif $(sys.BUILDARCH)="arm64"?>
    <?define Win64 = "yes" ?>
    <?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?else?>
    <?error Unsupported value of sys.BUILDARCH=$(sys.BUILDARCH)?>
<?endif?>

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product
            Id="*"
            Name="{{product_name}}"
            UpgradeCode="{{upgrade_code}}"
            Language="!(loc.TauriLanguage)"
            Manufacturer="{{manufacturer}}"
            Version="{{version}}">

        <Package Id="*"
                 Keywords="Installer"
                 InstallerVersion="450"
                 Languages="0"
                 Compressed="yes"
                 InstallScope="perMachine"
                 SummaryCodepage="!(loc.TauriCodepage)"/>

        <!-- https://docs.microsoft.com/en-us/windows/win32/msi/reinstallmode -->
        <!-- reinstall all files; rewrite all registry entries; reinstall all shortcuts -->
        <Property Id="REINSTALLMODE" Value="amus" />

        <!-- Auto launch app after installation, useful for passive mode which usually used in updates -->
        <Property Id="AUTOLAUNCHAPP" Secure="yes" />
        <!-- Property to forward cli args to the launched app to not lose those of the pre-update instance -->
        <Property Id="LAUNCHAPPARGS" Secure="yes" />

        {{#if allow_downgrades}}
            <MajorUpgrade Schedule="afterInstallInitialize" AllowDowngrades="yes" />
        {{else}}
            <MajorUpgrade Schedule="afterInstallInitialize" DowngradeErrorMessage="!(loc.DowngradeErrorMessage)" AllowSameVersionUpgrades="yes" />
        {{/if}}

        <InstallExecuteSequence>
            <RemoveShortcuts>Installed AND NOT UPGRADINGPRODUCTCODE</RemoveShortcuts>
        </InstallExecuteSequence>

        <Media Id="1" Cabinet="app.cab" EmbedCab="yes" />

        {{#if banner_path}}
        <WixVariable Id="WixUIBannerBmp" Value="{{banner_path}}" />
        {{/if}}
        {{#if dialog_image_path}}
        <WixVariable Id="WixUIDialogBmp" Value="{{dialog_image_path}}" />
        {{/if}}
        {{#if license}}
        <WixVariable Id="WixUILicenseRtf" Value="{{license}}" />
        {{/if}}

        <Icon Id="ProductIcon" SourceFile="{{icon_path}}"/>
        <Property Id="ARPPRODUCTICON" Value="ProductIcon" />
        <Property Id="ARPNOREPAIR" Value="yes" Secure="yes" />      <!-- Remove repair -->
        <SetProperty Id="ARPNOMODIFY" Value="1" After="InstallValidate" Sequence="execute"/>

        {{#if homepage}}
        <Property Id="ARPURLINFOABOUT" Value="{{homepage}}"/>
        <Property Id="ARPHELPLINK" Value="{{homepage}}"/>
        <Property Id="ARPURLUPDATEINFO" Value="{{homepage}}"/>
        {{/if}}

        <!-- initialize with previous InstallDir -->
        <Property Id="INSTALLDIR">
            <RegistrySearch Id="PrevInstallDirReg" Root="HKCU" Key="Software\\{{manufacturer}}\\{{product_name}}" Name="InstallDir" Type="raw"/>
        </Property>

        <!-- launch app checkbox -->
        <Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="!(loc.LaunchApp)" />
        <Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1"/>
        <CustomAction Id="LaunchApplication" Impersonate="yes" FileKey="Path" ExeCommand="[LAUNCHAPPARGS]" Return="asyncNoWait" />

        <UI>
            <!-- launch app checkbox -->
            <Publish Dialog="ExitDialog" Control="Finish" Event="DoAction" Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>

            <Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />

            {{#unless license}}
            <!-- Skip license dialog -->
            <Publish Dialog="WelcomeDlg"
                     Control="Next"
                     Event="NewDialog"
                     Value="InstallDirDlg"
                     Order="2">1</Publish>
            <Publish Dialog="InstallDirDlg"
                     Control="Back"
                     Event="NewDialog"
                     Value="WelcomeDlg"
                     Order="2">1</Publish>
            {{/unless}}
        </UI>

        <UIRef Id="WixUI_InstallDir" />

        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="DesktopFolder" Name="Desktop">
                <Component Id="ApplicationShortcutDesktop" Guid="*">
                    <Shortcut Id="ApplicationDesktopShortcut" Name="{{product_name}}" Description="Runs {{product_name}}" Target="[!Path]" WorkingDirectory="INSTALLDIR" />
                    <RemoveFolder Id="DesktopFolder" On="uninstall" />
                    <RegistryValue Root="HKCU" Key="Software\\{{manufacturer}}\\{{product_name}}" Name="Desktop Shortcut" Type="integer" Value="1" KeyPath="yes" />
                </Component>
            </Directory>
            <Directory Id="$(var.PlatformProgramFilesFolder)" Name="PFiles">
                <Directory Id="INSTALLDIR" Name="{{product_name}}"/>
            </Directory>
            <Directory Id="ProgramMenuFolder">
                <Directory Id="ApplicationProgramsFolder" Name="{{product_name}}"/>
            </Directory>
        </Directory>

        <DirectoryRef Id="INSTALLDIR">
            <Component Id="RegistryEntries" Guid="*">
                <RegistryKey Root="HKCU" Key="Software\\{{manufacturer}}\\{{product_name}}">
                    <RegistryValue Name="InstallDir" Type="string" Value="[INSTALLDIR]" KeyPath="yes" />
                </RegistryKey>
                <!-- Change the Root to HKCU for perUser installations -->
                {{#each deep_link_protocols as |protocol| ~}}
                <RegistryKey Root="HKLM" Key="Software\Classes\\{{protocol}}">
                    <RegistryValue Type="string" Name="URL Protocol" Value=""/>
                    <RegistryValue Type="string" Value="URL:{{bundle_id}} protocol"/>
                    <RegistryKey Key="DefaultIcon">
                        <RegistryValue Type="string" Value="&quot;[!Path]&quot;,0" />
                    </RegistryKey>
                    <RegistryKey Key="shell\open\command">
                        <RegistryValue Type="string" Value="&quot;[!Path]&quot; &quot;%1&quot;" />
                    </RegistryKey>
                </RegistryKey>
                {{/each~}}
            </Component>
            <Component Id="Path" Guid="{{path_component_guid}}" Win64="$(var.Win64)">
                <File Id="Path" Source="{{main_binary_path}}" KeyPath="yes" Checksum="yes"/>
                {{#each file_associations as |association| ~}}
                {{#each association.ext as |ext| ~}}
                <ProgId Id="{{../../product_name}}.{{ext}}" Advertise="yes" Description="{{association.description}}">
                    <Extension Id="{{ext}}" Advertise="yes">
                        <Verb Id="open" Command="Open with {{../../product_name}}" Argument="&quot;%1&quot;" />
                    </Extension>
                </ProgId>
                {{/each~}}
                {{/each~}}
            </Component>
            {{#each binaries as |bin| ~}}
            <Component Id="{{ bin.id }}" Guid="{{bin.guid}}" Win64="$(var.Win64)">
                <File Id="Bin_{{ bin.id }}" Source="{{bin.path}}" KeyPath="yes"/>
            </Component>
            {{/each~}}
            {{#if enable_elevated_update_task}}
            <Component Id="UpdateTask" Guid="C492327D-9720-4CD5-8DB8-F09082AF44BE" Win64="$(var.Win64)">
                <File Id="UpdateTask" Source="update.xml" KeyPath="yes" Checksum="yes"/>
            </Component>
            <Component Id="UpdateTaskInstaller" Guid="011F25ED-9BE3-50A7-9E9B-3519ED2B9932" Win64="$(var.Win64)">
                <File Id="UpdateTaskInstaller" Source="install-task.ps1" KeyPath="yes" Checksum="yes"/>
            </Component>
            <Component Id="UpdateTaskUninstaller" Guid="D4F6CC3F-32DC-5FD0-95E8-782FFD7BBCE1" Win64="$(var.Win64)">
                <File Id="UpdateTaskUninstaller" Source="uninstall-task.ps1" KeyPath="yes" Checksum="yes"/>
            </Component>
            {{/if}}
            {{resources}}
            <Component Id="CMP_UninstallShortcut" Guid="*">

                <Shortcut Id="UninstallShortcut"
						  Name="Uninstall {{product_name}}"
						  Description="Uninstalls {{product_name}}"
						  Target="[System64Folder]msiexec.exe"
						  Arguments="/x [ProductCode]" />

				<RemoveFolder Id="INSTALLDIR"
							  On="uninstall" />

				<RegistryValue Root="HKCU"
							   Key="Software\\{{manufacturer}}\\{{product_name}}"
							   Name="Uninstaller Shortcut"
							   Type="integer"
							   Value="1"
							   KeyPath="yes" />
            </Component>
        </DirectoryRef>

        <DirectoryRef Id="ApplicationProgramsFolder">
            <Component Id="ApplicationShortcut" Guid="*">
                <Shortcut Id="ApplicationStartMenuShortcut"
                    Name="{{product_name}}"
                    Description="Runs {{product_name}}"
                    Target="[!Path]"
                    Icon="ProductIcon"
                    WorkingDirectory="INSTALLDIR">
                    <ShortcutProperty Key="System.AppUserModel.ID" Value="{{bundle_id}}"/>
                </Shortcut>
                <RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
                <RegistryValue Root="HKCU" Key="Software\\{{manufacturer}}\\{{product_name}}" Name="Start Menu Shortcut" Type="integer" Value="1" KeyPath="yes"/>
           </Component>
        </DirectoryRef>

        {{#each merge_modules as |msm| ~}}
        <DirectoryRef Id="TARGETDIR">
            <Merge Id="{{ msm.name }}" SourceFile="{{ msm.path }}" DiskId="1" Language="!(loc.TauriLanguage)" />
        </DirectoryRef>

        <Feature Id="{{ msm.name }}" Title="{{ msm.name }}" AllowAdvertise="no" Display="hidden" Level="1">
            <MergeRef Id="{{ msm.name }}"/>
        </Feature>
        {{/each~}}

        <Feature
                Id="MainProgram"
                Title="Application"
                Description="!(loc.InstallAppFeature)"
                Level="1"
                ConfigurableDirectory="INSTALLDIR"
                AllowAdvertise="no"
                Display="expand"
                Absent="disallow">

            <ComponentRef Id="RegistryEntries"/>

            {{#each resource_file_ids as |resource_file_id| ~}}
                <ComponentRef Id="{{ resource_file_id }}"/>
            {{/each~}}

            {{#if enable_elevated_update_task}}
                <ComponentRef Id="UpdateTask" />
                <ComponentRef Id="UpdateTaskInstaller" />
                <ComponentRef Id="UpdateTaskUninstaller" />
            {{/if}}

            <Feature Id="ShortcutsFeature"
                Title="Shortcuts"
                Level="1">
                <ComponentRef Id="Path"/>
                <ComponentRef Id="CMP_UninstallShortcut" />
                <ComponentRef Id="ApplicationShortcut" />
                <ComponentRef Id="ApplicationShortcutDesktop" />
            </Feature>

            <Feature
                Id="Environment"
                Title="PATH Environment Variable"
                Description="!(loc.PathEnvVarFeature)"
                Level="1"
                Absent="allow">
            <ComponentRef Id="Path"/>
            {{#each binaries as |bin| ~}}
            <ComponentRef Id="{{ bin.id }}"/>
            {{/each~}}
            </Feature>
        </Feature>

        <Feature Id="External" AllowAdvertise="no" Absent="disallow">
            {{#each component_group_refs as |id| ~}}
            <ComponentGroupRef Id="{{ id }}"/>
            {{/each~}}
            {{#each component_refs as |id| ~}}
            <ComponentRef Id="{{ id }}"/>
            {{/each~}}
            {{#each feature_group_refs as |id| ~}}
            <FeatureGroupRef Id="{{ id }}"/>
            {{/each~}}
            {{#each feature_refs as |id| ~}}
            <FeatureRef Id="{{ id }}"/>
            {{/each~}}
            {{#each merge_refs as |id| ~}}
            <MergeRef Id="{{ id }}"/>
            {{/each~}}
        </Feature>

        {{#if install_webview}}
        <!-- WebView2 -->
        <Property Id="WVRTINSTALLED">
            <RegistrySearch Id="WVRTInstalledSystem" Root="HKLM" Key="SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" Name="pv" Type="raw" Win64="no" />
            <RegistrySearch Id="WVRTInstalledUser" Root="HKCU" Key="SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" Name="pv" Type="raw"/>
        </Property>

        {{#if download_bootstrapper}}
        <CustomAction Id='DownloadAndInvokeBootstrapper' Directory="INSTALLDIR" Execute="deferred" ExeCommand='powershell.exe -NoProfile -windowstyle hidden try [\{] [\[]Net.ServicePointManager[\]]::SecurityProtocol = [\[]Net.SecurityProtocolType[\]]::Tls12 [\}] catch [\{][\}]; Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/p/?LinkId=2124703" -OutFile "$env:TEMP\MicrosoftEdgeWebview2Setup.exe" ; Start-Process -FilePath "$env:TEMP\MicrosoftEdgeWebview2Setup.exe" -ArgumentList ({{webview_installer_args}} &apos;/install&apos;) -Wait' Return='check'/>
        <InstallExecuteSequence>
            <Custom Action='DownloadAndInvokeBootstrapper' Before='InstallFinalize'>
                <![CDATA[NOT(REMOVE OR WVRTINSTALLED)]]>
            </Custom>
        </InstallExecuteSequence>
        {{/if}}

        <!-- Embedded webview bootstrapper mode -->
        {{#if webview2_bootstrapper_path}}
        <Binary Id="MicrosoftEdgeWebview2Setup.exe" SourceFile="{{webview2_bootstrapper_path}}"/>
        <CustomAction Id='InvokeBootstrapper' BinaryKey='MicrosoftEdgeWebview2Setup.exe' Execute="deferred" ExeCommand='{{webview_installer_args}} /install' Return='check' />
        <InstallExecuteSequence>
            <Custom Action='InvokeBootstrapper' Before='InstallFinalize'>
                <![CDATA[NOT(REMOVE OR WVRTINSTALLED)]]>
            </Custom>
        </InstallExecuteSequence>
        {{/if}}

        <!-- Embedded offline installer -->
        {{#if webview2_installer_path}}
        <Binary Id="MicrosoftEdgeWebView2RuntimeInstaller.exe" SourceFile="{{webview2_installer_path}}"/>
        <CustomAction Id='InvokeStandalone' BinaryKey='MicrosoftEdgeWebView2RuntimeInstaller.exe' Execute="deferred" ExeCommand='{{webview_installer_args}} /install' Return='check' />
        <InstallExecuteSequence>
            <Custom Action='InvokeStandalone' Before='InstallFinalize'>
                <![CDATA[NOT(REMOVE OR WVRTINSTALLED)]]>
            </Custom>
        </InstallExecuteSequence>
        {{/if}}

        {{/if}}

        {{#if enable_elevated_update_task}}
        <!-- Install an elevated update task within Windows Task Scheduler -->
        <CustomAction
            Id="CreateUpdateTask"
            Return="check"
            Directory="INSTALLDIR"
            Execute="commit"
            Impersonate="yes"
            ExeCommand="powershell.exe -WindowStyle hidden .\install-task.ps1" />
        <InstallExecuteSequence>
            <Custom Action='CreateUpdateTask' Before='InstallFinalize'>
                NOT(REMOVE)
            </Custom>
        </InstallExecuteSequence>
        <!-- Remove elevated update task during uninstall -->
        <CustomAction
            Id="DeleteUpdateTask"
            Return="check"
            Directory="INSTALLDIR"
            ExeCommand="powershell.exe -WindowStyle hidden .\uninstall-task.ps1" />
        <InstallExecuteSequence>
            <Custom Action="DeleteUpdateTask" Before='InstallFinalize'>
                (REMOVE = "ALL") AND NOT UPGRADINGPRODUCTCODE
            </Custom>
        </InstallExecuteSequence>
        {{/if}}

        <InstallExecuteSequence>
          <Custom Action="LaunchApplication" After="InstallFinalize">AUTOLAUNCHAPP AND NOT Installed</Custom>
        </InstallExecuteSequence>

        <SetProperty Id="ARPINSTALLLOCATION" Value="[INSTALLDIR]" After="CostFinalize"/>
    </Product>
</Wix>