using System.Collections.Generic; using System.IO; using System.Linq; namespace PortingAssistant.Client.Common.Utils { public static class FileSystemAccess { private static readonly string[] fileTypesToCheck = { ".csproj", ".cs", ".vbproj", ".vb" }; /// /// Checks directory and all content for write access /// /// Directory path /// List of items without write access public static List CheckWriteAccessForDirectory(string path) { var result = (Directory.GetFiles(path) .Where(file => fileTypesToCheck.Contains(Path.GetExtension(file))) .Where(file => !CanWriteFile(file))).ToList(); foreach (string subDirectory in Directory.GetDirectories(path)) { if (!CanWriteToDirectory(subDirectory)) { result.Add(subDirectory); } result.AddRange(CheckWriteAccessForDirectory(subDirectory)); } return result; } /// /// Checks project file and at least one file is writable /// /// Project file path /// True if csproj and at least one .cs file is writable public static bool CheckWriteAccessForProject(string projectFilePath) { return CanWriteFile(projectFilePath) && DirectoryHasWriteableCSharpFile(Path.GetDirectoryName(projectFilePath)); } private static bool DirectoryHasWriteableCSharpFile(string directoryPath) { if (string.IsNullOrEmpty(directoryPath)) { return false; } bool fileFound = Directory.GetFiles(directoryPath) .Where(file => fileTypesToCheck.Contains(Path.GetExtension(file))) .Any(file => CanWriteFile(file)); return fileFound || Directory.GetDirectories(directoryPath).Any(subDirectory => DirectoryHasWriteableCSharpFile(subDirectory)); } private static bool CanWriteFile(string filePath) { try { using var fs = File.Open(filePath, FileMode.Open, FileAccess.Write); return fs.CanWrite; } catch (System.UnauthorizedAccessException) { return false; } } private static bool CanWriteToDirectory(string directoryPath) { try { using FileStream fs = File.Create( Path.Combine(directoryPath, Path.GetRandomFileName()), 1, FileOptions.DeleteOnClose); return true; } catch (System.UnauthorizedAccessException) { return false; } } } }