microsoft/vssdk-sdk-style-conversion
> Converts Visual Studio extension (VSIX/VSSDK) projects from legacy project format to SDK-style. Handles VSSDK-specific concerns including package references, VSIX manifest, VSCT command tables, project capabilities, and solution deploy markers for F5 debugging. Use when asked to "convert VSIX to SDK style", "modernize VS extension project", "migrate VSSDK project", "SDK-style VSIX", or "update extension csproj format".
npx skills add https://github.com/microsoft/upgrade-agent-plugins --skill vssdk-sdk-style-conversion
Convert Visual Studio extension projects from legacy (old-style) format to modern SDK-style while preserving VSIX packaging, F5 debugging, and extension functionality.
> Related skills:
> - converting-to-sdk-style — base SDK-style conversion mechanics (used during execution)
> - sdk-style-conversion — general SDK-style conversion scenario (for non-VSIX projects)
> - managing-package-references — NuGet package management
Run these stages in order:
assessment.md.plan.md.Analyze the VSIX project to understand its structure and identify conversion considerations.
| Aspect | Where to Look | Why It Matters |
|--------|--------------|----------------|
| VSIX manifest | source.extension.vsixmanifest | Must preserve generator metadata |
| VSCT command tables | *.vsct files (may be multiple) | Need all VSCTCompile items preserved |
| Tool windows / MEF exports | [Export], [ProvideToolWindow] attributes | May require framework references |
| Current packages | packages.config or PackageReference items | Must migrate to VSSDK metapackages; VSSDK.BuildTools must be ≥18.5.38461 — never downgrade an existing higher version |
| Custom build targets | <Import> elements beyond standard VS SDK imports | May need preservation |
| Solution format | .sln vs .slnx | Determines deploy marker format |
| Existing debug config | StartAction/StartProgram in csproj; Deploy.0 in sln | Replaced by deploy markers |
| Target framework | TargetFrameworkVersion / TargetFramework | Keep net48 if using Community.VisualStudio.Toolkit.17 |
| Auto-generated files | Files with <AutoGen>True</AutoGen> metadata | Must switch to <Compile Update> |
Create assessment.md:
# Assessment: VSSDK SDK-Style Conversion
## Target Project
| Property | Value |
|----------|-------|
| Project | [name] |
| Path | [path] |
| Current TFM | [e.g., net472, net48] |
| Solution format | [.sln / .slnx] |
| packages.config | [Yes/No] |
## VSIX Components Found
- [ ] VSIX manifest (source.extension.vsixmanifest)
- [ ] VSCT command table ([file])
- [ ] Tool windows
- [ ] MEF exports
- [ ] Custom editors
- [ ] Language services
## Current Package References
[list current VS SDK packages and versions]
## Baseline
- Project builds: [Yes/No]
- Solution builds: [Yes/No]
## Key Findings
[Notable patterns, risks, or decisions needed]
Create plan.md with ordered tasks. VSSDK projects are typically standalone for conversion purposes, but verify no other projects depend on the VSIX output.
converting-to-sdk-style skill for structural format changeIf the project is loaded in Visual Studio during conversion, unload it first. The IDE locks project files and caches project state — modifying the file while loaded risks corruption or stale evaluation. After conversion completes, reload the project so VS picks up the new SDK-style format cleanly.
If running outside VS (CLI or VS Code), skip this step.
All project file (.csproj) edits must use the edit file tool — never write, overwrite, or reconstruct the project file through PowerShell (e.g., Set-Content, output redirection, [xml] manipulation, or Add-Content). The project is unloaded specifically so the edit file tool can make surgical, targeted replacements that preserve formatting and minimize diff noise. PowerShell is only for build commands (msbuild, dotnet build), NuGet restore, and other non-file-editing operations.
This applies to all phases below: base conversion tool output, VSSDK overlay changes, and any fix-up edits during validation.
Apply the converting-to-sdk-style feature skill for the structural conversion. This handles:
<Project Sdk="Microsoft.NET.Sdk">)<Compile> includes (SDK globbing takes over)packages.config to PackageReference (if present)<Import> elementsAfter base conversion, the project is SDK-style but missing VSSDK-specific configuration.
Load ref/vssdk-project-format.md for detailed property values, package versions, and the complete template.
Apply these changes in order:
PropertyGroup: VSSDKBuildToolsAutoSetup, VsixDeployOnDebug, UseCodebase. Add GeneratePkgDefFile only if not already present — if the project already sets it, preserve the existing value.<ProjectCapability Include="CreateVsixContainer" /><Compile Include> to <Compile Update> for files like source.extension.cs and VSCommandTable.cs. Using Include on auto-globbed files causes duplicate errors.<VSCTCompile> items as-is (there may be more than one; they work identically in SDK-style)<None Include="source.extension.vsixmanifest"> with generator metadata<Content> items with <IncludeInVSIX>true</IncludeInVSIX>PresentationCore, PresentationFrameworkSystem.ComponentModel.CompositionSystem.Design (rare)Microsoft.VSSDK.BuildTools — minimum version 18.5.38461 required; NEVER downgrade an existing higher version. SDK-style VSIX projects do not work with older build tools — 18.5.38461 is a hard floor, not a target. If the project already references a version above 18.5.38461, keep the existing version as-is — downgrading causes obscure build failures and is never correct. Only raise the version if it is below the minimum. If the package cannot be added or restored at the minimum version (e.g., due to version constraints, feed issues, or central package management conflicts), stop and report the blocker — the conversion cannot proceed. After updating, perform a full clean (msbuild /t:Clean or delete bin/obj folders) before building, because stale build tool artifacts from older versions cause misleading errors. Never clear NuGet caches — only clean project output directories.Microsoft.VisualStudio.SDK — keep existing version if already referenced; add if missing (replaces individual VS interop packages)Community.VisualStudio.Toolkit.17 (if used — keep existing version)Community.VisualStudio.VSCT (if VSCT files present — keep existing version)Properties/AssemblyInfo.cs (SDK auto-generates assembly attributes). Move polyfills like IsExternalInit to standalone files. Keep custom attributes like InternalsVisibleTo in any .cs file.StartAction/StartProgram/StartArguments properties<Import> elements for Microsoft.Common.props, Microsoft.CSharp.targets, Microsoft.VsSDK.targetsMark the project as deployable in the solution file. This replaces the old StartAction/StartProgram pattern for F5 debugging — VsixDeployOnDebug=true in the project file does the rest once deploy markers are set.
For .slnx files:
<Project Path="src/YourExtension.csproj">
<Deploy />
</Project>
For classic .sln files, add Deploy.0 entries in GlobalSection(ProjectConfigurationPlatforms):
{PROJECT-GUID}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{PROJECT-GUID}.Release|Any CPU.Deploy.0 = Release|Any CPU
After all file edits and solution updates are complete, reload the solution so the IDE picks up the new SDK-style format and deploy markers. This must happen before building or verifying — building against stale cached project state produces misleading results.
If running outside VS (CLI or VS Code), skip this step.
After reloading, verify:
msbuild).vsix file is produced in the output directoryCompile item warningspackages.config removed (if it existed)Properties/AssemblyInfo.cs removed<Import> elements remainStartAction/StartProgram properties remain| Problem | Likely Cause | Fix |
|---------|-------------|-----|
| Build tools version blocked | Central package management or feed constraint prevents VSSDK.BuildTools ≥18.5.38461 | Resolve version conflict in Directory.Packages.props or NuGet config — conversion cannot proceed without this minimum |
| Build tools downgraded | Replaced a higher VSSDK.BuildTools version with 18.5.38461 | NEVER downgrade — 18.5.38461 is a floor, not a target. Restore the original higher version immediately. |
| Stale build artifacts after conversion | Old build tools artifacts in bin/obj | Full clean: msbuild /t:Clean or delete bin/obj directories. Never clear NuGet caches. |
| Build or restore fails with file-lock errors | dotnet or msbuild processes holding locks on project outputs, NuGet cache, or build artifacts | Kill all dotnet and msbuild processes (Stop-Process -Name dotnet -Force; Stop-Process -Name msbuild -Force), then retry the build. If insufficient permissions prevent killing processes, ask the user to close Visual Studio and/or run taskkill /F /IM dotnet.exe & taskkill /F /IM msbuild.exe from an elevated prompt. |
| CreatePkgDef task fails or hangs | Stale msbuild/dotnet processes caching old build tool assemblies | Kill all dotnet and msbuild processes, clean bin/obj, then rebuild. Same escalation to user if permissions are insufficient. |
| CS0234: 'Composition' does not exist | Missing framework reference | Add <Reference Include="System.ComponentModel.Composition" /> |
| CS0234: 'Controls' does not exist | Missing WPF reference | Add <Reference Include="PresentationFramework" /> |
| Duplicate Compile items | Using Include instead of Update | Change to <Compile Update="file.cs"> |
| Assembly info conflicts | SDK generates attributes conflicting with AssemblyInfo.cs | Delete AssemblyInfo.cs or set <GenerateAssemblyInfo>false</GenerateAssemblyInfo> |
| F5 doesn't launch experimental instance | Missing deploy markers in solution | Add deploy entries to .sln/.slnx |
| CS0246: 'Community' could not be found | Toolkit targets net48 but project targets net472 | Change <TargetFramework> to net48 |
.vsixTake microsoft/vssdk-sdk-style-conversion from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.