Skip to content
Merged
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
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
# 2.5.1 (2025-07-29)

- 🐛 Improved error handling when loading or unloading projects fails.

# 2.5.0 (2023-12-23)

- ✨ Filtering options (load dependencies, use regular expressions, etc.) are now stored on a per-solution basis.
- ✨ The expanded state of nodes in the Project Filter dialog are remembered.

# 2.4.1 (2023-08-14)

- 🐛 When using a Solution Filter (`.slnf`), projects would sometimes be hidden in Solution Explorer after they were loaded (#4).
- 🐛 When using a Solution Filter (`.slnf`), projects would sometimes be hidden in Solution Explorer after they were loaded (#4).

# 2.4.0 (2022-10-22)

Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>

<PropertyGroup>
<Version>2.5.0</Version>
<Version>2.5.1</Version>
<TargetFramework>net48</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>10.0</LangVersion>
Expand Down
4 changes: 2 additions & 2 deletions global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "9.0.200"
"version": "9.0.302"
}
}
}
4 changes: 2 additions & 2 deletions source/ProjectFilter/ProjectFilter.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Community.VisualStudio.Toolkit.17" Version="17.0.527" />
<PackageReference Include="Community.VisualStudio.Toolkit.17" Version="17.0.533" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.SDK" Version="17.0.32112.339" ExcludeAssets="runtime">
<IncludeAssets>compile; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VSSDK.BuildTools" Version="17.13.2126">
<PackageReference Include="Microsoft.VSSDK.BuildTools" Version="17.14.2094">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
59 changes: 42 additions & 17 deletions source/ProjectFilter/Services/FilterService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,19 +137,26 @@ private static async Task UnloadProjectAsync(Guid identifier, State state) {

if (IsLoaded(state.Solution, identifier)) {
string name;
int result;


name = state.Solution.GetName(identifier);
state.SetProgressText($"Unloading {name}...");

result = state.Solution.UnloadProject(
identifier,
(uint)_VSProjectUnloadStatus.UNLOADSTATUS_UnloadedByUser
);
try {
int result;


result = state.Solution.UnloadProject(
identifier,
(uint)_VSProjectUnloadStatus.UNLOADSTATUS_UnloadedByUser
);

if (ErrorHandler.Failed(result)) {
await LogFailureAsync($"Failed to unload project '{name}'.", result);
if (ErrorHandler.Failed(result)) {
await LogFailureAsync($"Failed to unload project '{name}'.", result);
}

} catch (Exception ex) when (!ErrorHandler.IsCriticalException(ex)) {
await LogFailureAsync($"Failed to unload project '{name}'.", ex);
}

state.OnProjectUnloaded(identifier);
Expand All @@ -166,23 +173,33 @@ private static async Task LoadProjectAsync(Guid identifier, bool loadProjectDepe
// visited it before, then we don't need to do anything this time.
if (state.ProjectsVisitedWhileLoading.Add(identifier)) {
IEnumerable<Guid>? dependencies;
bool loaded;
bool wasLoaded;


dependencies = null;
loaded = false;
wasLoaded = false;

if (!IsLoaded(state.Solution, identifier)) {
string name;
int result;


name = state.Solution.GetName(identifier);
state.SetProgressText($"Loading {name}...");
result = state.Solution.ReloadProject(identifier);

if (ErrorHandler.Failed(result)) {
await LogFailureAsync($"Failed to load project '{name}'.", result);
try {
int result;


result = state.Solution.ReloadProject(identifier);

if (ErrorHandler.Failed(result)) {
await LogFailureAsync($"Failed to load project '{name}'.", result);
return;
}

} catch (Exception ex) when (!ErrorHandler.IsCriticalException(ex)) {
await LogFailureAsync($"Failed to load project '{name}'.", ex);
return;
}

// Don't record that we've loaded the project _yet_. If we do that
Expand All @@ -193,7 +210,7 @@ private static async Task LoadProjectAsync(Guid identifier, bool loadProjectDepe
// the progress will increase to 100% and then immediately decrease.
// We'll wait until we've recorded that the dependencies need to be
// loaded before we record that this project was loaded.
loaded = true;
wasLoaded = true;

// Whenever a project is loaded, we should recalculate project dependencies
// to ensure that the new project's dependencies are correct.
Expand All @@ -219,7 +236,7 @@ private static async Task LoadProjectAsync(Guid identifier, bool loadProjectDepe
// if we actually loaded the given project, then we can record that
// it has been loaded. This prevents the progress from increasing
// and then decreasing (instead, it will decrease and then increase).
if (loaded) {
if (wasLoaded) {
state.OnProjectLoaded(identifier);
}

Expand Down Expand Up @@ -357,13 +374,21 @@ private static async Task<IEnumerable<Guid>> GetProjectsToCollapseAsync(ISolutio
}


private static async Task LogFailureAsync(string message, int result) {
private static Task LogFailureAsync(string message, int result) {
return LogFailureAsync(message, Marshal.GetExceptionForHR(result));
}


private static async Task LogFailureAsync(string message, Exception? ex) {
ILogger logger;
string exceptionMessage;


logger = await VS.GetRequiredServiceAsync<ILogger, ILogger>();

await logger.WriteLineAsync($"{message} {Marshal.GetExceptionForHR(result).Message}");
exceptionMessage = ex?.Message ?? "[Unknown Error]";

await logger.WriteLineAsync($"{message} {exceptionMessage}");
}

}
8 changes: 4 additions & 4 deletions tests/ProjectFilter.UnitTests/ProjectFilter.UnitTests.csproj
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<RootNamespace>ProjectFilter</RootNamespace>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Community.VisualStudio.Toolkit.17" Version="17.0.527" />
<PackageReference Include="Community.VisualStudio.Toolkit.17" Version="17.0.533" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="Microsoft.VisualStudio.SDK" Version="17.0.32112.339" />
<PackageReference Include="Microsoft.VisualStudio.Sdk.TestFramework" Version="17.2.7" />
<PackageReference Include="Microsoft.VisualStudio.Sdk.TestFramework.Xunit" Version="17.2.7" />
<PackageReference Include="NSubstitute" Version="5.1.0" />
<PackageReference Include="NSubstitute" Version="5.3.0" />
<PackageReference Include="xunit" Version="2.6.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.5">
<PrivateAssets>all</PrivateAssets>
Expand Down