diff --git a/src/DotNetCensus.Core/GlobalSuppressions.cs b/src/DotNetCensus.Core/GlobalSuppressions.cs new file mode 100644 index 00000000..09e6d4a6 --- /dev/null +++ b/src/DotNetCensus.Core/GlobalSuppressions.cs @@ -0,0 +1,9 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +//Not a clear rule. Suppressing. +[assembly: SuppressMessage("Style", "IDE0054:Use compound assignment", Justification = "", Scope = "member", Target = "~M:DotNetCensus.Core.ProjectScanning.EnumerateFiles(System.String,System.String)~System.Collections.Generic.IEnumerable{System.IO.FileInfo}")] diff --git a/src/DotNetCensus.Core/ProjectScanning.cs b/src/DotNetCensus.Core/ProjectScanning.cs index 97264555..cc69ff7b 100644 --- a/src/DotNetCensus.Core/ProjectScanning.cs +++ b/src/DotNetCensus.Core/ProjectScanning.cs @@ -1,4 +1,5 @@ using DotNetCensus.Core.Models; +using System.Security; using System.Text.Json; namespace DotNetCensus.Core @@ -12,7 +13,8 @@ public static List SearchDirectory(string directory) List projects = new(); if (string.IsNullOrEmpty(directory) == false) { - foreach (FileInfo fileInfo in new DirectoryInfo(directory).GetFiles("*.*", SearchOption.AllDirectories)) + //foreach (FileInfo fileInfo in new DirectoryInfo(directory).GetFiles("*.*", SearchOption.AllDirectories)) + foreach (FileInfo fileInfo in EnumerateFiles(directory,"*.*")) { //if .NET project files are found, process them switch (fileInfo.Extension.ToLower()) @@ -373,5 +375,57 @@ private static string GetHistoricalFrameworkVersion(string line) return "unknown"; } } + + //From: https://stackoverflow.com/questions/37294702/directoryinfo-getfiles-error-system-unathorizedaccessexception + public static IEnumerable EnumerateFiles(string path, string? searchPattern = null) + { + if (searchPattern != null) + { + searchPattern = searchPattern ?? "*"; + } + + var queue = new Queue(); + queue.Enqueue(path); + + do + { + path = queue.Dequeue(); + foreach (var file in SafeEnumerateFiles(path, searchPattern)) + { + yield return new FileInfo(file); + } + foreach (var directory in SafeEnumerateDirectories(path)) + { + queue.Enqueue(directory); + } + } + while (queue.Any()); + } + + static IEnumerable SafeEnumerateFiles(string path, string searchPattern) + { + try + { + return Directory.EnumerateFiles(path, searchPattern); + } + catch (DirectoryNotFoundException) { } + catch (SecurityException) { } + catch (UnauthorizedAccessException) { } + + return Enumerable.Empty(); + } + + static IEnumerable SafeEnumerateDirectories(string path) + { + try + { + return Directory.EnumerateDirectories(path); + } + catch (DirectoryNotFoundException) { } + catch (SecurityException) { } + catch (UnauthorizedAccessException) { } + + return Enumerable.Empty(); + } } } diff --git a/src/DotNetCensus.Tests/ConsoleAppTests.cs b/src/DotNetCensus.Tests/ConsoleAppTests.cs index 98435e43..2899fdee 100644 --- a/src/DotNetCensus.Tests/ConsoleAppTests.cs +++ b/src/DotNetCensus.Tests/ConsoleAppTests.cs @@ -288,4 +288,5 @@ public void RunSamplesWithInvalidParametersTest() } } } + }