This document describes how we package the Roslyn LSP server and Visual Basic
assemblies for the VS Code extension. The goal is to allow selecting either
backend (vbnet or roslyn) without changing the extension binaries.
We ship two Roslyn-related folders inside the extension:
.roslyn/? base Roslyn LSP server (RID-specific).roslyn-vb/? VB assemblies used as--extensioninputs
This layout avoids duplicate analyzer references and mirrors the working
Neovim experiment: the Roslyn server loads VB language services only when the
VB assemblies are provided via --extension, and only if those assemblies are
not also present in the base directory.
We download artifacts from NuGet:
Microsoft.CodeAnalysis.LanguageServer.<rid>Microsoft.CodeAnalysis.VisualBasicMicrosoft.CodeAnalysis.VisualBasic.WorkspacesMicrosoft.CodeAnalysis.VisualBasic.Features
The Roslyn LSP packages are RID-specific and currently prerelease-only. The VB packages have stable releases and must match the Roslyn LSP version line to avoid binding issues.
- Roslyn LSP (RID-specific): prerelease only (no stable).
Example:
Microsoft.CodeAnalysis.LanguageServer.win-x645.0.0-1.25277.114. - VB packages (stable):
5.0.0. - VB packages (prerelease):
5.0.0-2.final.
Use the Node script:
# Auto-detect RID from the current platform
npm run bundle-roslyn
# Explicit RID
npm run bundle-roslyn:win32-x64
npm run bundle-roslyn:linux-x64
npm run bundle-roslyn:darwin-x64
npm run bundle-roslyn:darwin-arm64The script is src/extension/scripts/copy-roslyn-server.js and:
- Downloads the Roslyn LSP package for the RID.
- Extracts
content/LanguageServer/<rid>into.roslyn/. - Downloads VB packages and copies
Microsoft.CodeAnalysis.VisualBasic*.dll/xmlinto.roslyn-vb/.
Temporary NuGet downloads are cached under .roslyn-downloads/ and excluded
from VSIX packaging by .vscodeignore.
- CI caches
.roslyn-downloads/keyed by the packaging script hash and target. - Packaging runs
npm run validate-roslynto ensure.roslynand.roslyn-vbare coherent (server present, VB assemblies only in the extension folder).
Defaults are pinned in the script but can be overridden via args or environment:
# CLI args
node scripts/copy-roslyn-server.js --rid win-x64 --lsp-version <ver> --vb-version <ver>
# Environment
export VBNET_ROSLYN_RID=linux-x64
export VBNET_ROSLYN_LSP_VERSION=5.0.0-1.25277.114
export VBNET_ROSLYN_VB_VERSION=5.0.0To use Roslyn from the extension, set:
{
"vbnet.server.backend": "roslyn",
"vbnet.roslyn.server.extensionPath": "<path to .roslyn-vb>"
}If you leave vbnet.roslyn.server.extensionPath empty, the extension uses the
bundled .roslyn-vb directory.
- The Roslyn LSP binaries are RID-specific; you must bundle the correct RID for each VSIX target.
- The VB assemblies must not exist in the Roslyn base directory or the server will crash with duplicate analyzer references.
- Keep versions aligned across Roslyn LSP + VB packages to avoid missing dependencies.