Skip to content

Commit

Permalink
chocolatey-visualstudio.extension: fix installer version requirement …
Browse files Browse the repository at this point in the history
…determination logic

Logic extrapolated from Microsoft.VisualStudio.Setup.dll/Microsoft.VisualStudio.Setup.ChannelManager.EnsureEngineCanReadManifests().

EngineVersion := FileVersion of <VS Installer>\resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service\Microsoft.VisualStudio.Setup.dll
EngineVersion is in catalog manifest ($manifest.engineVersion)

installer version :=
    resources\app\main\Main.js:
    var EXE_VERSION = require("../package.json").version;

    function createSetupEngineAdapter:
        // exeVersionForEngine is used to detect updates. During development,
        // checking for updates is undesired. Typically, a true release version
        // looks like "x.y.build.qfe", otherwise the version is "x.y.z".
        // Passing null for version skips checking for updates.
        var exeVersionParts = EXE_VERSION.split(".");
        var exeVersionForEngine = exeVersionParts.length > 3 ? EXE_VERSION : null;
(this gets passed to Microsoft.VisualStudio.Setup.Service.dll/Microsoft.VisualStudio.Setup.ProductsProviderService.Initialize()
and from that through ((Service)base).Initialize() -> Service.InitializeSharedFields() to ChannelManagerFactory and ChannelManager)
so: <VS Installer>\resources\app\package.json -> version
NOT <VS Installer>\vs_installer.version.json -> version!
installer version is in channel manifest ($bootstrapper.version)

ChannelManager.EnsureEngineCanReadManifests() compares engine versions and installer versions; both comparisons must be satisfied (greater or equal)

GitHub-Issue: GH-7 GH-8 GH-10 GH-26
  • Loading branch information
jberezanski committed May 15, 2018
1 parent b3cbede commit 5751f8a
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 68 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
function Get-VSRequiredInstallerVersion
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory = $true)] [hashtable] $PackageParameters,
[PSObject] $ProductReference
)
Write-Verbose 'Trying to determine the required installer and engine version from the manifests'

Write-Debug 'Obtaining the channel manifest in order to determine the required installer version'
$channelManifest = Get-VSChannelManifest -PackageParameters $PackageParameters -ProductReference $ProductReference

Write-Debug 'Parsing the channel manifest'
$version = $null
$channelItem = Get-VSChannelManifestItem -Manifest $channelManifest -ChannelItemType 'Bootstrapper'
if ($channelItem -is [Collections.IDictionary] -and $channelItem.ContainsKey('version'))
{
$versionString = $channelItem['version']
if ($versionString -is [string])
{
try
{
$version = [version]$versionString
}
catch
{
Write-Debug ('Manifest parsing error: failed to parse version string ''{0}''' -f $versionString)
}
}
else
{
Write-Debug 'Manifest parsing error: version is not a string'
}
}
else
{
Write-Debug 'Manifest parsing error: channelItem is not IDictionary or does not contain version'
}

if ($version -ne $null)
{
Write-Verbose "Required installer version determined from the channel manifest: '$version'"
}
else
{
Write-Verbose "The required installer version could not be determined from the component manifest"
}

Write-Debug 'Obtaining the component manifest in order to determine the required engine version'
$manifest = Get-VSComponentManifest -PackageParameters $PackageParameters -ProductReference $ProductReference -ChannelManifest $channelManifest

Write-Debug 'Parsing the component manifest'
$engineVersion = $null
if ($manifest -is [Collections.IDictionary] -and $manifest.ContainsKey('engineVersion'))
{
$engineVersionString = $manifest['engineVersion']
if ($engineVersionString -is [string])
{
$engineVersion = [version]$engineVersionString
}
else
{
Write-Debug 'Manifest parsing error: engineVersion is not a string'
}
}
else
{
Write-Debug 'Manifest parsing error: manifest is not IDictionary or does not contain engineVersion'
}

if ($engineVersion -ne $null)
{
Write-Verbose "Required engine version determined from the component manifest: '$engineVersion'"
}
else
{
Write-Verbose "The required engine version could not be determined from the component manifest"
}

$props = @{
Version = $version
EngineVersion = $engineVersion
}
$obj = New-Object -TypeName PSObject -Property $props
Write-Output $obj
}
Original file line number Diff line number Diff line change
Expand Up @@ -226,31 +226,8 @@
# TODO: if bootstrapperPath present, check for existence of Catalog.json instead of downloading the VS component manifest
# TODO: if bootstrapperPath present, check for existence of vs_installer.opc and auto add --offline
# TODO: same for installLayoutPath
$requiredEngineVersion = Get-VSRequiredEngineVersion -PackageParameters $PackageParameters -ProductReference $thisProductReference
# WRONG! EngineVersion != installer version
# logic extrapolated from Microsoft.VisualStudio.Setup.dll/Microsoft.VisualStudio.Setup.ChannelManager.EnsureEngineCanReadManifests()
# EngineVersion := FileVersion of <VS Installer>\resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service\Microsoft.VisualStudio.Setup.dll
# EngineVersion is in catalog manifest ($manifest.engineVersion)
# installer version :=
<#
resources\app\main\Main.js:
var EXE_VERSION = require("../package.json").version;
function createSetupEngineAdapter:
// exeVersionForEngine is used to detect updates. During development,
// checking for updates is undesired. Typically, a true release version
// looks like "x.y.build.qfe", otherwise the version is "x.y.z".
// Passing null for version skips checking for updates.
var exeVersionParts = EXE_VERSION.split(".");
var exeVersionForEngine = exeVersionParts.length > 3 ? EXE_VERSION : null;
#>
# (this gets passed to Microsoft.VisualStudio.Setup.Service.dll/Microsoft.VisualStudio.Setup.ProductsProviderService.Initialize()
# and from that through ((Service)base).Initialize() -> Service.InitializeSharedFields() to ChannelManagerFactory and ChannelManager)
# so: <VS Installer>\resources\app\package.json -> version
# NOT <VS Installer>\vs_installer.version.json -> version!
# installer version is in channel manifest ($bootstrapper.version)
# ChannelManager.EnsureEngineCanReadManifests() compares engine versions and installer versions; both comparisons must be satisfied (greater or equal)
Install-VSInstaller -PackageName $PackageName -PackageParameters $PackageParameters -ProductReference $thisProductReference -Url $BootstrapperUrl -Checksum $BootstrapperChecksum -ChecksumType $BootstrapperChecksumType -RequiredVersion $requiredEngineVersion
$requiredVersionInfo = Get-VSRequiredInstallerVersion -PackageParameters $PackageParameters -ProductReference $thisProductReference
Install-VSInstaller -PackageName $PackageName -PackageParameters $PackageParameters -ProductReference $thisProductReference -Url $BootstrapperUrl -Checksum $BootstrapperChecksum -ChecksumType $BootstrapperChecksumType -RequiredInstallerVersion $requiredVersionInfo.Version -RequiredEngineVersion $requiredVersionInfo.EngineVersion
$installerUpdated = $true
}
}
Expand Down

0 comments on commit 5751f8a

Please sign in to comment.