# Microsoft.DotNet.Build.Tasks.Installers

Task package for installer specific tasks with optional opt-in targets for automatic installer generation.

This package supports generating installers for projects in .msi, .deb, .rpm, and .pkg formats. This support is opt-in by setting the `GenerateInstallers` property to `true`. In addition, to enable the .deb and .rpm support, the `GenerateDebPackage` and `GenerateRpmPackage` properties respectively need to be set to true. This support depends on a `PublishToDisk` target that publishes the project's outputs to the `$(OutputPath)` folder.

There are a few common properties used by all of the installer types and the bundle installers (documented after the installers):

- `InstallerName`
  - The name of the installer file without an extension..
- `ProductBrandPrefix`
  - The branding name of this component, such as "Microsoft Windows Desktop"
- `PackageBrandNameSuffix`
  - The type of package, for example "Shared Host" or "AppHost Pack". This is set automatically for any non-ToolPack packages produced by the Shared Framework SDK.

For correct branding and versioning, this SDK has a dependency on Arcade's versioning setup, including the `MajorVersion`, `MinorVersion`, `PreReleaseVersionLabel`, `PreReleaseVersionIteration` and `DotNetFinalVersionKind` properties.

Since some framework packs do not use `RuntimeIdentifier`s in their build, for example targeting packs, for the installer build you can define `InstallerRuntimeIdentifiers` and the build will fan out for the installer build across those target RIDs. In addition, the `InstallerRuntimeIdentifier` property will default to the value of `RuntimeIdentifier` if it is not set.

### Wix MSI configuration

If you have files that need to have a stabilized identity in the MSI file, you can add items to the `HeatOutputFileElementToStabilize` item group. Each item in this group specifies a unique suffix of a path (enough to identify a single file) and a value for the `ReplacementId` metadata as the id to set in the MSI for this file.

If you want to create MSIs for the target RID that target other architecture install locations, you can add `CrossArchSdkMsiInstallerArch` items for all of the target architecture install locations you want to generate installers of the current build for.

To control the order in which an older product is removed during an upgrade, set the `MajorUpgradeSchedule` property to a value defined [here](https://wixtoolset.org/documentation/manual/v3/xsd/wix/majorupgrade.html).  The default is `afterInstallInitialize`.

### Linux package configuration

To add package dependencies for linux packages, add a `LinuxPackageDependency` item with the version in the `Version` metadata.

To add package conflicts, add a `LinuxPackageConflict` item for the package.

To add symlinks that should be installed on the system, add a `LinuxPackageSymlink` item with the `LinkTarget` metadata pointing to the target of the symlink.

> [!NOTE]
> Symlinks added with `LinuxPackageSymlink` are relative to the filesystem root, not to the `LinuxInstallRoot` property.
> As the vast majority of symlinks in a package are from system locations to the install root, this provides an easier UX for defining symlinks.

Add a `LinuxPostInstallScript` item to specify an sh script that should be run after the package is installed.
Add a `LinuxPostRemoveScript` item to specify an sh script that should be run after the package is removed.

#### Deb package configuration

To add additional properties for the deb control file, add `DebControlProperty` items with the value of the field in the `Value` metadata.

To add additional files to the `control` tarball in the package, add `DebControlFile` items for each file.

#### Rpm package configuration

To specify directories owned by the package, add `RpmOwnedDirectory` items for each directory. These are provided automatically for any non-ToolPack packages produced by the Shared Framework SDK.

### MacOS Pkg configuration

To specify a directory where `pkgbuild` should look for scripts, set the `MacOSScriptsDirectory` to the path to the scripts.

You need to specify the `MacOSComponentNamePackType` to create the component name for the `.pkg` package. This is set automatically for any non-ToolPack packages produced by the Shared Framework SDK.

If you want the component name to not include the version (for example you are building the shared host), you can set the `IncludeVersionInMacOSComponentName` property to false.

If your `pkg` is later going to be bundled in a macOS `pkg` bundle created by `productbuild`, you should also specify the `MacOSPackageDescription` property, which will set the package description in the bundle distribution file.

### Visual Studio Insertion Package configuration

Visual Studio insertion packages generated by the SDK are named in the form `VS.Redist.Common.$(VSInsertionShortComponentName).$(InstallerTargetArchitecture)$(CrossArchContentsBuildPart).$(MajorVersion).$(MinorVersion)`

The `InstallerTargetArchitecture` and later properties are automatically calculated by the SDK or are version properties. You are required to provide the `VSInsertionShortComponentName` property value yourself.

## Building Installer Bundles

As part of the installer support, the SDK supports building Wix bundle installers and macOS pkg bundles. These bundles are defined in a separate project with a `.bundleproj` extension that includes the .NET SDK and this SDK as shown in the example project. Like the installer targets, the bundle targets also use the `InstallerName` property and the support for `RuntimeIdentifiers` to identify target architectures for the bundle. The bundle targets verify that the RID is targeting an OS that supports an installer bundle, so be sure to limit the RID list to platforms that support bundles (Windows and macOS today).

The bundle installers also require the `ProductBrandPrefix` property and a `BundleNameSuffix` property in the place of the `PackageBrandNameSuffix` property used by the installer targets.

To include installers in the bundle, add `BundleComponentReference` items that point to the projects that produce the installers.

### Wix Bundle configuration

A number of properties are required to configure the Wix bundle generation:

- `BundleInstallerUpgradeCodeSeed`
  - This property specifies a seed for generating the bundle upgrade GUID. This must not change within a product band, otherwise the upgrade code will not match.
- `BundleThemeDirectory`
  - This property should point to a directory that contains the following files and folders:
    - `bundle.thm`
    - `bundle.wxl`
    - A `theme` directory that contains subdirectories with resources per codepage.

### MacOS Pkg bundle configuration

A number of properties are required to configure the MacOS Pkg bundle generation:

- `MacOSBundleIdentifierName`
  - The identifier of the pkg bundle.
- `MacOSBundleResourcesPath`
  - The folder with the resources for the bundle, including various HTML and RTF files that the installer shows the user.
- `MacOSBundleTemplate`
  - A partial [macOS Distribution XML file](https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html). The build system will add the `<title>`, `<choices-outline>`, `<choice>`, and `<pkg-ref>` elements automatically to the provided XML file based on the provided properties and the bundled `.pkg` files defined in the project file.

## Build Skip Support for Unsupported Platforms and Servicing

This SDK also supports automatically skipping builds on unsupported platforms or in servicing releases. If a project with a list of provided RIDs in `RuntimeIdentifiers` or `InstallerRuntimeIdentifiers` is built with the `RuntimeIdentifier` property or `InstallerRuntimeIdentifier` property set to a RID that is not in the `RuntimeIdentifiers` or `InstallerRuntimeIdentifiers` list respectively, the build will be skipped. This enables cleanly skipping optional packs, installers, or bundles that only exist on specific platforms. 

Additionally, if a `ProjectServicingConfiguration` item is provided with the identity of the project name and the `PatchVersion` metadata on the item is not equal to the current `PatchVersion`, the build will be skipped. This support enables a repository to disable building targeting packs in servicing releases if that is desired.

## Wix Command packages

### Overview

Wix command packages contain all of the artifacts and intermediates required to produce a wix package (msi, wixlib, exe, etc) and a script file which can be used to generate the wix file.

The purpose of the wix command package is to provide a simple way to operate on the intermediate files before they are used to generate the wix artifact and generate the wix file (artifact).  In practice, this provides a way to post-build sign the wix intermediates and produce signed wix files.

### Producing Wix Command packages

If you're using the targets in this package to produce wix artifacts, then a wix command package will automatically be created for you.  If you're using the [wix toolset](https://wixtoolset.org/) to produce wix files, then you can produce "wix command packages" using the MSBuild tasks directly.

Wix command packages are produced by using the `CreateLightCommandPackageDrop` MSBuild task from the `Microsoft.DotNet.Build.Tasks.Installers` package.  Task usage is defined [here](https://github.com/dotnet/arcade/blob/master/src/Microsoft.DotNet.Build.Tasks.Installers/README.md#tasks)

### File Format

Wix command packages have the file extension `.wixpack.zip`, but they are standard zip files.

Wix command packages contain a `create.cmd` script file in the root of the archive which is used to generate the wix file.

Intermediate files needed to produce a wix file are placed in a folder which is the wix id value defined in the wixobj file for that artifact.

WixObj files which are used to create the wix file are placed in the root of the archive and contain the info needed to produce a wix file.  File paths to intermediates are updated to refer to the paths in the archive.

### Task Usage

- **CreateLightCommandPackageDrop** - Create a layout that can be used to
  re-execute a light command. This can be used during post-build signing
  after files have been replaced. A cmd file that can be used to reconstruct the installer is created.
  
  The parameters for this task should be set to the parameters used on the input light command.
  
  After creating the layout, it can be zipped and added to the build artifacts.
  
  Parameters:
  - LightCommandWorkingDir - Base directory to place the layout
  - Out - Original installer output file. The filename is stripped
    of its extension and appended to LightCommandWorkingDir as the target directory for the layout
  - NoLogo - Add `-nologo`
  - Fv - Add `-fv`
  - PdbOut - Add `-pdbout <pdbfile>`
  - Cultures - Add `-cultures:<list of cultures>`
  - WixProjectFile - Add `-wixprojectfile:<project file>`
  - ContentsFile - Add `-contentsfile <contents file>`
  - OutputsFile - Add `-outputsfile <outputfile file>`
  - BuiltOutputsFile - Add `-builtoutputsfile <outputfile file>`
  - Loc - Add `-loc:<loc files>` and copy the loc files to the layout
  - Sice - Add `-sice:<supressed consistency checks>`
  - WixExtensions - Add `-ext <extension>` for each extension
  - WixSrcFiles - Add each input source file
