jberezanski / ChocolateyPackages

Chocolatey packages maintained by me
MIT License
84 stars 51 forks source link

Installing specific versions does not work #100

Open nanolonny opened 3 years ago

nanolonny commented 3 years ago

I tested this on multiple PC's and it seems that the version specified is ignored and 16.9.0 is the default.

PS C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin> choco install visualstudio2019buildtools --version=16.8.3.0 PS C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin> .\MSBuild -version Microsoft (R) Build Engine version 16.9.0+57a23d249 for .NET Framework Copyright (C) Microsoft Corporation. All rights reserved.

16.9.0.11203

keremispirli commented 3 years ago

I have the same problem. It always installs the latest version.

I tried to install 16.8.5 and 16.8.6, but the installed version is always 16.9.2 which is the current latest version.

I looked at the history of its ChocolateyInstall.ps1 file (here) and downloaded the "vs_BuildTools.exe" binaries from all 3 versions I mentioned above. The binaries are different, but once launched they all try to install 16.9.2. Below is the screenshot of the title of the window when vs_BuildTools.exe for 16.8.5 is launched.

image

Current version (16.9.x) has a breaking change that fails the build when a solution contains WiX projects, which was tolerated in the older (16.8.5) version. Is there a way to install an older version of Build Tools? A specific parameter to the vs_BuildTools.exe or something?

keremispirli commented 3 years ago

OK, I just found in the Release Notes that "the native installer always installs the latest released Visual Studio 2019 build", so apparently "this is not a bug, it is a feature" applies here, too.

Still, is there a way to install an older version of this package? A parameter to the vs_BuildTools.exe or something?

I found that here is a "--productId" parameter that can be passed to the binary, but I can't find the list of product Id's.

jberezanski commented 3 years ago

That is correct. Because of the way Microsoft designed the Visual Studio installer program, the packages on chocolatey.org will always install the latest VS version.

The reason is that the executables downloaded by the packages (from urls published by Microsoft) are just tiny, simple bootstrappers which only download the real VS Installer (the latest version of it) and invoke it. The VS Installer, in turn, is driven by two data files (the "channel manifest", https://aka.ms/vs/16/release/channel, and the "component catalog", linked from the channel manifest; they specify the exact versions of the components to be installed) which the Installer downloads from a specific address. Those files are updated by Microsoft in-place whenever an update of VS is released.

There is a documented way of installing an earlier Visual Studio version, but it requires prior preparation. You can create an offline installation source ("layout") - a local cache of Visual Studio installation files. If you do it today, you will have a set of files which can be used to install VS 2019 16.9.3.

The packages on chocolatey.org can both create such an offline source and install from it. Example command lines are provided here (the syntax for 2019 is the same as for 2017). But there is no time machine, sorry - today you cannot create an offline source for a past VS 2019 release.

Now, it is technically possible (albeit undocumented and probably not supported by Microsoft) to install an earlier VS release using only those two data files mentioned earlier, instead of keeping a full, multi-gigabyte offline installation source. The VS installer parameters --installChannelUri, --installCatalogUri and --noWeb should be used in that case. You could even create an automated mechanism to periodically download and store subsequent versions of the data files, building up a private repository of previous VS versions. (I do have such a repository for my own purposes, but I will never share it because those files are Microsoft property and I do not think I or anyone else except Microsoft is allowed to redistribute them.) One could even create custom Chocolatey packages with those files embedded - such packages could indeed install a specific VS release. But such packages could only be used internally by an organization, not published on chocolatey.org.

keremispirli commented 3 years ago

If I understand correctly, that last option also needs old Channel Manifest and Component Catalog files to be already kept around. So it's not possible to use those parameters without a time machine either.

I may have sort of a "time machine" lying around, though... I still have container images with correct version of build tools installed; maybe I can salvage the files from there.

Thank very much you for detailed explanation, Jakub!

jberezanski commented 3 years ago

You're welcome :)

Yes, that last option also needs the old files. Its benefit is only in reducing the amount of data to be stored.

I believe the VS Installer caches the data files under C:\ProgramData\Microsoft\VisualStudio\Packages\_Channels. Additionally, the Component Catalog for an installed VS instance is present in C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances\<instance id>.

jberezanski commented 3 years ago

Oh, I've just accidentally stumbled upon this: https://docs.microsoft.com/en-us/visualstudio/releases/2019/history#installing-an-earlier-release It seems Microsoft is now providing links to bootstrappers capable of installing a specific, earlier version, at least for Professional/Enterprise/BuildTools products. These bootstrappers are preconfigured with specific installChannelUri links, which lead to the appropriate channel manifests.

It would take some effort to change the packages to use those installers and I'm not sure how it would work for upgrades, but it may help in your scenario. The bootstrappers are self-extracting zip archives which can be unpacked using, for example, Total Commander. Then you can get the channel manifest link from vs_setup_bootstrapper.json and pass it as --installChannelUri, for example

cinst -y visualstudio2019buildtools --params "--installChannelUri https://aka.ms/vs/16/release/143670269_-969659425/channel"

installs VS Build Tools 16.7.4.

keremispirli commented 3 years ago

Oh, I've just accidentally stumbled upon this: https://docs.microsoft.com/en-us/visualstudio/releases/2019/history#installing-an-earlier-release

This is exactly what I needed! I tried to pass the --installChannelUri to the current native installer and it offered to install 16.7.4 just like you said. So now I can pin the version to whatever I want. Thanks again Jakub!

About updating the chocolatey package: Maybe it's enough to update the package description with the sentence in the Release Notes so it is not a surprise, and add a link to this issue so that people who need old versions can find the solution easily.

jberezanski commented 3 years ago

Well, ideally I would like to have the cake and eat it, so to speak. That is, retain the ability to easily install the latest VS and upgrade to it, but at the same time be able to install a specific, older version.

Design considerations:

Related: #11 #82

jberezanski commented 3 years ago

Here is a wild idea:

  1. Use the existing package ids for both scenarios.
  2. Divide the package version numbers into two "channels" (similar in meaning to AU streams):
    • a "latest" channel, which behaves the same as the packages do now
    • a "specific versions" channel, which can install a specific version (a new instance of VS), but not upgrade to it
  3. The "latest" channel would have synthetic version numbers, not connected to VS version numbers (but higher than all of them), recording only package updates:
    • idea 1: 200.0.0.20210413 (make it crystal clear the number is synthetic and not offer even a hint of suggestion of VS 20.x)
    • idea 2: 16.999.0.20210413 (retain the VS 2019 major version number)
  4. The "specific versions" channel would retain version numbers similar to VS numbers.
    • Like before, for new VS versions, the packages would have predictable versions (16.9.4.0).
    • For older VS versions, the "clean" version numbers were already used up, so the packages will use fix notation - again, similar to existing practice (16.2.3.20210413).
  5. Whenever a new VS release is published, a new package version will be published in both channels.
  6. Packages in the "specific versions" channel will not support upgrades. Not sure yet whether they should signal an error and fail the installation, or install successfully but do nothing.
  7. Upgrading a VS instance installed using a "specific versions" package to the latest avaliable version will be possible simply via cup -y visualstudio2019buildtools.
  8. To reduce confusion, earlier versions of "latest" channel packages could be unlisted (provided it can be done automatically, via some api of chocolatey.org, because I definitely would not be doing it manually...). Possibly retaining version N and N-1 (upon publishing N, unlisting N-2 or older), in case the bootstrapper used by latest version has some issues.
jberezanski commented 3 years ago

One scenario which would offer a slightly worse UX in the above design is the case of a workload package depending on a minimum version of the main product, such as was the case with several VS 2017 Build Tools workloads, added in minor VS versions. Fortunately, there is no such workload in VS 2019 yet (and probably will not be added this late in the lifetime of the product).

Correction: no, on second thought, the UX would not change. Thanks to Chocolatey dependency resolution (always latest version), Build Tools would still be upgraded to the latest version (using the "latest" package).

asfernandes commented 7 months ago

Oh, I've just accidentally stumbled upon this: https://docs.microsoft.com/en-us/visualstudio/releases/2019/history#installing-an-earlier-release It seems Microsoft is now providing links to bootstrappers capable of installing a specific, earlier version, at least for Professional/Enterprise/BuildTools products. These bootstrappers are preconfigured with specific installChannelUri links, which lead to the appropriate channel manifests.

It would take some effort to change the packages to use those installers and I'm not sure how it would work for upgrades, but it may help in your scenario. The bootstrappers are self-extracting zip archives which can be unpacked using, for example, Total Commander. Then you can get the channel manifest link from vs_setup_bootstrapper.json and pass it as --installChannelUri, for example

cinst -y visualstudio2019buildtools --params "--installChannelUri https://aka.ms/vs/16/release/143670269_-969659425/channel"

installs VS Build Tools 16.7.4.

Is this still valid?

I'm trying with vs 2022 and the installer fails.

asfernandes commented 7 months ago

I'm trying with vs 2022 and the installer fails.

Looks like it was not working because I was installing in the default place and the previous container already had a version there. It worked with a custom --installPath.

danielMCF99 commented 1 month ago

I'm trying with vs 2022 and the installer fails.

Looks like it was not working because I was installing in the default place and the previous container already had a version there. It worked with a custom --installPath.

Can you paste here the full command pls ?

Breee commented 1 month ago

a custom --installPath has no effect for me.

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="visualstudio2022enterprise" version="117.8.6.0"
    packageParameters="--quiet --norestart --wait --nocache
    --installPath c:\Program Files\Microsoft Visual Studio\2022\Enterprise
    --remove Microsoft.VisualStudio.Component.Windows10SDK.10240
    --remove Microsoft.VisualStudio.Component.Windows10SDK.10586
    --remove Microsoft.VisualStudio.Component.Windows10SDK.14393
    --remove Microsoft.VisualStudio.Component.Windows81SDK
    --remove Microsoft.VisualStudio.Component.Azure.Storage.AzCopy
    --add Microsoft.VisualStudio.Workload.Azure
    --add Microsoft.VisualStudio.Workload.ManagedDesktop;includeRecommended;includeOptional
    --add Microsoft.VisualStudio.Workload.NativeDesktop;includeRecommended;includeOptional
    --add Microsoft.VisualStudio.Workload.NetCoreTools;includeRecommended
    --add Microsoft.VisualStudio.Workload.NetWeb;includeRecommended;includeOptional
    --add Microsoft.VisualStudio.Workload.Node;includeRecommended
    --add Microsoft.VisualStudio.Workload.Office;includeRecommended;includeOptional
    --add Microsoft.VisualStudio.Workload.Python;includeRecommended
    --add Microsoft.VisualStudio.Workload.VisualStudioExtension;includeRecommended
    --add Microsoft.VisualStudio.Component.VC.v141.x86.x64
    --add Microsoft.VisualStudio.Component.VC.v141.MFC
    --add Microsoft.VisualStudio.Component.VC.v141.ATL" />
</packages>

Still installs VS 117.10

asfernandes commented 1 month ago

a custom --installPath has no effect for me.

Check if c:\Program Files\Microsoft Visual Studio\2022\Enterprise is empty. If there is something already there, it will ignore the version you pass.

Breee commented 1 month ago

I'm afraid not. We start our build from the container image mcr.microsoft.com/windows/server:ltsc2022-amd64 Which is empty and nothing VS related exists. It simply ignores the Version and install latest.

In https://github.com/jberezanski/ChocolateyPackages/blob/master/visualstudio2022enterprise/tools/ChocolateyInstall.ps1#L4 we can see that the channel 17 ist used.

Would probably be enough to let us pass a link to a custom release channel https://learn.microsoft.com/en-us/visualstudio/releases/2022/release-history#release-dates-and-build-numbers based on version we pass

asfernandes commented 1 month ago

Check https://github.com/FirebirdSQL/firebird/blob/master/builds/docker/windows/Dockerfile (and its history) to see how I did (and fixed) it.

bdashore3 commented 1 month ago

@Breee I experimented with this yesterday and the following command worked:

choco install -y visualstudio2022buildtools --version=117.9.7.0 --params "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --installChannelUri https://aka.ms/vs/17/release/180911598_-255012421/channel"

This installs VS 17.9.7 Build Tools. I extracted the channel URI by grabbing an exe of v17.9.7 on MS's VS 2022 builds page. Then, I used 7zip's Open Archive to open the downloaded exe, and then opened the file vs_setup_bootstrapter.json.

From there, I copied the channelUri value and used that for the --installChannelUri arg above.

The --add arg is passed to the installer so I can add the VC++ build tools for my usecase. Hope this helps!