Skip to content

Commit 8ea1f94

Browse files
committed
Add support for Visual Studio 2026, including a right-click option to open a solution in a different installed version.
1 parent 973019d commit 8ea1f94

16 files changed

+206
-44
lines changed
Lines changed: 50 additions & 0 deletions
Loading

WorkspaceLauncherForVSCode/Classes/Constant.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public static class Constant
1212
public const string AppName = "WorkspaceLauncherForVSCode";
1313
#endif
1414
public const string VscodeRemoteScheme = "vscode-remote://";
15+
public const string VisualStudio2026Version = "18";
1516
public static readonly string AssemblyVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? string.Empty;
1617
public static readonly string SettingsFolderPath = Utilities.BaseSettingsPath(AppName);
1718
}

WorkspaceLauncherForVSCode/Classes/Icon.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public static class Icon
88
{
99
public static readonly IconInfo Extension = IconHelpers.FromRelativePath(@"Assets\icon.svg");
1010
public static readonly IconInfo VisualStudio = IconHelpers.FromRelativePath(@"Assets\VisualStudioIcon.svg");
11+
public static readonly IconInfo VisualStudio2026 = IconHelpers.FromRelativePath(@"Assets\VisualStudioIcon2026.svg");
1112
public static readonly IconInfo VisualStudioCode = IconHelpers.FromRelativePath("Assets\\VisualStudioCodeIcon.svg");
1213
public static readonly IconInfo VisualStudioAndVisualStudioCode = IconHelpers.FromRelativePath("Assets\\VisualStudioAndVisualStudioCodeIcon.svg");
1314
public static readonly IconInfo FileExplorer = IconHelpers.FromRelativePath("Assets\\FileExplorer.svg");

WorkspaceLauncherForVSCode/Classes/VisualStudioCodeWorkspace.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ public void SetWorkspaceType()
118118
WorkspaceTypeString = "Folder";
119119
break;
120120
case WorkspaceType.Solution:
121+
case WorkspaceType.Solution2026:
121122
WorkspaceTypeString = "Solution";
122123
break;
123124
default:

WorkspaceLauncherForVSCode/Classes/WorkspaceStorage.cs

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Threading.Tasks;
88
using Microsoft.CommandPalette.Extensions.Toolkit;
99
using Microsoft.Data.Sqlite;
10+
using WorkspaceLauncherForVSCode.Enums;
1011

1112
namespace WorkspaceLauncherForVSCode.Classes
1213
{
@@ -19,12 +20,13 @@ public sealed partial class WorkspaceStorage : IDisposable
1920
private static class Queries
2021
{
2122
public const string Initialize = @"
22-
CREATE TABLE IF NOT EXISTS Workspaces (
23-
Path TEXT PRIMARY KEY,
23+
CREATE TABLE IF NOT EXISTS WorkspacesV2 (
24+
Path TEXT,
2425
Name TEXT,
2526
Type INTEGER,
2627
Frequency INTEGER DEFAULT 0,
27-
LastAccessed TEXT
28+
LastAccessed TEXT,
29+
PRIMARY KEY (Path, Type)
2830
);
2931
CREATE TABLE IF NOT EXISTS PinnedWorkspaces (
3032
Path TEXT PRIMARY KEY,
@@ -38,28 +40,28 @@ PinDateTime TEXT NOT NULL
3840
w.Frequency,
3941
w.LastAccessed,
4042
p.PinDateTime
41-
FROM Workspaces w
43+
FROM WorkspacesV2 w
4244
LEFT JOIN PinnedWorkspaces p ON w.Path = p.Path;
4345
";
4446

4547
public const string SaveWorkspace = @"
46-
INSERT OR REPLACE INTO Workspaces (Path, Name, Type, Frequency, LastAccessed)
48+
INSERT OR REPLACE INTO WorkspacesV2 (Path, Name, Type, Frequency, LastAccessed)
4749
VALUES (
4850
@Path,
4951
@Name,
5052
@Type,
51-
COALESCE((SELECT Frequency FROM Workspaces WHERE Path = @Path), @Frequency),
52-
COALESCE((SELECT LastAccessed FROM Workspaces WHERE Path = @Path), @LastAccessed)
53+
COALESCE((SELECT Frequency FROM WorkspacesV2 WHERE Path = @Path AND Type = @Type), @Frequency),
54+
COALESCE((SELECT LastAccessed FROM WorkspacesV2 WHERE Path = @Path AND Type = @Type), @LastAccessed)
5355
);
5456
";
5557

56-
public const string UpdateFrequency = "UPDATE Workspaces SET Frequency = Frequency + 1, LastAccessed = @LastAccessed WHERE Path = @path";
58+
public const string UpdateFrequency = "UPDATE WorkspacesV2 SET Frequency = Frequency + 1, LastAccessed = @LastAccessed WHERE Path = @path AND Type = @Type";
5759

5860
public const string GetPinnedWorkspaces = "SELECT Path, PinDateTime FROM PinnedWorkspaces";
5961
public const string AddPinnedWorkspace = "INSERT OR REPLACE INTO PinnedWorkspaces (Path, PinDateTime) VALUES (@Path, @PinDateTime)";
6062
public const string RemovePinnedWorkspace = "DELETE FROM PinnedWorkspaces WHERE Path = @Path";
6163

62-
public const string ResetAllFrequencies = "UPDATE Workspaces SET Frequency = 0";
64+
public const string ResetAllFrequencies = "UPDATE WorkspacesV2 SET Frequency = 0";
6365
}
6466

6567
public WorkspaceStorage()
@@ -82,9 +84,34 @@ private void InitializeDatabase()
8284
{
8385
try
8486
{
85-
using var command = _connection.CreateCommand();
86-
command.CommandText = Queries.Initialize;
87-
command.ExecuteNonQuery();
87+
using var transaction = _connection.BeginTransaction();
88+
89+
// 1. Initialize V2 Table and PinnedWorkspaces
90+
var initCmd = _connection.CreateCommand();
91+
initCmd.Transaction = transaction;
92+
initCmd.CommandText = Queries.Initialize;
93+
initCmd.ExecuteNonQuery();
94+
95+
// 2. Check if old 'Workspaces' table exists (indicating legacy schema or previous version)
96+
var checkCmd = _connection.CreateCommand();
97+
checkCmd.Transaction = transaction;
98+
checkCmd.CommandText = "SELECT count(*) FROM sqlite_master WHERE type='table' AND name='Workspaces'";
99+
var oldTableExists = (long)checkCmd.ExecuteScalar() > 0;
100+
101+
if (oldTableExists)
102+
{
103+
// 3. Migrate data from 'Workspaces' to 'WorkspacesV2'
104+
var migrateCmd = _connection.CreateCommand();
105+
migrateCmd.Transaction = transaction;
106+
migrateCmd.CommandText = @"
107+
INSERT OR IGNORE INTO WorkspacesV2 (Path, Name, Type, Frequency, LastAccessed)
108+
SELECT Path, Name, Type, Frequency, LastAccessed FROM Workspaces;
109+
DROP TABLE Workspaces;
110+
";
111+
migrateCmd.ExecuteNonQuery();
112+
}
113+
114+
transaction.Commit();
88115
}
89116
catch (Exception ex)
90117
{
@@ -170,13 +197,14 @@ public async Task SaveWorkspacesAsync(IEnumerable<VisualStudioCodeWorkspace> wor
170197
}
171198
}
172199

173-
public async Task UpdateWorkspaceFrequencyAsync(string path)
200+
public async Task UpdateWorkspaceFrequencyAsync(string path, WorkspaceType type)
174201
{
175202
try
176203
{
177204
using var command = _connection.CreateCommand();
178205
command.CommandText = Queries.UpdateFrequency;
179206
command.Parameters.AddWithValue("@path", path);
207+
command.Parameters.AddWithValue("@Type", (int)type);
180208
command.Parameters.AddWithValue("@LastAccessed", DateTime.Now.ToString("o"));
181209
await command.ExecuteNonQueryAsync();
182210
}

WorkspaceLauncherForVSCode/Commands/OpenSolutionCommand.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Microsoft.CommandPalette.Extensions.Toolkit;
88
using WorkspaceLauncherForVSCode.Classes;
99
using WorkspaceLauncherForVSCode.Components;
10+
using WorkspaceLauncherForVSCode.Enums;
1011
using WorkspaceLauncherForVSCode.Helpers;
1112
using WorkspaceLauncherForVSCode.Interfaces;
1213

@@ -35,6 +36,10 @@ public OpenSolutionCommand(VisualStudioCodeWorkspace workspace, VisualStudioCode
3536
{
3637
Name = "Open";
3738
this.Icon = Classes.Icon.VisualStudio;
39+
if (workspace.WorkspaceType == WorkspaceType.Solution2026)
40+
{
41+
this.Icon = Classes.Icon.VisualStudio2026;
42+
}
3843
}
3944
}
4045
catch (Exception ex)
@@ -64,7 +69,7 @@ public override CommandResult Invoke()
6469

6570
if (page != null)
6671
{
67-
Task.Run(() => page.UpdateFrequencyAsync(Workspace.Path));
72+
Task.Run(() => page.UpdateFrequencyAsync(Workspace.Path, Workspace.WorkspaceType));
6873
}
6974

7075
OpenWindows.Instance.UpdateVisualStudioWindowsList();

WorkspaceLauncherForVSCode/Commands/OpenVisualStudioCodeCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public override CommandResult Invoke()
117117
OpenInShellHelper.OpenInShell(Workspace.VSCodeInstance.ExecutablePath, arguments, runAs: _elevated ? OpenInShellHelper.ShellRunAsType.Administrator : OpenInShellHelper.ShellRunAsType.None);
118118
}
119119

120-
Task.Run(() => page.UpdateFrequencyAsync(Workspace.Path));
120+
Task.Run(() => page.UpdateFrequencyAsync(Workspace.Path, Workspace.WorkspaceType));
121121

122122
return PageCommandResultHandler.HandleCommandResult(page);
123123
}

WorkspaceLauncherForVSCode/Enums/WorkspaceType.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ public enum WorkspaceType
1010
Workspace,
1111
Folder,
1212
Solution,
13+
Solution2026,
1314
}

WorkspaceLauncherForVSCode/Interfaces/IVisualStudioCodeService.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Threading.Tasks;
66
using WorkspaceLauncherForVSCode.Classes;
77
using WorkspaceLauncherForVSCode.Enums;
8+
using WorkspaceLauncherForVSCode.Services.VisualStudio.Models;
89

910
namespace WorkspaceLauncherForVSCode;
1011

@@ -14,6 +15,8 @@ public interface IVisualStudioCodeService
1415

1516
List<VisualStudioCodeInstance> GetInstances();
1617

18+
List<VisualStudioInstance> GetVisualStudioInstances();
19+
1720
Task<List<VisualStudioCodeWorkspace>> GetWorkspacesAsync(IEnumerable<VisualStudioCodeWorkspace> dbWorkspaces, CancellationToken cancellationToken);
1821

1922
Task<List<VisualStudioCodeWorkspace>> GetVisualStudioSolutions(IEnumerable<VisualStudioCodeWorkspace> dbWorkspaces, bool includeRegistry);

0 commit comments

Comments
 (0)