Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

msi (un)installer support #23

Closed
Gankra opened this issue Oct 24, 2022 · 9 comments
Closed

msi (un)installer support #23

Gankra opened this issue Oct 24, 2022 · 9 comments
Assignees
Labels
feature request - new integration feature request New feature or request help wanted Extra attention is needed
Milestone

Comments

@Gankra
Copy link
Member

Gankra commented Oct 24, 2022

This would be another potential killer app, but should be out of scope for the MVP.

@Gankra Gankra added this to the future milestone Oct 24, 2022
@Gankra Gankra added feature request New feature or request help wanted Extra attention is needed labels Feb 1, 2023
@CAD97
Copy link

CAD97 commented Feb 2, 2023

cargo-wix uses the WiX toolset to generate MSI installers.

Most of its functionality is available through the library crate and could be reused by cargo-dist. (Though obviously this will require installing the WiX toolset on CI and having cargo-wix initialized.)

@Gankra
Copy link
Member Author

Gankra commented Feb 2, 2023

Hell yes I was meaning to look into wix stuff. Here's my adventure blindly trying to run cargo-wix (documenting every excrutiating detail here is a good first step for figuring out what needs to be automated/documented):

  • cargo-wix doesn't like workspaces, wants you to manually pass --package to pick what to init/build
    • ERROR: Workspace detected. Please pass a package name.
  • cargo wix init creates a wix/main.wxs file in the package's root dir
  • errors out if authors isn't specified in Cargo.toml
    • No 'authors' field found in the package's manifest (Cargo.toml)
  • complains about licenses
    • WARN: An EULA was not specified at the command line, a RTF license file was not specified in the package manifest's (Cargo.toml) 'license-file' field, or the license ID from the package manifest's 'license' field is not recognized. The license agreement dialog will be excluded from the installer. An EULA can be added manually to the generated WiX Source (wxs) file using a text editor.
    • WARN: A license file could not be found and it will be excluded from the installer. A license file can be added manually to the generated WiX Source (wxs) file using a text editor.
  • dies due to wix toolset not being installed, but tells you what to do
    • ERROR: The compiler application (candle) could not be found in the PATH environment variable. Please check the WiX Toolset (http://wixtoolset.org/) is installed and check the WiX Toolset's 'bin' folder has been added to the PATH system environment variable, the WIX system environment variable exists, or use the '-b,--bin-path' command line argument.
  • clicked through and installed the visual studio 2019 extension: https://marketplace.visualstudio.com/items?itemName=WixToolset.WixToolsetVisualStudio2019Extension
    • This was insufficient
  • Says to install this https://marketplace.visualstudio.com/items?itemName=WixToolset.WiXToolset
  • dotnet tool install --global wix --version 4.0.0-rc.2..?
    • ERROR: NU1202: Package wix 4.0.0-rc.2 is not compatible with net5.0 (.NETCoreApp,Version=v5.0) / any. Package wix 4.0.0-rc.2 supports: net6.0
  • https://wixtoolset.org/docs/wix3/
  • wix --version still fails :(
    • rebooting doesn't help
  • check visual studio extension, wix v3 extension is setup but there's a "build tools" extension i can install
    • ...just links the v4 prerelease page again :(
  • wait fuck trying to run wix --version was a trap, cargo wix works now!
    • target\wix\cargo-dist-0.0.2-x86_64.msi is built!
    • holy shit puts it on PATH!
    • completes succesfully!
    • ...needs windows terminal to be restarted to kick in!
    • works!

Screenshot 2023-02-02 035946

@Gankra
Copy link
Member Author

Gankra commented Feb 2, 2023

image

uninstall button also works :)

@Gankra
Copy link
Member Author

Gankra commented Feb 2, 2023

Generated wix file:

main.wxs
<?xml version='1.0' encoding='windows-1252'?>
<!--
  Copyright (C) 2017 Christopher R. Field.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->

<!--
  The "cargo wix" subcommand provides a variety of predefined variables available
  for customization of this template. The values for each variable are set at
  installer creation time. The following variables are available:

  TargetTriple      = The rustc target triple name.
  TargetEnv         = The rustc target environment. This is typically either
                      "msvc" or "gnu" depending on the toolchain downloaded and
                      installed.
  TargetVendor      = The rustc target vendor. This is typically "pc", but Rust
                      does support other vendors, like "uwp".
  CargoTargetBinDir = The complete path to the binary (exe). The default would
                      be "target\release\<BINARY_NAME>.exe" where
                      "<BINARY_NAME>" is replaced with the name of each binary
                      target defined in the package's manifest (Cargo.toml). If
                      a different rustc target triple is used than the host,
                      i.e. cross-compiling, then the default path would be
                      "target\<CARGO_TARGET>\<CARGO_PROFILE>\<BINARY_NAME>.exe",
                      where "<CARGO_TARGET>" is replaced with the "CargoTarget"
                      variable value and "<CARGO_PROFILE>" is replaced with the
                      value from the `CargoProfile` variable.
  CargoTargetDir    = The path to the directory for the build artifacts, i.e.
                      "target".
  CargoProfile      = Either "debug" or `release` depending on the build
                      profile. The default is "release".
  Version           = The version for the installer. The default is the
                      "Major.Minor.Fix" semantic versioning number of the Rust
                      package.
-->

<!--
  Please do not remove these pre-processor If-Else blocks. These are used with
  the `cargo wix` subcommand to automatically determine the installation
  destination for 32-bit versus 64-bit installers. Removal of these lines will
  cause installation errors.
-->
<?if $(sys.BUILDARCH) = x64 or $(sys.BUILDARCH) = arm64 ?>
    <?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
<?else ?>
    <?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
<?endif ?>

<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>

    <Product
        Id='*'
        Name='cargo-dist'
        UpgradeCode='4D4C432C-7E23-4B3A-97AB-3743D86C3394'
        Manufacturer='axo.dev'
        Language='1033'
        Codepage='1252'
        Version='$(var.Version)'>

        <Package Id='*'
            Keywords='Installer'
            Description='Shippable application packaging for Rust'
            Manufacturer='axo.dev'
            InstallerVersion='450'
            Languages='1033'
            Compressed='yes'
            InstallScope='perMachine'
            SummaryCodepage='1252'
            />

        <MajorUpgrade
            Schedule='afterInstallInitialize'
            DowngradeErrorMessage='A newer version of [ProductName] is already installed. Setup will now exit.'/>

        <Media Id='1' Cabinet='media1.cab' EmbedCab='yes' DiskPrompt='CD-ROM #1'/>
        <Property Id='DiskPrompt' Value='cargo-dist Installation'/>

        <Directory Id='TARGETDIR' Name='SourceDir'>
            <Directory Id='$(var.PlatformProgramFilesFolder)' Name='PFiles'>
                <Directory Id='APPLICATIONFOLDER' Name='cargo-dist'>

                    <!--
                      Enabling the license sidecar file in the installer is a four step process:

                      1. Uncomment the `Component` tag and its contents.
                      2. Change the value for the `Source` attribute in the `File` tag to a path
                         to the file that should be included as the license sidecar file. The path
                         can, and probably should be, relative to this file.
                      3. Change the value for the `Name` attribute in the `File` tag to the
                         desired name for the file when it is installed alongside the `bin` folder
                         in the installation directory. This can be omitted if the desired name is
                         the same as the file name.
                      4. Uncomment the `ComponentRef` tag with the Id attribute value of "License"
                         further down in this file.
                    -->
                    <!--
                    <Component Id='License' Guid='*'>
                        <File Id='LicenseFile' Name='ChangeMe' DiskId='1' Source='C:\Path\To\File' KeyPath='yes'/>
                    </Component>
                    -->

                    <Directory Id='Bin' Name='bin'>
                        <Component Id='Path' Guid='2D7256A0-9B38-4932-A9B1-9B35B4BC22BA' KeyPath='yes'>
                            <Environment
                                Id='PATH'
                                Name='PATH'
                                Value='[Bin]'
                                Permanent='no'
                                Part='last'
                                Action='set'
                                System='yes'/>
                        </Component>
                        <Component Id='binary0' Guid='*'>
                            <File
                                Id='exe0'
                                Name='cargo-dist.exe'
                                DiskId='1'
                                Source='$(var.CargoTargetBinDir)\cargo-dist.exe'
                                KeyPath='yes'/>
                        </Component>
                    </Directory>
                </Directory>
            </Directory>
        </Directory>

        <Feature
            Id='Binaries'
            Title='Application'
            Description='Installs all binaries and the license.'
            Level='1'
            ConfigurableDirectory='APPLICATIONFOLDER'
            AllowAdvertise='no'
            Display='expand'
            Absent='disallow'>

            <!--
              Uncomment the following `ComponentRef` tag to add the license
              sidecar file to the installer.
            -->
            <!--<ComponentRef Id='License'/>-->

            <ComponentRef Id='binary0'/>

            <Feature
                Id='Environment'
                Title='PATH Environment Variable'
                Description='Add the install location of the [ProductName] executable to the PATH system environment variable. This allows the [ProductName] executable to be called from any location.'
                Level='1'
                Absent='allow'>
                <ComponentRef Id='Path'/>
            </Feature>
        </Feature>

        <SetProperty Id='ARPINSTALLLOCATION' Value='[APPLICATIONFOLDER]' After='CostFinalize'/>


        <!--
          Uncomment the following `Icon` and `Property` tags to change the product icon.

          The product icon is the graphic that appears in the Add/Remove
          Programs control panel for the application.
        -->
        <!--<Icon Id='ProductICO' SourceFile='wix\Product.ico'/>-->
        <!--<Property Id='ARPPRODUCTICON' Value='ProductICO' />-->

        <Property Id='ARPHELPLINK' Value='https://github.com/axodotdev/cargo-dist'/>

        <UI>
            <UIRef Id='WixUI_FeatureTree'/>

            <!--
              Enabling the EULA dialog in the installer is a three step process:

                1. Comment out or remove the two `Publish` tags that follow the
                   `WixVariable` tag.
                2. Uncomment the `<WixVariable Id='WixUILicenseRtf' Value='Path\to\Eula.rft'>` tag futher down
                3. Replace the `Value` attribute of the `WixVariable` tag with
                   the path to a RTF file that will be used as the EULA and
                   displayed in the license agreement dialog.
            -->
            <Publish Dialog='WelcomeDlg' Control='Next' Event='NewDialog' Value='CustomizeDlg' Order='99'>1</Publish>
            <Publish Dialog='CustomizeDlg' Control='Back' Event='NewDialog' Value='WelcomeDlg' Order='99'>1</Publish>

        </UI>


        <!--
          Enabling the EULA dialog in the installer requires uncommenting
          the following `WixUILicenseRTF` tag and changing the `Value`
          attribute.
        -->
        <!-- <WixVariable Id='WixUILicenseRtf' Value='Relative\Path\to\Eula.rtf'/> -->


        <!--
          Uncomment the next `WixVariable` tag to customize the installer's
          Graphical User Interface (GUI) and add a custom banner image across
          the top of each screen. See the WiX Toolset documentation for details
          about customization.

          The banner BMP dimensions are 493 x 58 pixels.
        -->
        <!--<WixVariable Id='WixUIBannerBmp' Value='wix\Banner.bmp'/>-->


        <!--
          Uncomment the next `WixVariable` tag to customize the installer's
          Graphical User Interface (GUI) and add a custom image to the first
          dialog, or screen. See the WiX Toolset documentation for details about
          customization.

          The dialog BMP dimensions are 493 x 312 pixels.
        -->
        <!--<WixVariable Id='WixUIDialogBmp' Value='wix\Dialog.bmp'/>-->

    </Product>

</Wix>

Looks like there's appropriate hooks for telling it where to grab the binary. We can also potentially manually provide better license info since we sniff out LICENSE* files. Although idk if it hates the idea of two licenses (dual MIT/Apache being standard).

@Gankra
Copy link
Member Author

Gankra commented Aug 17, 2023

Some upstream cargo-wix work: volks73/cargo-wix#198

@Gankra
Copy link
Member Author

Gankra commented Aug 17, 2023

UX is pretty miserable once you put it on the internet and download it (WITHOUT signing) -- windows throws up 3 barriers to getting to the actual installer:

image
image
image
image

So while I might land signing-less support for this initially, working out the story for signing will be pretty important for making this Good (cargo-wix can dispatch to windows signtool, but still need to tell users how the heck to setup signtool certs).

@Gankra Gankra self-assigned this Aug 29, 2023
@Gankra
Copy link
Member Author

Gankra commented Aug 29, 2023

I have a prototype of this in #370, pending some upstream work on cargo-wix.

@Gankra
Copy link
Member Author

Gankra commented Sep 13, 2023

cargo-dist v0.3.0-prerelease.5 has an I think shippable mvp, I just need to write the docs.

@Gankra
Copy link
Member Author

Gankra commented Sep 18, 2023

Closing in favour of #432 just so I don't forget what's left

@Gankra Gankra closed this as completed Sep 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request - new integration feature request New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants