Skip to content

Commit

Permalink
Visit hierarchy items only once no matter which items are selected.
Browse files Browse the repository at this point in the history
  • Loading branch information
awulkiew committed Jun 17, 2020
1 parent 895cb8b commit 767154f
Showing 1 changed file with 137 additions and 11 deletions.
148 changes: 137 additions & 11 deletions Visual_Studio_2017/ExcludeFromBuild/Util.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

using EnvDTE;
using EnvDTE80;
using Microsoft.VisualStudio;
using System;
using System.Collections;
using System.Collections.Generic;
Expand Down Expand Up @@ -43,7 +44,8 @@ public static void SetExcludedFromBuild(DTE2 dte, bool value, Configuration conf
var items = dte.ToolWindows.SolutionExplorer.SelectedItems as Array;
if (items == null)
return;
SetExcludedFromBuildRecursive(items, value, configuration);
HashSet<string> visited = new HashSet<string>();
SetExcludedFromBuildRecursive(items, value, configuration, visited);
}

// Casting COM objects to VCFile and VCFilter works but the problem is that
Expand All @@ -53,14 +55,29 @@ public static void SetExcludedFromBuild(DTE2 dte, bool value, Configuration conf

private static void SetExcludedFromBuildRecursive(IEnumerable items,
bool value,
Configuration configuration)
Configuration configuration,
HashSet<string> visited)
{
foreach (var item in items)
{
UIHierarchyItem hitem = item as UIHierarchyItem;
if (hitem == null)
continue;

// Get unique name of current item
string name = null;
if (!IsVisitableItem(hitem, out name))
continue;

// Ignore already visited items if possible
if (name != null)
{
if (visited.Contains(name))
continue;
else
visited.Add(name);
}

// Not expanded UIHierarchyItems report 0 Items
if (!hitem.UIHierarchyItems.Expanded)
{
Expand All @@ -71,7 +88,10 @@ private static void SetExcludedFromBuildRecursive(IEnumerable items,
// Any container, e.g. filter or C# XAML, etc.
if (hitem.UIHierarchyItems.Count > 0)
{
SetExcludedFromBuildRecursive(hitem.UIHierarchyItems, value, configuration);
SetExcludedFromBuildRecursive(hitem.UIHierarchyItems,
value,
configuration,
visited);
}

// For C++ this is Microsoft.VisualStudio.VCProjectEngine.VCProjectItem
Expand Down Expand Up @@ -163,6 +183,46 @@ private static void SetExcludedFromBuildRecursive(IEnumerable items,
}
#pragma warning restore VSTHRD010

private static bool IsVisitableItem(UIHierarchyItem hitem, out string name)
{
name = null;

var pitem = hitem.Object as ProjectItem;
if (pitem != null)
{
name = GetPropertyValue(pitem, "FullPath") as string;
if (name == null)
{
if (pitem.Kind == VSConstants.ItemTypeGuid.VirtualFolder_string
&& pitem.ContainingProject != null)
{
name = pitem.ContainingProject.FullName + "\\"
+ GetPropertyValue(pitem, "CanonicalName") as string;
}
}
}
else
{
var proj = hitem.Object as Project;
if (proj != null)
{
name = proj.FullName;
}
else
{
var solution = hitem.Object as Solution;
if (solution != null)
name = solution.FullName;
else
// Could not be casted to neither ProjectItem, Project nor Solution.
// This is probably a reference, so ignore it.
return false;
}
}

return true;
}

private static void SetPropertyValue(object o, string name, object value)
{
o.GetType().InvokeMember(name,
Expand Down Expand Up @@ -196,19 +256,93 @@ private static Property GetProperty(ProjectItem pitem, string name)
}
}

private static Property GetProperty(Project proj, string name)
{
try
{
return proj.Properties.Item(name);
}
catch (Exception)
{
return null;
}
}

private static Property GetProperty(Solution solution, string name)
{
try
{
return solution.Properties.Item(name);
}
catch (Exception)
{
return null;
}
}

private static object GetPropertyValue(ProjectItem pitem, string name)
{
Property prop = GetProperty(pitem, name);
return prop != null ? prop.Value : null;
}

private static object GetPropertyValue(Project proj, string name)
{
Property prop = GetProperty(proj, name);
return prop != null ? prop.Value : null;
}

private static object GetPropertyValue(Solution solution, string name)
{
Property prop = GetProperty(solution, name);
return prop != null ? prop.Value : null;
}

private static void SetPropertyValue(ProjectItem pitem, string name, object value)
{
Property prop = GetProperty(pitem, name);
if (prop != null)
prop.Value = value;
}

private static void SetPropertyValue(Project proj, string name, object value)
{
Property prop = GetProperty(proj, name);
if (prop != null)
prop.Value = value;
}

private static void SetPropertyValue(Solution solution, string name, object value)
{
Property prop = GetProperty(solution, name);
if (prop != null)
prop.Value = value;
}

private static List<string> GetPropertiesNames(ProjectItem pitem)
{
List<string> result = new List<string>();
foreach (Property p in pitem.Properties)
result.Add(p.Name);
return result;
}

private static List<string> GetPropertiesNames(Project proj)
{
List<string> result = new List<string>();
foreach (Property p in proj.Properties)
result.Add(p.Name);
return result;
}

private static List<string> GetPropertiesNames(Solution solution)
{
List<string> result = new List<string>();
foreach (Property p in solution.Properties)
result.Add(p.Name);
return result;
}

public static Configuration GetConfigurationOption()
{
var package = ExcludeFromBuildPackage.Instance;
Expand All @@ -233,13 +367,5 @@ private static string RootXMLElementName(string url)
return null;
}
}

private static List<string> GetPropertiesNames(ProjectItem pitem)
{
List<string> result = new List<string>();
foreach (Property p in pitem.Properties)
result.Add(p.Name);
return result;
}
}
}

0 comments on commit 767154f

Please sign in to comment.