I have installed Visual Studio Code on a machine that is not, and cannot be, connected to the Internet. According to the documentation, I can install an extension from the command line if I have the .vsix
, but I don't know how to get the .vsix
from the marketplace.
How can I download the .vsix
for an extension hosted on the marketplace?
This question is related to
visual-studio-code
A small powershell to get needed information for also visual studio extension :
function Get-VSMarketPlaceExtension {
[CmdLetBinding()]
Param(
[Parameter(ValueFromPipeline = $true,Mandatory = $true)]
[string[]]
$extensionName
)
begin {
$body=@{
filters = ,@{
criteria =,@{
filterType=7
value = $null
}
}
flags = 1712
}
}
process {
foreach($Extension in $extensionName) {
$response = try {
$body.filters[0].criteria[0].value = $Extension
$Query = $body|ConvertTo-JSON -Depth 4
(Invoke-WebRequest -Uri "https://marketplace.visualstudio.com/_apis/public/gallery/extensionquery?api-version=6.0-preview" -ErrorAction Stop -Body $Query -Method Post -ContentType "application/json")
} catch [System.Net.WebException] {
Write-Verbose "An exception was caught: $($_.Exception.Message)"
$_.Exception.Response
}
$statusCodeInt = [int]$response.StatusCode
if ($statusCodeInt -ge 400) {
Write-Warning "Erreur sur l'appel d'API : $($response.StatusDescription)"
return
}
$ObjResults = ($response.Content | ConvertFrom-Json).results
If ($ObjResults.resultMetadata.metadataItems.count -ne 1) {
Write-Warning "l'extension '$Extension' n'a pas été trouvée."
return
}
$Extension = $ObjResults.extensions
$obj2Download = ($Extension.versions[0].properties | Where-Object key -eq 'Microsoft.VisualStudio.Services.Payload.FileName').value
[PSCustomObject]@{
displayName = $Extension.displayName
extensionId = $Extension.extensionId
deploymentType = ($obj2Download -split '\.')[-1]
version = [version]$Extension.versions[0].version
LastUpdate = [datetime]$Extension.versions[0].lastUpdated
IsValidated = ($Extension.versions[0].flags -eq "validated")
extensionName = $Extension.extensionName
publisher = $Extension.publisher.publisherName
SourceURL = $Extension.versions[0].assetUri +"/" + $obj2Download
FileName = $obj2Download
}
}
}
}
This use marketplace API to get extension information. Exemple of usage and results :
>Get-VSMarketPlaceExtension "ProBITools.MicrosoftReportProjectsforVisualStudio"
displayName : Microsoft Reporting Services Projects
extensionId : 85e42f76-6afa-4a68-afb5-033d1fe08d7b
deploymentType : vsix
version : 2.6.7
LastUpdate : 13/05/2020 22:23:45
IsValidated : True
extensionName : MicrosoftReportProjectsforVisualStudio
publisher : ProBITools
SourceURL : https://probitools.gallery.vsassets.io/_apis/public/gallery/publisher/ProBITools/extension/MicrosoftReportProjectsforVisualStudio/2.6.7/assetbyname/Microsoft.DataTools.ReportingServices.vsix
FileName : Microsoft.DataTools.ReportingServices.vsix
All flags value are available here
Thanks to m4js7er and Adam Haynes for inspiration
For Python users the pattern to use with t3chbot's excellent answer looks like:
https://marketplace.visualstudio.com/_apis/public/gallery/publishers/ms-python/vsextensions/python/{version_number}/vspackage
be sure to scroll right to see where you have to enter the version number.
If you are looking for a scripted solution:
.vsix
files (see example below)unzip
the binary into ~/.vscode/extensions/
: you need to modify unzipped directory name, remove one file and move/rename another one.For API start by looking at following example, and for hints how to modify request head to https://github.com/Microsoft/vscode/blob/master/src/vs/platform/extensionManagement/common/extensionGalleryService.ts.
POST https://marketplace.visualstudio.com/_apis/public/gallery/extensionquery?api-version=5.1-preview HTTP/1.1
content-type: application/json
{
"filters": [
{
"criteria": [
{
"filterType": 8,
"value": "Microsoft.VisualStudio.Code",
},
{
"filterType": 7,
"value": "ms-python.python",
}
],
"pageNumber": 1,
"pageSize": 10,
"sortBy": 0,
"sortOrder": 0,
}
],
"assetTypes": ["Microsoft.VisualStudio.Services.VSIXPackage"],
"flags": 514,
}
Explanations to the above example:
"filterType": 8
- FilterType.Target
more FilterTypes"filterType": 7
- FilterType.ExtensionName
more FilterTypes"flags": 514
- 0x2 | 0x200
- Flags.IncludeFiles | Flags.IncludeLatestVersionOnly
- more Flags
python -c "print(0x2|0x200)"
"assetTypes": ["Microsoft.VisualStudio.Services.VSIXPackage"]
- to get only link to .vsix
file more AssetTypesadding on to t3chb0t's answer, not sure why the option to download is not visible, so created a patch for those who use GreaseMonkey/ TamperMonkey: you can find the gist code here
Or you can just paste the below lines in your browser console, and the link would magically appear:
let version = document.querySelector('.ux-table-metadata > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(2) > div:nth-child(1)').innerText
, itemDetails = window.location.search.replace('?', '').split('&').filter(str => !str.indexOf('itemName')).map(str => str.split('=')[1])[0]
, [author, extension] = itemDetails.split('.')
, lAuthor = author.toLowerCase()
, href = `https://${lAuthor}.gallery.vsassets.io:443/_apis/public/gallery/publisher/${author}/extension/${extension}/${version}/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage`
, element = document.createElement('a');
element.href = href;
element.className = 'vscode-moreinformation dark';
element.innerHTML = 'download .vsix file';
element.download = `${extension}.${version}.vsix`;
document.querySelector('.vscode-install-info-container').appendChild(element);
As of today the download URL for the latest version of the extension is embedded verbatim in the source of the page on Marketplace, e.g. source at URL:
https://marketplace.visualstudio.com/items?itemName=lukasz-wronski.ftp-sync
contains string:
https://lukasz-wronski.gallerycdn.vsassets.io/extensions/lukasz-wronski/ftp-sync/0.3.3/1492669004156/Microsoft.VisualStudio.Services.VSIXPackage
I use following Python regexp to extract dl URL:
urlre = re.search(r'source.+(http.+Microsoft\.VisualStudio\.Services\.VSIXPackage)', content)
if urlre:
return urlre.group(1)
I wanted to throw a PowerShell download option on the pile in case anyone else comes across this. I have several offline scenarios and I run this in a loop to download and update all of the extensions I use offline.
$page = Invoke-WebRequest -Uri 'https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell'
$details = ( $page.Scripts | ? {$_.class -eq 'vss-extension'}).innerHTML | Convertfrom-Json
$extensionName = $details.extensionName
$publisher = $details.publisher.publisherName
$version = $details.versions.version
Invoke-WebRequest -uri "$($details.versions.fallbackAssetUri)/Microsoft.VisualStudio.Services.VSIXPackage" `
-OutFile "C:\Scripts\extensions\$publisher.$extensionName.$version.VSIX"
Adding to t3chb0t's excellent answer - Use these PowerShell commands to install all VSCode extensions in a folder:
cd C:\PathToFolderWithManyDownloadedExtensionFiles
Get-ChildItem . -Filter *.vsix | ForEach-Object { code --install-extension $_.FullName }
Then, reload VSCode to complete the installation.
If you have a specific (legacy) version of VSCode on your offline instance, pulling the latest extensions might not properly integrate.
To make sure that VSCode and the extensions work together, they must all be installed together on the online machine. This resolves any dependencies (with specific versions), and ensures the exact configuration of the offline instance.
Install the VSCode version, turn off updating, and install the extensions. Copy the extensions from the installed location and place them on the target machine.
Install the exact version of VSCode on online machine. Then turn off updates by going to File -> Preferences -> Settings
. In the Settings
window, under User Settings -> Application
, go to Update
section, and change the parameter for Channel
to none
. This prevents VSCode from reaching out to the internet and auto-updating your versions to the latest.
Then go to the VSCode extensions section and install all of your desired extensions. Copy the installed extensions from their install location (with windows its C:\Users\<username>\.vscode\extensions
) to the same location on the target machine.
Works perfectly.
I've stored a script in my gist to download an extension from the marketplace using a PowerShell script. Feel free to comment of share it.
https://gist.github.com/azurekid/ca641c47981cf8074aeaf6218bb9eb58
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[string] $Publisher,
[Parameter(Mandatory = $true)]
[string] $ExtensionName,
[Parameter(Mandatory = $true)]
[ValidateScript( {
If ($_ -match "^([0-9].[0-9].[0-9])") {
$True
}
else {
Throw "$_ is not a valid version number. Version can only contain digits"
}
})]
[string] $Version,
[Parameter(Mandatory = $true)]
[string] $OutputLocation
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
Write-Output "Publisher: $($Publisher)"
Write-Output "Extension name: $($ExtensionName)"
Write-Output "Version: $($Version)"
Write-Output "Output location $($OutputLocation)"
$baseUrl = "https://$($Publisher).gallery.vsassets.io/_apis/public/gallery/publisher/$($Publisher)/extension/$($ExtensionName)/$($Version)/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage"
$outputFile = "$($Publisher)-$($ExtensionName)-$($Version).visx"
if (Test-Path $OutputLocation) {
try {
Write-Output "Retrieving extension..."
[uri]::EscapeUriString($baseUrl) | Out-Null
Invoke-WebRequest -Uri $baseUrl -OutFile "$OutputLocation\$outputFile"
}
catch {
Write-Error "Unable to find the extension in the marketplace"
}
}
else {
Write-Output "The Path $($OutputLocation) does not exist"
}
Now you can download an extension directly in the "Resources" section, there's a "Download extension" link, I hope this information is still useful.
All these suggestions are great, but kind of painful to follow because executing the code to construct the URL or constructing that crazy URL by hand is kind of annoying...
So, I threw together a quick web app to make things easier. Just paste the URL of the extension you want and out comes out the download of your extension already properly named: publisher-extension-version.vsix.
Hope someone finds it helpful: http://vscode-offline.herokuapp.com/
Source: Stackoverflow.com