chocolatey / choco

Chocolatey - the package manager for Windows
https://chocolatey.org
Other
10.06k stars 891 forks source link

Install-ChocolateyVsixPackage.ps1 Doesnt work with 2017 packages #1201

Open bbowman opened 7 years ago

bbowman commented 7 years ago

Please follow https://blogs.msdn.microsoft.com/heaths/2016/09/15/changes-to-visual-studio-15-setup/ to find VS installs now.

ferventcoder commented 7 years ago

@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.

bbowman commented 7 years ago

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.

gep13 commented 7 years ago

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

gep13 commented 7 years ago

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

bbowman commented 7 years ago

@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.

ferventcoder commented 7 years ago

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?

StefanScherer commented 7 years ago

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

bbowman commented 7 years ago

@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?

ferventcoder commented 7 years ago

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?

ferventcoder commented 7 years ago

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

What options are available here?

bbowman commented 7 years ago

@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?

ferventcoder commented 7 years ago

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.

ferventcoder commented 7 years ago

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

gep13 commented 7 years ago

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.

bbowman commented 7 years ago

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

coldacid commented 7 years ago

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.

heaths commented 7 years ago

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

coldacid commented 7 years ago

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

heaths commented 7 years ago

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.

coldacid commented 7 years ago

Please do.

wade0016 commented 7 years ago

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.

coldacid commented 7 years ago

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:

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.

coldacid commented 7 years ago

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

KZeronimo commented 7 years ago

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

ferventcoder commented 7 years ago

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.

ferventcoder commented 7 years ago

Marking this up for grabs.

heaths commented 7 years ago

@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.

jberezanski commented 7 years ago

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.)

heaths commented 7 years ago

@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.

AdmiringWorm commented 7 years ago

@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

heaths commented 7 years ago

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
coldacid commented 7 years ago

@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

KZeronimo commented 7 years ago

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

jberezanski commented 7 years ago

@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.

heaths commented 7 years ago

@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.

jberezanski commented 7 years ago

@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!

heaths commented 7 years ago

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.

jberezanski commented 7 years ago

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).

heaths commented 7 years ago

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

jberezanski commented 6 years ago

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

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.

jberezanski commented 6 years ago

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

theperm commented 6 years ago

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

jberezanski commented 6 years ago

@theperm can you create an issue here?

jberezanski commented 6 years ago

@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.

theperm commented 6 years ago

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- .

jberezanski commented 6 years ago

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).