Choco: Install-ChocolateyVsixPackage.ps1 Doesnt work with 2017 packages

Created on 14 Mar 2017  Â·  46Comments  Â·  Source: chocolatey/choco

0 - Backlog Enhancement Up For Grabs

Most helpful comment

chocolatey-visualstudio.extension now includes the Install-VisualStudioVsixExtension helper, which is API-compatible with Install-ChocolateyVsixPackage and adds these features:

  • supports VS 2017 (in addition to all previous VS versions)
  • allows passing custom parameters to vsixinstaller.exe by means of --package-parameters (this allows, for example, installing an extension into specific VS instances only)

A slight semantic change from Install-ChocolateyVsixPackage is that the VisualStudioVersion parameter is declared (for API compatibility), but ignored. It never worked properly as advertised in the original helper (it influenced the choice of the vsixinstaller.exe version to use, but did not explicitly restrict the installation to specific VS versions). Also, I believe that choice should be left at the discretion of the user (possible now via --package-parameters), not hardcoded in the the package by the maintainer.

The extension is currently in prerelease status (version 1.6.0-rc7), pending some more testing. It can be evaluated using the latest prerelease of the stylecop-vsix package (version 5.0.6419.0-rc2). Example command lines:

````

install the vsix into all instances of all VS versions and products (supported by the vsix) installed on the machine

cinst -y stylecop-vsix --pre

install the vsix into VS 2013 Professional only

cinst -y stylecop-vsix --pre --params "--skuName Pro --skuVersion 12.0"

install the vsix into all instances of VS 2017 Community installed on the machine

cinst -y stylecop-vsix --pre --params "--skuName Community --skuVersion 15.0"

install the vsix into the one specific instance of VS 2017 Community

cinst -y stylecop-vsix --pre --params "--appIdInstallPath C:\Program Files (x86)\Microsoft Visual Studio\2017\Community --appIdName VS --skuName Community --skuVersion 15.0"

install the vsix into the one specific instance of a VS 2017 product

the instance id can be obtained via vswhere.exe or Get-VSSetupInstance (from the VSSetup.Powershell module)

cinst -y stylecop-vsix --pre --params "--instanceIds e6d6df86"
````

If nothing bad comes up, I'll release the packages as official versions in a couple of days.

All 46 comments

@bbowman can you provide more context? What needs to change? Is it simply an issue like #1056? That is being fixed for 0.10.4.

The install dir for Visual Studio 2017 is no longer discoverable from the registry and instead you need to make a few COM calls to the setup engine to query it for installs. Thus the logic to find a valid VSIXInstaller.exe to use for the install in Install-ChocolateyVsixPackage.ps1 will need to be changed for 2017 installs.

@bbowman you can use the vswhere.exe to find the installation path.

vswhere is actually available as a Chocolatey Package: https://chocolatey.org/packages/vswhere

@ferventcoder @gep13 Thanks guys! I coded up a small workaround for our package at https://github.com/Microsoft/WinObjC/pull/2233 ... I still think this is a good candidate to get into 0.10.5

I also saw that there are a few more error states for blocked process that makes an unattended / silent install challenging. I'd love to see some ideas on how to handle that.

I also saw that there are a few more error states for blocked process that makes an unattended / silent install challenging. I'd love to see some ideas on how to handle that.

725?

Finally found this issue after trying to spin up a new Vagrant box with

iwr https://chocolatey.org/install.ps1 -UseBasicParsing | iex
choco install -y visualstudio2017enterprise
choco install -y visualstudio-github

So installing and running vswhere shows me

PS C:\Windows\system32> vswhere
Visual Studio Locator, version 1.0.58
Copyright (C) Microsoft Corporation. All rights reserved.

instanceId: 497100bf
installDate: 3/17/2017
installationName: VisualStudio/15.0.0+26228.9
installationPath: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise
installationVersion: 15.0.26228.9
displayName: Visual Studio Enterprise 2017
description: Microsoft DevOps solution for productivity and coordination across teams of any size
enginePath: C:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service
channelId: VisualStudio.15.Release
channelPath: C:\Users\vagrant\AppData\Local\Microsoft\VisualStudio\Packages\_Channels\4CB340F5\catalog.json
channelUri: https://aka.ms/vs/15/release/channel

The registry has these entries

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\15.0]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\15.0\Registration]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\15.0\Registration\08860]
"EditionID"=dword:00000004
"ProductID"="00369-60000-00001-AA402"

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS]

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7]
"15.0"="C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Enterprise\\"

The VsixInstaller.exe can be found in C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE

@ferventcoder #725 is different. The scenario in this case is that the user has visual studio running when trying to install a 2017 VSIX. When not running the installer in quiet mode, the GUI shows that the running instance of VS is blocking the install and the installer waits until the user closes this otherwise unrelated process. The unattended installer just hangs for ~5 minutes and then returns 2004? (I'm on mobile so I forget the exact error code and can't easily look it up) to indicate the install is blocked. In my package I error out here and show a message about closing instances of VS and to try again.

Ideally I'd like to be able to still succeed (with the users help) in this case. Maybe the chocolatey script needs to list known VS processes that are running on the machine?

Perhaps @gep13 or others familiar with vswhere know of a way to query for running instances or something to be more useful than a 5 minute timeout.

Thoughts?

The scenario in this case is that the user has visual studio running when trying to install a 2017 VSIX. When not running the installer in quiet mode, the GUI shows that the running instance of VS is blocking the install and the installer waits until the user closes this otherwise unrelated process. The unattended installer just hangs for ~5 minutes and then returns 2004? (I'm on mobile so I forget the exact error code and can't easily look it up) to indicate the install is blocked. In my package I error out here and show a message about closing instances of VS and to try again.

@bbowman is this new? I always thought I could install VSIXs with Visual Studio running before. If this is new, wouldn't you agree that this is kind of suboptimal and it (VSIX installer) should allow the install to move forward but just not load it into the currently running Visual Studio?

Taking Chocolatey out of the equation for a moment and just talking about silent installation.

What options are available here?

@ferventcoder Yes this is new. Visual Studio changed their extension model for 2017 (@heaths can probably shed some light here or knows who can?). I would agree that the silent installation option doesn't seem as robust in the model. I also know that VS2017 update 1 is coming soon so maybe there are improvements we can expect there?

In terms of options for silent installation in general:

  1. we could try to detect and kill any running instances of visual studio but that is a non starter as a user might be working on something critical

  2. we could detect and fail the install before we call out to the installer. This is also kind of a non starter because it fails the install in a scenario that could be successful.

  3. we could detect this scenario and launch the installer not silently (only when this scenario is detected). This would allow to be silent in hopefully most cases but present the user with the most information in cases we can't be? This isn't ideal especially if the user isn't running in a mode where this UI would be readily visible (I'm thinking SSH'ed in or something).

Seems like we have a few not great options. Ideally we can get some input from vs folks to make a better choice?

Another option here:

  1. Fix the limitation and allow for the install to happen silently even if there are running instances of Visual Studio, then load the new extensions at the next restart of Visual Studio. (the same as the old behavior - the current way it works in 2017 is a regression aka a bug).

In a pinch, option 3 could be used. However even that option still needs a timeout as otherwise it is not a robust enterprise type of deployment without some predictability of silent deployment (blocking on a GUI thread forever is a non-starter).

Option 2 is probably the next option - it would need to exit with a different code so it's known why it failed.

Here's the best option - support all three of your options by adding additional switches to the VSIX installer to allow for these options to be set by the user performing the installs. Then set a sensible default, which might be 2 or 3.

Where does the VS team congregate these days? Where can we file issues?

This is probably as good a place to start as any...

https://gitter.im/Microsoft/extendvs

Lots of VS Development Team people's in there.

Also https://github.com/Microsoft/vsixbootstrapper seems like it might be useful for this discussion.

A further potential issue for 2017 is that quiet installs may fail with a 3001 exit code unless version and SKU flags are set on the command line for VSIXInstaller.exe; see https://developercommunity.visualstudio.com/content/problem/26008/vs-2017-rtm-vsixinstaller-cannot-find-setup-engine.html for details. It looks like the SKU value is always going to be the last part of the installationPath property from vswhere output, but unfortunately there's no property explicitly for SKU.

You should not use the VSIXInstaller.exe in the old location. Use it from the enginePath returned from _vswhere.exe_.

@heaths That will likely still require /s and /v parameters in a side-by-side scenario, which is the issue I brought up.

It shouldn't, as that is the copy that gets used to install _.vsix_ files when VS2017 is installed and those parameters are not passed in a simple double-click-to-install scenario. But I can refer this thread to the Extensibility team for comment.

Please do.

Unfortunately, the /s and /v will not work when using the VS2017 vsixinstaller to install to VS2015 and older. Right now, the only work-around is to use the VS2015 vsixinstaller to go downlevel. To install to VS2017, you can specify the /instanceIds parameter to apply to all of the relevant VS2017 instances.

Fortunately the current Install-ChocolateyVsixPackage function inside Chocolatey calls the VSIXInstaller for the requested Visual Studio version for 2015 and older. However, the function it uses to do that, Install-Vsix, only takes a path to the appropriate VSIXInstaller an the path to the package being installed. What it seems like to me is that to solve this issue, we need:

  • [ ] determine enginePath and instance IDs for VS 2017+ installs inside Install-ChocolateyVsixPackage
  • [ ] extend Install-Vsix to accept an optional collection of instance IDs to add to the VSIXInstaller.exe command line

Taken like that neither of these seem like a big deal, but I expect that the core Chocolatey devs would prefer to handle the first task in a pure PowerShell way if possible, rather than add a new dependency on vswhere. (@ferventcoder et al. please correct me if I'm mistaken!) If we can determine enginePath and instanceId from the registry or a fixed file location, then this can be banged out in no time. If we can add a dependency on vswhere inside Chocolatey, ditto.

vswhere is MIT licensed, so that shouldn't be a blocker to adding it as a dependency to Chocolatey itself.

A PowerShell native option to test for VS 2017 in addition to vswhere is VSSetup

if ((Get-VSSetupInstance).InstallationVersion -ge "15.0") {
}

Available in the PSGallery

I'm good with whatever works best! It looks like we need to handle vs2017 possibly differently, and it would be nice to know when we are looking at VS2017 vs older VS installations in a way that is very convention-based if possible, with a fall back to explicitly specified when not.

Marking this up for grabs.

@coldacid how is being MIT licensed a blocker? Visual Studio itself - a mostly closed-source product - installs a number of OSS products under different licenses. You may need something like a _ThirdPartyNotices.txt_ (names may vary, but I see this commonly).

We will also be included _vswhere_ with the install starting with Visual Studio 2017 version 15.2 but that will only work for _vswhere_ and above. Since _vswhere_ is also a chocolatey package (and the same package is posted on nuget.org if that is more convenient) you could pull it down if needed.

I'd like to tackle this, but I would also like to use this opportunity to move this helper out of core Chocolatey and into the chocolatey-visualstudio.extension, which already contains a lot of code dealing with VS installation and addition/removal of VS 2017 workloads. That way future development of the helper would be decoupled from Chocolatey releases and it would be trivial to add a dependency on the vswhere package.

(The VSSetup module would be more convenient to use than vswhere.exe, but unfortunately it requires PowerShell 3.0 and Chocolatey still supports PS 2.0.)

@jberezanski _vswhere_ works great with PowerShell:

$instances = vswhere -format json | convertfrom-json

At that point, you've got a subset - but the core information - of what Get-VSSetupInstance provides.

@heaths although that works, it would be a no-go with choco packages as ConvertFrom-Json was added in PSv3.

Choco packages requires to be compatible with v2

It's hard remembering what was added when. I've been using it since it was "Monad". ;)

You can also do:

$instances = ([xml](vswhere -format xml)).instances | select-object -expand instance

@heaths Licensing can be touchy, and while I've been making packages for some time, working on Chocolatey itself I've not done aside from some commentary on issues and in Gitter. Pardon me if I'm overcautious. As for [xml] I wish I had known of that before! Despite using ConvertFrom-Json in the Sandcastle package, as @AdmiringWorm points out that's not something that can be done in Chocolatey itself.

@jberezanski +1 on moving this to chocolatey-visualstudio.extension

Seems like there is a clear path for discovering VS 2017 compatible with PSv2 via vswhere ala @heaths

@ferventcoder any opinion on moving this into @jberezanski choco package and out of core choco

@heaths vswhere -format xml works, yes. However, it does not provide all the information I need in other scenarios (the list of installed packages), so I've been looking for alternatives.

I haven't been able to use the interop library directly from PowerShell (couldn't find a way to cast the SetupConfigurationClass to the SetupConfiguration interface), but I've managed to build a working prototype port of the VSSetup module to PowerShell 2.0.

@jberezanski may I ask why you need the list? We only document a small number of packages available. Others - like with reflecting private members of managed code - may change (many have already, since refactoring of packages is supported for agility).

With _vswhere_ you can pass -requires Name1[ Name2[ ...NameN]] to find an instance that actually has required components or workloads (technically any package ID, but note again the lack of a guarantee).

BTW, starting today _vswhere_ is also in the box. I just posted this: https://blogs.msdn.microsoft.com/heaths/2017/04/21/vswhere-is-now-installed-with-visual-studio-2017/. May or may not help your situation. Just updating a few issue threads that may be interested.

@heaths I'm only looking at the documented packages. In particular, when installing workloads, I look for all instances which _do not_ have that workload installed. I suppose I could call vswhere twice, first for all instances, then with -requires, and subtract the sets, but that feels less elegant than obtaining the instances once with all information needed for filtering, hence my attempts to use the more powerful API.

Thanks for the heads-up regarding vswhere distribution!

But to what end? Installing a VSIX v3 with dependencies will install those dependencies automatically. I can see a case where you don't want _VSIXInstaller_ to install workloads automatically (something I've been working to solve for https://github.com/wixtoolset since I've been maintaining the _VSExtension_ for several years (and helped write quite a bit of WiX when it was internal), but then you're looking for instances that have all required workloads.

If you want workloads installed automatically, _VSIXInstaller_ will do that if required. But I recommend - because it can be a long-running operation (and detrimental when running from within an MSI already, as one of the other problems with installing VSIX v3s in WiX) - you make the user opt into that behavior through a switch parameter and/or prompt them.

Also note that casting in PowerShell doesn't support interop. In managed code, you create the SetupConfiguration interface (which PowerShell can't do either; it's something the C# compiler knows how to do for interop types) and when you cast to other interfaces it calls IUnknown::QueryInterface underneath in the CLR.

Sorry, I wandered off the topic of installing VSIX packages a bit. I started thinking about the other usage scenarios supported by chocolatey-visualstudio.extension, in this case installation of VS 2017 workloads (there is a Chocolatey package for each workload).

Also note that casting in PowerShell doesn't support interop.

Not only that, but PowerShell seems to ignore interfaces and always operates on the real underlying types. I created a DynamicMethod with the exact IL the C# compiler generates for a new SetupConfiguration(); statement (newobj, castclass), but even though I made the method return SetupConfiguration, PowerShell still treated the return value as SetupConfigurationClass and was unable to call any SetupConfiguration methods. Working around this would require wrapping each interop call in a new method (either using System.Reflection.Emit or Add-Type), but then I would be essentially reimplementing the VSSetup module, which is why I went ahead to experiment with porting the module to PowerShell 2.0 (very few changes needed, really).

Depending on the changes (I.e. no loss of functionality), we could look at taking a PR to the VSSetup module to support PSv2.

chocolatey-visualstudio.extension now includes the Install-VisualStudioVsixExtension helper, which is API-compatible with Install-ChocolateyVsixPackage and adds these features:

  • supports VS 2017 (in addition to all previous VS versions)
  • allows passing custom parameters to vsixinstaller.exe by means of --package-parameters (this allows, for example, installing an extension into specific VS instances only)

A slight semantic change from Install-ChocolateyVsixPackage is that the VisualStudioVersion parameter is declared (for API compatibility), but ignored. It never worked properly as advertised in the original helper (it influenced the choice of the vsixinstaller.exe version to use, but did not explicitly restrict the installation to specific VS versions). Also, I believe that choice should be left at the discretion of the user (possible now via --package-parameters), not hardcoded in the the package by the maintainer.

The extension is currently in prerelease status (version 1.6.0-rc7), pending some more testing. It can be evaluated using the latest prerelease of the stylecop-vsix package (version 5.0.6419.0-rc2). Example command lines:

````

install the vsix into all instances of all VS versions and products (supported by the vsix) installed on the machine

cinst -y stylecop-vsix --pre

install the vsix into VS 2013 Professional only

cinst -y stylecop-vsix --pre --params "--skuName Pro --skuVersion 12.0"

install the vsix into all instances of VS 2017 Community installed on the machine

cinst -y stylecop-vsix --pre --params "--skuName Community --skuVersion 15.0"

install the vsix into the one specific instance of VS 2017 Community

cinst -y stylecop-vsix --pre --params "--appIdInstallPath C:\Program Files (x86)\Microsoft Visual Studio\2017\Community --appIdName VS --skuName Community --skuVersion 15.0"

install the vsix into the one specific instance of a VS 2017 product

the instance id can be obtained via vswhere.exe or Get-VSSetupInstance (from the VSSetup.Powershell module)

cinst -y stylecop-vsix --pre --params "--instanceIds e6d6df86"
````

If nothing bad comes up, I'll release the packages as official versions in a couple of days.

Both packages are now available as official versions: chocolatey-visualstudio.extension, stylecop-vsix.

I am unable to install any extensions from the VS Gallery. It looks like there is still an issue. Can you try the following?

Install-VisualStudioVsixExtension -PackageName "WixToolsetExtension" -VsixUrl https://marketplace.visualstudio.com/_apis/public/gallery/publishers/RobMensching/vsextensions/WixToolsetVisualStudio2017Extension/0.9.21.62588/vspackage
WARNING: Missing package checksums are not allowed (by default for HTTP/FTP,
HTTPS when feature 'allowEmptyChecksumsSecure' is disabled) for
safety and security reasons. Although we strongly advise against it,
if you need this functionality, please set the feature
'allowEmptyChecksums' ('choco feature enable -n
allowEmptyChecksums')
or pass in the option '--allow-empty-checksums'. You can also pass
checksums at runtime (recommended). See choco install -? for details.
This package downloads over HTTPS but does not yet have package checksums to verify the package. We recommend asking the maintainer to add checksums to
this package. In the meantime if you need this package to work correctly, please enable the feature allowEmptyChecksumsSecure, provide the runtime switch
'--allow-empty-checksums-secure', or pass in checksums at runtime (recommended - see 'choco install -?' / 'choco upgrade -?' for details).
At C:\ProgramData\chocolatey\helpers\functions\Get-CheckSumValid.ps1:167 char:7

  • throw "This package downloads over HTTPS but does not yet have ...
  • ~~~~~~~~~~~~~~~

    • CategoryInfo : OperationStopped: (This package do...' for details).:String) [], RuntimeException

    • FullyQualifiedErrorId : This package downloads over HTTPS but does not yet have package checksums to verify the package. We recommend asking the mai

      ntainer to add checksums to this package. In the meantime if you need this package to work correctly, please enable the feature allowEmptyChecksumsSec

      ure, provide the runtime switch '--allow-empty-checksums-secure', or pass in checksums at runtime (recommended - see 'choco install -?' / 'choco upgra

      de -?' for details).

@theperm can you create an issue here?

@theperm can you create an issue here?

Scratch that. I'm guessing you are running Install-VisualStudioVsixExtension directly from a PowerShell prompt (after manually importing the chocolatey-visualstudio.psm1 and chocolateyInstaller.psm1 modules). The error you are running into is expected in this case, because the helper functions expect certain environment variables to be set (choco.exe does it before invoking the PowerShell scripts).

Try building an actual package for that vsix and installing it with choco.

I think I tried it from a boxstarter package as that's where I want to use
it. Is that supported?

On Tue, 15 May 2018, 21:19 Jakub Bereżański, notifications@github.com
wrote:

@theperm https://github.com/theperm can you create an issue here?

Scratch that. I'm guessing you are running
Install-VisualStudioVsixExtension directly from a PowerShell prompt
(after manually importing the chocolatey-visualstudio.psm1 and
chocolateyInstaller.psm1 modules). The error you are running into is
expected in this case, because the helper functions expect certain
environment variables to be set (choco.exe does it before invoking the
PowerShell scripts).

Try building an actual package for that vsix and installing it with choco.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/chocolatey/choco/issues/1201#issuecomment-389299782,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAyHqWfw47igUHCaZQQtv3xIZkMWC-m9ks5tyzhIgaJpZM4Mb_p-
.

As I have no experience with Boxstarter, I don't know how Boxstarter packages and their execution environment differ from Chocolatey packages. chocolatey-visualstudio.extension is designed and tested only for usage inside Chocolatey.

I suggest you put Boxstarter aside for the moment, build and test your package in plain Chocolatey, and, once you confirm it works, try to install it with Boxstarter (and seek assistance from Boxstarter authors if something fails at that point).

Was this page helpful?
0 / 5 - 0 ratings