Skip to content
Open
Show file tree
Hide file tree
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
181 changes: 157 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<div align="center">

**Your Visual Studio installations, beautifully organized** ✨
**Your Visual Studio and VS Code installations, beautifully organized** ✨

[![.NET](https://img.shields.io/badge/.NET-10.0-512BD4?style=for-the-badge&logo=dotnet)](https://dotnet.microsoft.com/)
[![WinUI 3](https://img.shields.io/badge/WinUI-3.0-0078D4?style=for-the-badge&logo=windows)](https://microsoft.github.io/microsoft-ui-xaml/)
Expand All @@ -15,45 +15,65 @@

## 🎯 What is Visual Studio Toolbox?

Visual Studio Toolbox is a sleek **system tray application** for Windows that helps you manage all your Visual Studio installations in one place. Think of it as your personal command center for Visual Studio! 🚀
Visual Studio Toolbox is a sleek **system tray application** for Windows that helps you manage all your **Visual Studio** and **Visual Studio Code** installations in one place. Think of it as your personal command center for all your development tools! 🚀

> 💡 **Inspired by JetBrains Toolbox** - bringing the same convenience to the Visual Studio ecosystem!
> 💡 **Inspired by JetBrains Toolbox** - bringing the same convenience to the Microsoft development ecosystem!

---

## ✨ Features

### 🎨 **Core Features**

| Feature | Description |
|---------|-------------|
| 🔍 **Auto-Detection** | Automatically discovers all VS 2019, 2022, and 2026 installations |
| 🔍 **Auto-Detection** | Automatically discovers VS 2019, 2022, 2026, VS Code, and VS Code Insiders |
| 🎨 **Beautiful UI** | Modern WinUI 3 interface with light/dark mode support |
| 🚀 **Quick Launch** | Launch any VS instance with a single click |
| 🚀 **Quick Launch** | Launch any installation with a single click |
| 🧪 **Experimental Hives** | See and launch experimental/custom VS hives |
| 💻 **Developer Shells** | Launch VS Developer Command Prompt or PowerShell |
| 📁 **Quick Access** | Open installation folders and AppData directories |
| 🖥️ **Windows Terminal** | Integrates with your Windows Terminal profiles |
| 📌 **System Tray** | Lives quietly in your system tray until needed |
| ⚙️ **Configurable** | Startup and window behavior settings |
| 🪟 **Custom Chrome** | Sleek custom title bar with VS purple branding |

### 💻 **Visual Studio Features**

| Feature | Description |
|---------|-------------|
| 💻 **Developer Shells** | Launch VS Developer Command Prompt or PowerShell |
| 📁 **Quick Access** | Open installation folders and AppData directories |
| 🖥️ **Windows Terminal** | Integrates with your Windows Terminal profiles |
| 🛠️ **VS Installer Integration** | Modify, update, or manage installations directly |
| 📦 **Workload Detection** | View installed workloads for each instance |
| 📂 **Recent Projects** | Quick access to recently opened solutions ⭐ **NEW!** |

### 📝 **VS Code Features** ⭐ **NEW!**

| Feature | Description |
|---------|-------------|
| 🧩 **Extension Detection** | Automatically detects installed VS Code extensions |
| 📂 **Quick Access** | Open extensions folder, data folder, and installation directory |
| 🪟 **New Window** | Launch new VS Code windows quickly |
| 🎨 **Custom Icons** | Support for custom VS Code icons |
| 📂 **Recent Folders** | Quick access to recently opened folders ⭐ **NEW!** |

---

## 📸 Screenshots

### Instance List
See all your Visual Studio installations at a glance, including version info, build numbers, and channel badges:
See all your Visual Studio and VS Code installations at a glance, including version info, build numbers, and channel badges:

![Instance List](assets/instance-list.png)
![Instance List](assets/instance-list-v2.png)

### Hover State
Hover over any installation to highlight it with the signature purple accent:

![Instance List Hover](assets/instance-list-hover.png)

### Quick Actions Menu
Access powerful options for each installation - open folders, launch dev shells, and more:
Access powerful options for each installation - open folders, launch dev shells, manage with VS Installer, and more:

![Instance Menu](assets/instance-list-menu.png)
![Instance Menu](assets/instance-list-menu-v2.png)

### Settings
Configure startup behavior and window preferences:
Expand Down Expand Up @@ -87,13 +107,31 @@ dotnet run --project src/CodingWithCalvin.VSToolbox

## 🎮 Usage

### 🖱️ Installed Tab
- **Click** the ▶️ play button to launch Visual Studio
- **Click** the ⚙️ gear button for more options:
- 📂 Open Explorer - Open the VS installation folder
- 💻 VS CMD Prompt - Launch Developer Command Prompt
- 🐚 VS PowerShell - Launch Developer PowerShell
- 📁 Open Local AppData - Access VS settings and extensions
### 🖱️ Visual Studio Instances

**Click** the ▶️ play button to launch Visual Studio, or **click** the ⚙️ gear button for more options:

#### 📋 **Visual Studio Menu:**
- 📂 **Recent Projects** ⭐ **NEW!** - Quick access to recently opened solutions
- 📂 **Open Explorer** - Open the VS installation folder
- 💻 **VS CMD Prompt** - Launch Developer Command Prompt
- 🐚 **VS PowerShell** - Launch Developer PowerShell
- 🛠️ **Visual Studio Installer** ⭐ **NEW!**
- 🔧 **Modify Installation** - Add/remove workloads and components
- 📥 **Update** - Install available updates
- 🚀 **Open Installer** - Launch VS Installer dashboard
- 📁 **Open Local AppData** - Access VS settings and extensions

### 🖱️ VS Code Instances ⭐ **NEW!**

**Click** the ▶️ play button to launch VS Code, or **click** the ⚙️ gear button for more options:

#### 📋 **VS Code Menu:**
- 📂 **Recent Folders** ⭐ **NEW!** - Quick access to recently opened folders
- 🧩 **Open Extensions Folder** - Browse installed extensions
- 🪟 **Open New Window** - Launch a new VS Code window
- 📂 **Open Installation Folder** - Browse VS Code files
- 📁 **Open VS Code Data Folder** - Access settings and configuration

### ⚙️ Settings Tab
- **Launch on startup** - Start Visual Studio Toolbox when Windows starts
Expand All @@ -119,7 +157,16 @@ VSToolbox/
│ │
│ └── 📁 CodingWithCalvin.VSToolbox.Core/ # 📦 Core Library
│ ├── 📁 Models/ # Data models
│ └── 📁 Services/ # VS detection & launch
│ └── 📁 Services/ # VS & VS Code detection
├── 📁 docs/ # 📚 Documentation
│ ├── VSCODE_INTEGRATION.md # VS Code features guide
│ ├── VS_INSTALLER_INTEGRATION.md # VS Installer guide
│ ├── RECENT_PROJECTS.md # Recent Projects feature guide
│ └── VSCODE_ICONS.md # Icon setup guide
├── 📁 scripts/ # 🔧 Helper scripts
│ └── extract_vscode_icons.ps1 # Extract VS Code icons
└── 📁 tests/ # 🧪 Unit tests
```
Expand All @@ -130,7 +177,7 @@ VSToolbox/

| Technology | Purpose |
|------------|---------|
| 💜 **C# 13** | Language |
| 💜 **C# 14** | Language |
| 🎯 **.NET 10** | Runtime |
| 🎨 **WinUI 3** | UI Framework |
| 📦 **Windows App SDK 1.8** | Windows APIs |
Expand All @@ -139,6 +186,74 @@ VSToolbox/

---

## 🆕 What's New

### 🎉 **Latest Features**

#### ✅ **Recent Projects** ⭐ **NEW!**
- Quick access to recently opened solutions for Visual Studio
- Quick access to recently opened folders for VS Code
- Sorted by last access time
- Click to open directly

#### ✅ **VS Code Integration** ⭐
- Detects Visual Studio Code and VS Code Insiders
- Shows installed extensions
- Quick access to VS Code folders
- Custom icon support

#### ✅ **Visual Studio Installer Integration** ⭐
- Modify installations directly from VSToolbox
- Update Visual Studio with one click
- Quick access to VS Installer dashboard

#### ✅ **Enhanced Detection**
- Faster and more reliable detection
- Support for multiple VS Code installation locations
- Extension discovery and counting

See [RECENT_PROJECTS.md](docs/RECENT_PROJECTS.md), [VSCODE_INTEGRATION.md](docs/VSCODE_INTEGRATION.md) and [VS_INSTALLER_INTEGRATION.md](docs/VS_INSTALLER_INTEGRATION.md) for detailed documentation.

---

## 📚 Documentation

- 📖 [VS Code Integration Guide](docs/VSCODE_INTEGRATION.md)
- 🛠️ [Visual Studio Installer Integration](docs/VS_INSTALLER_INTEGRATION.md)
- 📂 [Recent Projects Feature](docs/RECENT_PROJECTS.md) ⭐ **NEW!**
- 🎨 [VS Code Icons Setup](docs/VSCODE_ICONS.md)
- 📝 [Implementation Details](docs/VS_INSTALLER_IMPLEMENTATION.md)

---

## 🔧 Advanced Features

### **Extract VS Code Icons**

Run the included PowerShell script to extract icons from your VS Code installations:

```powershell
.\scripts\extract_vscode_icons.ps1
```

Options:
```powershell
# Custom output directory
.\scripts\extract_vscode_icons.ps1 -OutputDir "C:\custom\path"

# Custom icon size
.\scripts\extract_vscode_icons.ps1 -Size 256
```

### **Visual Studio Installer Commands**

Use the context menu to access VS Installer features:
- **Modify** - Opens the installer to add/remove workloads
- **Update** - Automatically updates the VS instance
- **Open Installer** - Launches the main installer window

---

## 🤝 Contributing

Contributions are welcome! Feel free to:
Expand All @@ -152,7 +267,7 @@ Contributions are welcome! Feel free to:
## 👥 Contributors

<!-- readme: contributors -start -->
[![CalvinAllen](https://avatars.githubusercontent.com/u/41448698?v=4&s=64)](https://github.com/CalvinAllen) [![timheuer](https://avatars.githubusercontent.com/u/4821?v=4&s=64)](https://github.com/timheuer)
[![CalvinAllen](https://avatars.githubusercontent.com/u/41448698?v=4&s=64)](https://github.com/CalvinAllen) [![timheuer](https://avatars.githubusercontent.com/u/4821?v=4&s=64)](https://github.com/timheuer) [![eincioch](https://avatars.githubusercontent.com/u/12565944?v=4&s=64)](https://github.com/eincioch)
<!-- readme: contributors -end -->

---
Expand All @@ -165,16 +280,34 @@ This project is licensed under the **MIT License** - see the [LICENSE](LICENSE)

## 💖 Acknowledgments

- 🙏 Microsoft for Visual Studio and WinUI
- 🙏 Microsoft for Visual Studio, VS Code, and WinUI
- 💡 JetBrains Toolbox for the inspiration
- 🎨 The .NET community for amazing libraries
- 🌟 All contributors and users of this project

---

## 🗺️ Roadmap

Future enhancements we're considering:

- [x] ~~Recent projects list~~ ✅ **Implemented!**
- [ ] VS Code workspace detection
- [ ] VS Code extension management
- [ ] More Visual Studio Installer commands
- [ ] Custom launch arguments
- [ ] Keyboard shortcuts
- [ ] Solution file associations
- [ ] Pin favorite projects

---

<div align="center">

**Made with 💜 by [Coding with Calvin](https://github.com/CodingWithCalvin)**

⭐ Star this repo if you find it useful! ⭐
⭐ **Star this repo if you find it useful!** ⭐

🐛 [Report a bug](https://github.com/CalvinAllen/VSToolbox/issues) · 💡 [Request a feature](https://github.com/CalvinAllen/VSToolbox/issues)

</div>
Binary file added assets/instance-list-menu-v2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/instance-list-v2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions src/CodingWithCalvin.VSToolbox.Core/Models/RecentProject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace CodingWithCalvin.VSToolbox.Core.Models;

public sealed class RecentProject
{
public required string Name { get; init; }
public required string Path { get; init; }
public required DateTimeOffset LastAccessed { get; init; }
public bool IsSolution => Path.EndsWith(".sln", StringComparison.OrdinalIgnoreCase);
public bool IsFolder => Directory.Exists(Path) && !File.Exists(Path);

public string DisplayName => System.IO.Path.GetFileNameWithoutExtension(Name);
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DisplayName property in RecentProject uses Path.GetFileNameWithoutExtension(Name) which could throw an exception if Name contains invalid path characters. Consider adding error handling or validating the Name property.

Suggested change
public string DisplayName => System.IO.Path.GetFileNameWithoutExtension(Name);
public string DisplayName
{
get
{
if (string.IsNullOrWhiteSpace(Name))
{
return string.Empty;
}
try
{
return System.IO.Path.GetFileNameWithoutExtension(Name);
}
catch (System.ArgumentException)
{
// Fallback to the raw name if it contains invalid path characters.
return Name;
}
}
}

Copilot uses AI. Check for mistakes.

public string ProjectType => Path switch
{
var p when p.EndsWith(".sln", StringComparison.OrdinalIgnoreCase) => "Solution",
var p when p.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase) => "C# Project",
var p when p.EndsWith(".vbproj", StringComparison.OrdinalIgnoreCase) => "VB.NET Project",
var p when p.EndsWith(".fsproj", StringComparison.OrdinalIgnoreCase) => "F# Project",
var p when p.EndsWith(".vcxproj", StringComparison.OrdinalIgnoreCase) => "C++ Project",
var p when Directory.Exists(p) => "Folder",
_ => "Project"
};

public bool Exists => File.Exists(Path) || Directory.Exists(Path);
}
4 changes: 3 additions & 1 deletion src/CodingWithCalvin.VSToolbox.Core/Models/VSSku.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ public enum VSSku
Community,
Professional,
Enterprise,
BuildTools
BuildTools,
VSCode,
VSCodeInsiders
}
3 changes: 2 additions & 1 deletion src/CodingWithCalvin.VSToolbox.Core/Models/VSVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ public enum VSVersion
{
VS2019 = 16,
VS2022 = 17,
VS2026 = 18 // Anticipated major version
VS2026 = 18,
VSCode = 100
}
24 changes: 20 additions & 4 deletions src/CodingWithCalvin.VSToolbox.Core/Models/VisualStudioInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,20 @@ public sealed class VisualStudioInstance

private static string ParseChannelType(string channelId)
{
// ChannelId format: VisualStudio.{majorVersion}.{channel}
// e.g., VisualStudio.17.Release, VisualStudio.17.Preview, VisualStudio.17.Canary
var parts = channelId.Split('.');
if (parts.Length < 2)
return "Unknown";

if (parts[0] == "VSCode")
{
return parts[^1] switch
{
"Stable" => "Stable",
"Insiders" => "Insiders",
_ => parts[^1]
};
}

if (parts.Length < 3)
return "Unknown";

Expand All @@ -42,9 +53,13 @@ private static string ParseChannelType(string channelId)
}

public bool CanLaunch => !string.IsNullOrEmpty(ProductPath) &&
ProductPath.EndsWith("devenv.exe", StringComparison.OrdinalIgnoreCase);
(ProductPath.EndsWith("devenv.exe", StringComparison.OrdinalIgnoreCase) ||
ProductPath.EndsWith("Code.exe", StringComparison.OrdinalIgnoreCase) ||
ProductPath.EndsWith("Code - Insiders.exe", StringComparison.OrdinalIgnoreCase));

public string ShortDisplayName => $"Visual Studio {GetVersionYear()} {Sku}";
public string ShortDisplayName => Version == VSVersion.VSCode
? (Sku == VSSku.VSCodeInsiders ? "VS Code Insiders" : "VS Code")
: $"Visual Studio {GetVersionYear()} {Sku}";

public string VersionYear => GetVersionYear();

Expand All @@ -53,6 +68,7 @@ private static string ParseChannelType(string channelId)
VSVersion.VS2019 => "2019",
VSVersion.VS2022 => "2022",
VSVersion.VS2026 => "2026",
VSVersion.VSCode => "Code",
_ => "Unknown"
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using CodingWithCalvin.VSToolbox.Core.Models;

namespace CodingWithCalvin.VSToolbox.Core.Services;

public interface IRecentProjectsService
{
IReadOnlyList<RecentProject> GetRecentProjects(VisualStudioInstance instance, int maxCount = 10);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using CodingWithCalvin.VSToolbox.Core.Models;

namespace CodingWithCalvin.VSToolbox.Core.Services;

public interface IVSCodeDetectionService
{
Task<IReadOnlyList<VisualStudioInstance>> GetInstalledInstancesAsync(CancellationToken cancellationToken = default);
}
Loading
Loading