| File: src\GenerateMsiVersion.cs | Web Access |
| Project: src\arcade\src\Microsoft.DotNet.Build.Tasks.Installers\Microsoft.DotNet.Build.Tasks.Installers.csproj (Microsoft.DotNet.Build.Tasks.Installers) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Build.Framework; namespace Microsoft.DotNet.Build.Tasks.Installers { // MSI versioning // Encode the CLI version to fit into the MSI versioning scheme - https://msdn.microsoft.com/en-us/library/windows/desktop/aa370859(v=vs.85).aspx // MSI versions are 3 part // major.minor.build // Size(bits) of each part 8 8 16 // So we have 32 bits to encode the CLI version // For a CLI version based on commit count: // Starting with most significant bit this how the CLI version is going to be encoded as MSI Version // CLI major -> 6 bits // CLI minor -> 6 bits // CLI patch -> 6 bits // CLI commitcount -> 14 bits // // For a CLI version based on BuildTools versioning // CLI major -> 5 bits // CLI minor -> 5 bits // CLI patch -> 4 bits // BuildNumber major -> 14 bits // BuildNumber minor -> 4 bits public class GenerateMsiVersion : BuildTask { [Required] public string Major { get; set; } [Required] public string Minor { get; set; } [Required] public string Patch { get; set; } public string BuildNumber { get; set; } public string BuildNumberMajor { get; set; } public string BuildNumberMinor { get; set; } [Output] public string MsiVersion { get; set; } public override bool Execute() { if(BuildNumber == null && BuildNumberMajor == null) { Log.LogError("Either BuildNumber or BuildNumberMajor and BuildNumberMinor are required parameters."); return false; } if(BuildNumber != null && BuildNumberMajor != null) { Log.LogError("You must specify either BuildNumber or BuildNumberMajor and BuildNumberMinor, you cannot specify both parameters."); return false; } if (BuildNumberMajor != null && BuildNumberMinor == null) { Log.LogError("If you specify a BuildNumberMajor, you must also specify the BuildNumberMinor."); return false; } if(BuildNumber != null) { ParseBuildNumber(); } else { ParseBuildNumberMajorMinor(); } return true; } private void ParseBuildNumber() { var major = int.Parse(Major) << 26; var minor = int.Parse(Minor) << 20; var patch = int.Parse(Patch) << 14; var msiVersionNumber = major | minor | patch | int.Parse(BuildNumber); var msiMajor = (msiVersionNumber >> 24) & 0xFF; var msiMinor = (msiVersionNumber >> 16) & 0xFF; var msiBuild = msiVersionNumber & 0xFFFF; MsiVersion = $"{msiMajor}.{msiMinor}.{msiBuild}"; } private void ParseBuildNumberMajorMinor() { var major = int.Parse(Major) << 27; var minor = int.Parse(Minor) << 22; var patch = int.Parse(Patch) << 18; var buildNumberMajor = (int.Parse(BuildNumberMajor) & 0x3FFF) << 4; var buildNumberMinor = int.Parse(BuildNumberMinor) & 0xF; var msiVersionNumber = major | minor | patch | buildNumberMajor | buildNumberMinor; var msiMajor = (msiVersionNumber >> 24) & 0xFF; var msiMinor = (msiVersionNumber >> 16) & 0xFF; var msiBuild = msiVersionNumber & 0xFFFF; MsiVersion = $"{msiMajor}.{msiMinor}.{msiBuild}"; } } }