private void FindMissingFiles(Project proj) { Debug.WriteLine($"Project {proj.Name}"); IDictionary <string, string> dict = new Dictionary <string, string>(); dict.Add("Configuration", proj.ConfigurationManager.ActiveConfiguration.ConfigurationName); using (var projectCollection = new ProjectCollection(dict)) { var buildProject = projectCollection.LoadProject(proj.FullName); var physicalFiles = new HashSet <string>(StringComparer.OrdinalIgnoreCase); var logicalFiles = new HashSet <string>(StringComparer.OrdinalIgnoreCase); var physicalFileProjectMap = new Dictionary <string, string>(); NavigateProjectItems(proj.ProjectItems, buildProject, physicalFiles, logicalFiles, new HashSet <string>(), physicalFileProjectMap); if (Options.NotIncludedFiles) { var errorCategory = Options.MessageLevel; physicalFiles.ExceptWith(logicalFiles); foreach (var file in physicalFiles) { Debug.WriteLine($"Physical file: {file}"); if (_filters.Any(f => f.IsMatch(file)) || (CheckIgnored(file))) { Debug.WriteLine("\tIgnored by filter"); continue; } IVsHierarchy hierarchyItem; string physicalFileProject = physicalFileProjectMap[file]; _solution.GetProjectOfUniqueName(physicalFileProject, out hierarchyItem); var newError = new MissingErrorTask() { ErrorCategory = errorCategory, Category = TaskCategory.BuildCompile, Text = "File on disk is not included in project", Code = Constants.FileOnDiskNotInProject, Document = file, HierarchyItem = hierarchyItem, ProjectPath = physicalFileProject, }; newError.Navigate += SelectParentProjectInSolution; Debug.WriteLine("\t\t** Missing"); _errorListProvider.Tasks.Add(newError); } } } }
protected override bool VisibleExpression(MissingErrorTask task) { return(task != null && task.Code == Constants.FileOnDiskNotInProject); }
private void NavigateProjectItems(ProjectItems projectItems, Microsoft.Build.Evaluation.Project buildProject, ISet <string> projectPhysicalFiles, ISet <string> projectLogicalFiles, ISet <string> processedPhysicalDirectories, IDictionary <string, string> physicalFileProjectMap) { if (projectItems == null) { return; } var projectDirectory = buildProject.DirectoryPath + Path.DirectorySeparatorChar; var projectFilename = buildProject.FullPath; var errorCategory = Options.MessageLevel; foreach (ProjectItem item in projectItems) { NavigateProjectItems(item.ProjectItems, buildProject, projectPhysicalFiles, projectLogicalFiles, processedPhysicalDirectories, physicalFileProjectMap); if (item.Kind != "{6BB5F8EE-4483-11D3-8BCF-00C04F8EC28C}") // VSConstants.GUID_ItemType_PhysicalFile { continue; } string itemName = item.Name; Debug.WriteLine("\t" + itemName + item.Kind); for (short i = 0; i < item.FileCount; i++) { var filePath = item.FileNames[i]; // Skip if this is a linked file if (!filePath.StartsWith(projectDirectory, StringComparison.InvariantCultureIgnoreCase)) { continue; } projectLogicalFiles.Add(filePath); if (!File.Exists(filePath)) { var relativePath = filePath.Replace(buildProject.DirectoryPath + @"\", ""); var found = buildProject.Items.Any(x => x.EvaluatedInclude == relativePath); if (!found) { Debug.WriteLine("\t\tFile excluded due to Condition evaluation"); return; } IVsHierarchy hierarchyItem; _solution.GetProjectOfUniqueName(projectFilename, out hierarchyItem); var newError = new MissingErrorTask() { ErrorCategory = errorCategory, Category = TaskCategory.BuildCompile, Text = "File referenced in project does not exist", Code = "MI0001", Document = filePath, HierarchyItem = hierarchyItem, ProjectPath = projectFilename }; newError.Navigate += NewErrorOnNavigate; Debug.WriteLine("\t\t** Missing"); _errorListProvider.Tasks.Add(newError); } string directoryName = Path.GetDirectoryName(filePath); // If we haven't seen this directory before, find the files inside it if (processedPhysicalDirectories.Add(directoryName)) { AddGitIgnoreFromDirectory(directoryName); var physicalFiles = new DirectoryInfo(directoryName).GetFiles() .Where( f => f.Attributes != FileAttributes.Hidden && f.Attributes != FileAttributes.System) .Where(f => !f.Name.EndsWith(".user", StringComparison.InvariantCultureIgnoreCase) && !f.Name.EndsWith("proj", StringComparison.InvariantCultureIgnoreCase)) .Select(f => f.FullName) .ToList(); foreach (var physicalFile in physicalFiles) { projectPhysicalFiles.Add(physicalFile); physicalFileProjectMap.Add(physicalFile, projectFilename); } } } } }
protected abstract bool VisibleExpression(MissingErrorTask task);
private void FindMissingFiles() { // unhook event handlers to reduce risk of memory leaks foreach (MissingErrorTask task in _errorListProvider.Tasks) { task.Navigate -= SelectParentProjectInSolution; task.Navigate -= NewErrorOnNavigate; } _errorListProvider.Tasks.Clear(); var projects = _dte.AllProjects(); var solutionDirectory = Path.GetDirectoryName(_dte.Solution.FullName); var gitIgnoreFile = Path.Combine(solutionDirectory, ".gitignore"); IgnoreList gitignores = null; if (Options.UseGitIgnore && File.Exists(gitIgnoreFile)) { gitignores = new IgnoreList(gitIgnoreFile); } var filters = new List <Regex>(); if (!string.IsNullOrEmpty(Options.IgnorePhysicalFiles)) { filters.AddRange(Options.IgnorePhysicalFiles.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).Select(p => FindFilesPatternToRegex.Convert(p.Trim()))); } foreach (Project proj in projects) { Debug.WriteLine(proj.Name); IDictionary <string, string> dict = new Dictionary <string, string>(); dict.Add("Configuration", proj.ConfigurationManager.ActiveConfiguration.ConfigurationName); using (var projectCollection = new ProjectCollection(dict)) { var buildProject = projectCollection.LoadProject(proj.FullName); var physicalFiles = new HashSet <string>(StringComparer.OrdinalIgnoreCase); var logicalFiles = new HashSet <string>(StringComparer.OrdinalIgnoreCase); var physicalFileProjectMap = new Dictionary <string, string>(); NavigateProjectItems(proj.ProjectItems, buildProject, physicalFiles, logicalFiles, new HashSet <string>(), physicalFileProjectMap); if (Options.NotIncludedFiles) { var errorCategory = Options.MessageLevel; physicalFiles.ExceptWith(logicalFiles); foreach (var file in physicalFiles) { Debug.WriteLine($"Physical file: {file}"); if (filters.Any(f => f.IsMatch(file)) || (gitignores != null && gitignores.IsIgnored(file, false))) { Debug.WriteLine("\tIgnored by filter"); continue; } IVsHierarchy hierarchyItem; string physicalFileProject = physicalFileProjectMap[file]; _solution.GetProjectOfUniqueName(physicalFileProject, out hierarchyItem); var newError = new MissingErrorTask() { ErrorCategory = errorCategory, Category = TaskCategory.BuildCompile, Text = "File on disk is not included in project", Code = Constants.FileOnDiskNotInProject, Document = file, HierarchyItem = hierarchyItem, ProjectPath = physicalFileProject, }; newError.Navigate += SelectParentProjectInSolution; Debug.WriteLine("\t\t** Missing"); _errorListProvider.Tasks.Add(newError); } } } } if (_errorListProvider.Tasks.Count > 0) { _errorListProvider.Show(); if (Options.FailBuildOnError && Options.Timing == RunWhen.BeforeBuild) { _dte.ExecuteCommand("Build.Cancel"); } } }