From 3ffee078831c7f0cf5cb2a99fff99398b2c8a3d4 Mon Sep 17 00:00:00 2001 From: "Calvin A. Allen" Date: Thu, 14 May 2026 09:40:14 -0400 Subject: [PATCH 1/2] fix(commands): skip Web Site projects when cleaning For legacy Web Site Projects (project type GUID {E24C65DC-7377-472B-9ABA-BC803B73C61A}) the bin folder is not a build output; it contains assemblies that are integral to the project. Detect these via Project.IsKindAsync(ProjectTypes.WEBSITE) and skip them. --- .../Commands/SuperCleanCommand.cs | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/CodingWithCalvin.SuperClean/Commands/SuperCleanCommand.cs b/src/CodingWithCalvin.SuperClean/Commands/SuperCleanCommand.cs index a0716b8..72027c6 100644 --- a/src/CodingWithCalvin.SuperClean/Commands/SuperCleanCommand.cs +++ b/src/CodingWithCalvin.SuperClean/Commands/SuperCleanCommand.cs @@ -116,8 +116,10 @@ Unable to Super Clean solution case SolutionItemType.Project: try { - SuperCleanProject(activeItem); - VsixTelemetry.LogInformation("Project super cleaned successfully"); + var cleaned = await SuperCleanProjectAsync(activeItem); + VsixTelemetry.LogInformation(cleaned + ? "Project super cleaned successfully" + : $"Project skipped: {activeItem.Name}"); } catch (Exception ex) { @@ -151,8 +153,10 @@ Unable to Super Clean project ${activeItem.Name} { try { - SuperCleanProject(project); - projectCount++; + if (await SuperCleanProjectAsync(project)) + { + projectCount++; + } } catch (Exception ex) { @@ -168,11 +172,19 @@ Unable to Super Clean project ${activeItem.Name} return (success, errors.ToString()); } - void SuperCleanProject(SolutionItem project) + async Task SuperCleanProjectAsync(SolutionItem project) { using var projectActivity = VsixTelemetry.StartCommandActivity("SuperClean.SuperCleanProject"); - var projectPath = + if (project is Project typedProject && await typedProject.IsKindAsync(ProjectTypes.WEBSITE)) + { + projectActivity?.SetTag("skipped", true); + projectActivity?.SetTag("skip.reason", "website-project"); + VsixTelemetry.LogInformation($"Skipped Web Site project: {project.Name}"); + return false; + } + + var projectPath = Path.GetDirectoryName(project.FullPath) ?? throw new InvalidOperationException(); @@ -190,6 +202,8 @@ void SuperCleanProject(SolutionItem project) Directory.Delete(objPath, true); projectActivity?.SetTag("obj.deleted", true); } + + return true; } } } From 55f3d4993d5d1a9c7862ebd8021e5b9a59d3aaaf Mon Sep 17 00:00:00 2001 From: "Calvin A. Allen" Date: Thu, 14 May 2026 09:46:03 -0400 Subject: [PATCH 2/2] feat(commands): notify user when Web Site projects are skipped Show a single summary MessageBox after a solution-level Super Clean listing any skipped Web Site projects, and a dedicated MessageBox when Super Clean is invoked directly on a Web Site project so the user understands why nothing was cleaned. --- .../Commands/SuperCleanCommand.cs | 41 ++++++++++++++++--- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/CodingWithCalvin.SuperClean/Commands/SuperCleanCommand.cs b/src/CodingWithCalvin.SuperClean/Commands/SuperCleanCommand.cs index 72027c6..bbef494 100644 --- a/src/CodingWithCalvin.SuperClean/Commands/SuperCleanCommand.cs +++ b/src/CodingWithCalvin.SuperClean/Commands/SuperCleanCommand.cs @@ -86,7 +86,7 @@ private static async Task OpenPathAsync(object sender, EventArgs e) case SolutionItemType.Solution: try { - var (success, errors) = await SuperCleanSolution(); + var (success, errors, skippedWebsites) = await SuperCleanSolution(); if (!success) { @@ -94,6 +94,16 @@ private static async Task OpenPathAsync(object sender, EventArgs e) } VsixTelemetry.LogInformation("Solution super cleaned successfully"); + + if (skippedWebsites.Count > 0) + { + MessageBox.Show( + $"Super Clean skipped the following Web Site project(s) because their bin folder is required at runtime:{Environment.NewLine}{Environment.NewLine} • {string.Join($"{Environment.NewLine} • ", skippedWebsites)}", + "Super Clean", + System.Windows.Forms.MessageBoxButtons.OK, + System.Windows.Forms.MessageBoxIcon.Information + ); + } } catch (Exception ex) { @@ -117,9 +127,22 @@ Unable to Super Clean solution try { var cleaned = await SuperCleanProjectAsync(activeItem); - VsixTelemetry.LogInformation(cleaned - ? "Project super cleaned successfully" - : $"Project skipped: {activeItem.Name}"); + + if (cleaned) + { + VsixTelemetry.LogInformation("Project super cleaned successfully"); + } + else + { + VsixTelemetry.LogInformation($"Project skipped: {activeItem.Name}"); + + MessageBox.Show( + $"Super Clean skipped \"{activeItem.Name}\" because Web Site projects rely on their bin folder at runtime.", + "Super Clean", + System.Windows.Forms.MessageBoxButtons.OK, + System.Windows.Forms.MessageBoxIcon.Information + ); + } } catch (Exception ex) { @@ -141,13 +164,14 @@ Unable to Super Clean project ${activeItem.Name} break; } - async Task<(bool, string)> SuperCleanSolution() + async Task<(bool, string, List)> SuperCleanSolution() { using var solutionActivity = VsixTelemetry.StartCommandActivity("SuperClean.SuperCleanSolution"); var success = true; var errors = new StringBuilder(); var projectCount = 0; + var skippedWebsites = new List(); foreach (var project in await VS.Solutions.GetAllProjectsAsync()) { @@ -157,6 +181,10 @@ Unable to Super Clean project ${activeItem.Name} { projectCount++; } + else + { + skippedWebsites.Add(project.Name); + } } catch (Exception ex) { @@ -167,9 +195,10 @@ Unable to Super Clean project ${activeItem.Name} } solutionActivity?.SetTag("projects.cleaned", projectCount); + solutionActivity?.SetTag("projects.skipped", skippedWebsites.Count); solutionActivity?.SetTag("success", success); - return (success, errors.ToString()); + return (success, errors.ToString(), skippedWebsites); } async Task SuperCleanProjectAsync(SolutionItem project)