Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
268 changes: 135 additions & 133 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@
[![NuGet](https://img.shields.io/nuget/v/CodingWithCalvin.VsixSdk.svg)](https://www.nuget.org/packages/CodingWithCalvin.VsixSdk)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

An MSBuild SDK that brings modern SDK-style `.csproj` files to Visual Studio extension development. No more XML soup!
An MSBuild SDK that brings modern SDK-style `.csproj` files to Visual Studio extension development. No more XML soup! 🎉

## Why This Exists
## 💡 Why This Exists

Visual Studio extension projects are stuck in the past. They still use the old, verbose project format while the rest of .NET has moved on to clean SDK-style projects.

**This SDK fixes that.**

Write clean `.csproj` files. Get source generators for compile-time constants. Ship fully functional VSIX packages.
✨ Write clean `.csproj` files
✨ Get source generators for compile-time constants
✨ Ship fully functional VSIX packages

## Getting Started
## 🚀 Getting Started

### Using the Template (Recommended)
### 📦 Using the Template (Recommended)

The easiest way to create a new VSIX project is with the dotnet template:

Expand Down Expand Up @@ -57,7 +59,117 @@ dotnet new vsix -n MyExtension \
--tags "productivity, tools, editor"
```

### Manual Setup
### 🔄 Migrating from Legacy Projects

Have an existing non-SDK style VSIX project? Here's how to modernize it:

#### Step 1: Back Up Your Project

Before making changes, ensure your project is committed to source control or backed up.

#### Step 2: Replace the .csproj Content

Replace your entire `.csproj` file with the SDK-style format:

**Before (Legacy):**
```xml
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('...')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{YOUR-GUID}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MyExtension</RootNamespace>
<AssemblyName>MyExtension</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<!-- ... many more lines ... -->
</PropertyGroup>
<!-- ... hundreds of lines of XML ... -->
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
```

**After (SDK-style):**
```xml
<Project Sdk="CodingWithCalvin.VsixSdk/1.0.0">

<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<RootNamespace>MyExtension</RootNamespace>
<AssemblyName>MyExtension</AssemblyName>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.SDK" Version="17.*" />
<PackageReference Include="Microsoft.VSSDK.BuildTools" Version="17.*" PrivateAssets="all" />
</ItemGroup>

</Project>
```

#### Step 3: Update the VSIX Manifest for VS 2022+

Add `<ProductArchitecture>amd64</ProductArchitecture>` to each `InstallationTarget`:

```xml
<Installation>
<InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[17.0, 19.0)">
<ProductArchitecture>amd64</ProductArchitecture>
</InstallationTarget>
<!-- Repeat for Professional, Enterprise if needed -->
</Installation>
```

#### Step 4: Remove Unnecessary Files

Delete these files if they exist (the SDK handles them automatically):
- 📄 `packages.config` - Use `PackageReference` instead
- 📄 `Properties/AssemblyInfo.cs` - SDK generates this automatically
- 📄 `app.config` - Usually not needed

#### Step 5: Update Package References

Convert from `packages.config` to `PackageReference` format in your `.csproj`:

```xml
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.SDK" Version="17.*" />
<PackageReference Include="Microsoft.VSSDK.BuildTools" Version="17.*" PrivateAssets="all" />
<!-- Add other packages your extension uses -->
</ItemGroup>
```

#### Step 6: Handle VSCT Files

If you have `.vsct` files, they're automatically included. Remove any explicit `<VSCTCompile>` items unless you need custom metadata.

#### Step 7: Build and Test

```bash
dotnet build
```

Fix any errors that arise. Common issues:
- ❌ **Missing types**: Add the appropriate `PackageReference`
- ❌ **Duplicate files**: Remove explicit includes that conflict with auto-inclusion
- ❌ **Resource files**: Ensure `VSPackage.resx` files are in the project

#### ✅ Migration Checklist

- [ ] Replaced `.csproj` with SDK-style format
- [ ] Added `<ProductArchitecture>amd64</ProductArchitecture>` to manifest
- [ ] Converted `packages.config` to `PackageReference`
- [ ] Removed `Properties/AssemblyInfo.cs`
- [ ] Removed explicit file includes (now auto-included)
- [ ] Updated version range to `[17.0, 19.0)` for VS 2022+
- [ ] Build succeeds with `dotnet build`
- [ ] F5 debugging works in Visual Studio

### 🛠️ Manual Setup

If you prefer to set up manually, create a `.csproj` file:

Expand Down Expand Up @@ -104,9 +216,9 @@ Then create `source.extension.vsixmanifest`:
</PackageManifest>
```

## Features
## Features

### Source Generators
### 🔮 Source Generators

The SDK includes source generators that create compile-time constants from your manifest files.

Expand Down Expand Up @@ -159,11 +271,11 @@ public static class MyCommandsVsct
}
```

#### Generated Files Location
#### 📁 Generated Files Location

Generated source files are written to the `Generated/` folder in your project and are visible in Solution Explorer. They're marked as auto-generated so you know not to edit them directly.

### Version Override
### 🏷️ Version Override

Update the VSIX version at build time without manually editing the manifest:

Expand All @@ -173,33 +285,33 @@ dotnet build -p:SetVsixVersion=2.0.0

This updates the `source.extension.vsixmanifest` file with the new version, rebuilds with the correct version in all outputs (including the generated `VsixInfo.Version` constant), and produces the VSIX with the specified version.

This is useful for CI/CD pipelines:
Perfect for CI/CD pipelines:

```yaml
# GitHub Actions example
- name: Build Release
run: dotnet build -c Release -p:SetVsixVersion=${{ github.ref_name }}
```

### Auto-Inclusion
### 📂 Auto-Inclusion

The SDK automatically includes common VSIX files:

- `*.vsct` files as `VSCTCompile` items
- `VSPackage.resx` files with proper metadata
- `source.extension.vsixmanifest` as an `AdditionalFile` for source generators
- 📄 `*.vsct` files as `VSCTCompile` items
- 📄 `VSPackage.resx` files with proper metadata
- 📄 `source.extension.vsixmanifest` as an `AdditionalFile` for source generators

### F5 Debugging
### 🐛 F5 Debugging

Press F5 to launch the Visual Studio Experimental Instance with your extension loaded. This works automatically when:
- Building in Debug configuration
- Building inside Visual Studio (not `dotnet build`)

### Smart Deployment
### 🚀 Smart Deployment

Extensions are only deployed to the Experimental Instance when building inside Visual Studio. This prevents errors when building from the command line.

### Publish Manifest Generation
### 📋 Publish Manifest Generation

The SDK automatically generates a `publish.manifest.json` file for publishing to the VS Marketplace. All values are extracted from your VSIX manifest:

Expand Down Expand Up @@ -236,7 +348,7 @@ To disable publish manifest generation:
</PropertyGroup>
```

## Configuration
## ⚙️ Configuration

### Properties

Expand Down Expand Up @@ -282,122 +394,12 @@ Or disable specific categories:
</PropertyGroup>
```

## Migrating from Legacy Projects

If you have an existing non-SDK style VSIX project, follow these steps to convert it.

### Step 1: Back Up Your Project

Before making changes, ensure your project is committed to source control or backed up.

### Step 2: Replace the .csproj Content

Replace your entire `.csproj` file with the SDK-style format:

**Before (Legacy):**
```xml
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('...')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{YOUR-GUID}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MyExtension</RootNamespace>
<AssemblyName>MyExtension</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<!-- ... many more lines ... -->
</PropertyGroup>
<!-- ... hundreds of lines of XML ... -->
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
```

**After (SDK-style):**
```xml
<Project Sdk="CodingWithCalvin.VsixSdk/1.0.0">

<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<RootNamespace>MyExtension</RootNamespace>
<AssemblyName>MyExtension</AssemblyName>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.SDK" Version="17.*" />
<PackageReference Include="Microsoft.VSSDK.BuildTools" Version="17.*" PrivateAssets="all" />
</ItemGroup>

</Project>
```

### Step 3: Update the VSIX Manifest for VS 2022+

Add `<ProductArchitecture>amd64</ProductArchitecture>` to each `InstallationTarget`:

```xml
<Installation>
<InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[17.0, 19.0)">
<ProductArchitecture>amd64</ProductArchitecture>
</InstallationTarget>
<!-- Repeat for Professional, Enterprise if needed -->
</Installation>
```

### Step 4: Remove Unnecessary Files

Delete these files if they exist (the SDK handles them automatically):
- `packages.config` - Use `PackageReference` instead
- `Properties/AssemblyInfo.cs` - SDK generates this automatically
- `app.config` - Usually not needed

### Step 5: Update Package References

Convert from `packages.config` to `PackageReference` format in your `.csproj`:

```xml
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.SDK" Version="17.*" />
<PackageReference Include="Microsoft.VSSDK.BuildTools" Version="17.*" PrivateAssets="all" />
<!-- Add other packages your extension uses -->
</ItemGroup>
```

### Step 6: Handle VSCT Files

If you have `.vsct` files, they're automatically included. Remove any explicit `<VSCTCompile>` items unless you need custom metadata.

### Step 7: Build and Test

```bash
dotnet build
```

Fix any errors that arise. Common issues:
- **Missing types**: Add the appropriate `PackageReference`
- **Duplicate files**: Remove explicit includes that conflict with auto-inclusion
- **Resource files**: Ensure `VSPackage.resx` files are in the project

### Migration Checklist

- [ ] Replaced `.csproj` with SDK-style format
- [ ] Added `<ProductArchitecture>amd64</ProductArchitecture>` to manifest
- [ ] Converted `packages.config` to `PackageReference`
- [ ] Removed `Properties/AssemblyInfo.cs`
- [ ] Removed explicit file includes (now auto-included)
- [ ] Updated version range to `[17.0, 19.0)` for VS 2022+
- [ ] Build succeeds with `dotnet build`
- [ ] F5 debugging works in Visual Studio

## Requirements
## 📋 Requirements

- Visual Studio 2022 or later
- .NET Framework 4.7.2+ target framework

## Building from Source
## 🏗️ Building from Source

```bash
# Clone the repository
Expand All @@ -413,12 +415,12 @@ dotnet pack src/CodingWithCalvin.VsixSdk.Templates/CodingWithCalvin.VsixSdk.Temp
# Packages output to artifacts/packages/
```

## Contributors
## 👥 Contributors

<!-- readme: contributors -start -->
<!-- readme: contributors -end -->

## License
## 📄 License

MIT License - see [LICENSE](LICENSE) for details.

Expand Down