public int PreloadProjects(ProjectSetup projectSetup, IEnumerable<string> projectLocations) { int count = 0; if (projectLocations != null) { Stopwatch stopwatch = Stopwatch.StartNew(); foreach (string projectLocation in projectLocations) { try { LoadProject(projectSetup, projectLocation); ++count; } catch (Exception e) { throw new SolutionGeneratorException("Unable to load project [{0}].", e, projectLocation); } } stopwatch.Stop(); ++count; Logger.Trace("Loaded {0} projects in {1} ms", count, stopwatch.ElapsedMilliseconds); } return count; }
public void Execute(ProjectConfiguration configuration, string selectedProject) { DirectoryInfo projectDirectory = new DirectoryInfo(configuration.RootPath); List<FileSystemInfo> projectFiles = projectDirectory .EnumerateFileSystemInfos("*.csproj", SearchOption.AllDirectories) .ToList(); var targetProjects = configuration.ResolveAssemblies(selectedProject); if (_checkOnlyDependencies) { var projectSetup = new ProjectSetup { WhenAssemblyKeyFileNotFound = ProjectSetupBehavior.Valid, WhenContainsFileReferences = ProjectSetupBehavior.Valid, WhenContainsProjectReferences = ProjectSetupBehavior.Warn, WhenReferenceNotResolved = ProjectSetupBehavior.Warn, WhenReferenceResolvedInDifferentLocation = ProjectSetupBehavior.Warn, WhenRequiredProjectLinkNotFound = ProjectSetupBehavior.Valid }; var consoleLogger = ConsoleLogger.Default; var generator = new SolutionGenerator.Toolkit.SolutionGenerator(consoleLogger); var projectLoader = generator.GetProjectLoader(projectSetup, configuration.RootPath); var targetProjectFiles = generator.GetTargetProjectFiles(projectLoader, targetProjects); ReferenceWalker walker = new ReferenceWalker(consoleLogger); var dependencies = walker.WalkReferencesRecursively( projectSetup, projectLoader, targetProjectFiles, new[] {configuration.ThirdPartiesRootPath}, new HashSet<string>()); projectFiles = new List<FileSystemInfo>(); foreach (var dependency in dependencies) { var project = projectLoader.GetProjectById(dependency); projectFiles.Add(new FileInfo(project.ProjectFileLocation)); } } ChangeOutputPath(projectFiles, configuration.RootPath, configuration.BinariesOutputPath, targetProjects); ChangeReferences(projectFiles, configuration.RootPath, configuration.BinariesOutputPath, configuration.TargetFrameworkVersion, configuration.GetSystemRuntimeReferenceMode, configuration.GetSpecificVersionReferenceMode, targetProjects); ChangeProjectSettings(projectFiles); }
private int GenerateSolution(string projectPath, string thirdParties, string[] targetProjects) { var projectSetup = new ProjectSetup { WhenAssemblyKeyFileNotFound = ProjectSetupBehavior.Valid, WhenContainsFileReferences = ProjectSetupBehavior.Valid, WhenContainsProjectReferences = ProjectSetupBehavior.Warn, WhenReferenceNotResolved = ProjectSetupBehavior.Warn, WhenReferenceResolvedInDifferentLocation = ProjectSetupBehavior.Warn, WhenRequiredProjectLinkNotFound = ProjectSetupBehavior.Valid }; SolutionGenerator.Toolkit.SolutionGenerator generator = new SolutionGenerator.Toolkit.SolutionGenerator(ConsoleLogger.Default); return generator.CreateSolution(projectSetup, _solutionOutputPath, projectPath, thirdParties, targetProjects); }
private int CopyThirdParties(string projectPath, string thirdParties, string targetProject) { var projectSetup = new ProjectSetup { WhenAssemblyKeyFileNotFound = ProjectSetupBehavior.Valid, WhenContainsFileReferences = ProjectSetupBehavior.Valid, WhenContainsProjectReferences = ProjectSetupBehavior.Warn, WhenReferenceNotResolved = ProjectSetupBehavior.Warn, WhenReferenceResolvedInDifferentLocation = ProjectSetupBehavior.Warn, WhenRequiredProjectLinkNotFound = ProjectSetupBehavior.Valid }; SolutionGenerator.Toolkit.SolutionGenerator generator = new SolutionGenerator.Toolkit.SolutionGenerator(new ConsoleLogger()); return generator.CopyThirdParties(projectSetup, _outputPath, projectPath, thirdParties, new[] {targetProject}); }
public int CopyThirdParties(ProjectSetup projectSetup, string thirdPartyOutput, string sourceRootFolder, string thirdPartiesFolder, string[] targetProjects) { Logger.Info("Root folder: {0}", sourceRootFolder); Logger.Info("Thirdparties folder: {0}", thirdPartiesFolder); Logger.Info("Output folder: {0}", thirdPartyOutput); Logger.Info("Projects: {0}", string.Join(";", targetProjects)); List<string> projectFiles = FileSearcher.Scan("*.csproj", new[] { sourceRootFolder }); ProjectLoader projectLoader = ProjectLoader.Create(Logger, sourceRootFolder); int loadedCount = 0; Stopwatch loadTimer = Stopwatch.StartNew(); try { Logger.Info(""); Logger.Info("Preloading project files..."); loadedCount = projectLoader.PreloadProjects(projectSetup, projectFiles); } finally { loadTimer.Stop(); Logger.Info("Source load completed in {0}. Loaded project files = {1}{2}", loadTimer.Elapsed, loadedCount, Environment.NewLine); } var targetProjectFiles = new List<string>(); foreach (var assemblyName in targetProjects) { var projectFile = projectLoader.GetProjectByAssemblyName(assemblyName); if (projectFile == null) throw new Exception($"Project by assembly name {assemblyName} not found"); targetProjectFiles.Add(projectFile.ProjectFileLocation); } var thirdPartyFolders = string.IsNullOrWhiteSpace(thirdPartiesFolder) ? new string[] { } : new[] { thirdPartiesFolder }; var walker = new ReferenceWalker(Logger); var dependencies = walker.WalkReferencesRecursively(projectSetup, projectLoader, targetProjectFiles, thirdPartyFolders, new HashSet<string>()); var projectList = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); projectList.UnionWith(targetProjectFiles); HashSet<string> projectDependenciesToCopy = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); foreach (var dependency in dependencies) { var p = projectLoader.GetProjectById(dependency); if (p != null) { projectList.Add(p.ProjectFileLocation); projectDependenciesToCopy.Add(p.ResolvedOutput); } } Stopwatch timer = Stopwatch.StartNew(); try { if (!Directory.Exists(thirdPartyOutput)) Directory.CreateDirectory(thirdPartyOutput); HashSet<string> dependenciesToCopy = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); GeneratedSolution solution = SolutionCreator.CreateSolution( projectSetup, projectLoader, projectList, "GeneratedSolution", thirdPartyFolders, dependenciesToCopy, null); HashSet<string> completeThirdPartyList = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); foreach (string assemblyLocation in dependenciesToCopy) { string folder = Path.GetDirectoryName(assemblyLocation) ?? "."; CollectDependentAssemblies(folder, assemblyLocation, completeThirdPartyList, null); } projectDependenciesToCopy.UnionWith(completeThirdPartyList); if (projectDependenciesToCopy.Count > 0) { ThirdPartyFileContainer container = new ThirdPartyFileContainer { Items = new ThirdPartyFile[projectDependenciesToCopy.Count] }; var coppied = 0; var index = 0; foreach (var assemblyLocation in projectDependenciesToCopy) { container.Items[index++] = new ThirdPartyFile(sourceRootFolder, assemblyLocation); var fileName = Path.GetFileName(assemblyLocation) ?? ""; var targetFileLocation = Path.Combine(thirdPartyOutput, fileName); FileInfo sourceFileInfo = new FileInfo(assemblyLocation); FileInfo targetFileInfo = new FileInfo(targetFileLocation); if (!targetFileInfo.Exists || targetFileInfo.Length != sourceFileInfo.Length || targetFileInfo.LastWriteTimeUtc != sourceFileInfo.LastWriteTimeUtc) { try { sourceFileInfo.CopyTo(targetFileLocation, true); ++coppied; Logger.Info("Copied to target: {0}", targetFileLocation); } catch (Exception e) { Logger.Error("Unable to copy to target: {0}. Error: {1}", targetFileLocation, e.Message); } } } Logger.Info("Coppied {0} files.", coppied); } return solution.IncludedProjects; } finally { timer.Stop(); Logger.Warn("Third parties copied in {0}", timer.Elapsed); } }
public int CreateSolution(ProjectSetup projectSetup, string solutionToGenerate, string sourceRootFolder, string thirdPartiesFolder, string[] targetProjects) { var projectLoader = GetProjectLoader(projectSetup, sourceRootFolder); var targetProjectFiles = GetTargetProjectFiles(projectLoader, targetProjects); var thirdPartyFolders = string.IsNullOrWhiteSpace(thirdPartiesFolder) ? new string[] { } : new[] { thirdPartiesFolder }; ReferenceWalker walker = new ReferenceWalker(Logger); var dependencies = walker.WalkReferencesRecursively(projectSetup, projectLoader, targetProjectFiles, thirdPartyFolders, new HashSet<string>()); var projectList = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); projectList.UnionWith(targetProjectFiles); foreach (var dependency in dependencies) { var p = projectLoader.GetProjectById(dependency); if (p != null) { projectList.Add(p.ProjectFileLocation); } } Logger.Info("Files configured for solution generation:"); foreach (string item in projectList) { Logger.Info(" {0}", item); } Stopwatch timer = Stopwatch.StartNew(); try { if (!Path.IsPathRooted(solutionToGenerate)) { solutionToGenerate = Path.GetFullPath(Path.Combine(sourceRootFolder, solutionToGenerate)); } HashSet<string> usedThirdParties = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); GeneratedSolution solution = SolutionCreator.CreateSolution( projectSetup, projectLoader, projectList, solutionToGenerate, thirdPartyFolders, usedThirdParties, null); string solutionDirectory = Path.GetDirectoryName(solutionToGenerate) ?? "."; if (!Directory.Exists(solutionDirectory)) Directory.CreateDirectory(solutionDirectory); Logger.Info("Writing solution with {0} project to file {1}", solution.IncludedProjects, solutionToGenerate); File.WriteAllText(solutionToGenerate, solution.Content, Encoding.UTF8); HashSet<string> completeThirdPartyList = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); foreach (string assemblyLocation in usedThirdParties) { string folder = Path.GetDirectoryName(assemblyLocation) ?? "."; CollectDependentAssemblies(folder, assemblyLocation, completeThirdPartyList, null); } List<string> usedThirdPartyList = new List<string>(completeThirdPartyList); usedThirdPartyList.Sort(); if (usedThirdPartyList.Count > 0) { Logger.Info("Third parties used in solution:"); ThirdPartyFileContainer container = new ThirdPartyFileContainer { Items = new ThirdPartyFile[usedThirdPartyList.Count] }; for (int i = 0; i < usedThirdPartyList.Count; ++i) { string assemblyLocation = usedThirdPartyList[i]; container.Items[i] = new ThirdPartyFile(sourceRootFolder, assemblyLocation); } //string thirdPartyFileContent = container.XmlSerialize(false, "http://schemas.microsoft.com/developer/msbuild/2003"); //File.WriteAllText(solutionToGenerate + ".thirdparties", thirdPartyFileContent, Encoding.UTF8); } return solution.IncludedProjects; } finally { timer.Stop(); Logger.Info("Solution generated in {0}", timer.Elapsed); } }
public ProjectLoader GetProjectLoader(ProjectSetup projectSetup, string sourceRootFolder) { List<string> projectFiles = FileSearcher.Scan("*.csproj", new[] { sourceRootFolder }); ProjectLoader projectLoader = ProjectLoader.Create(Logger, sourceRootFolder); int loadedCount = 0; Stopwatch loadTimer = Stopwatch.StartNew(); try { Logger.Info(""); Logger.Info("Preloading project files..."); loadedCount = projectLoader.PreloadProjects(projectSetup, projectFiles); } finally { loadTimer.Stop(); Logger.Info("Source load completed in {0}. Loaded project files = {1}{2}", loadTimer.Elapsed, loadedCount, Environment.NewLine); } return projectLoader; }
public GeneratedSolution CreateSolution(ProjectSetup projectSetup, ProjectLoader projectLoader, IEnumerable<string> projectLocations, string solutionFileLocation, string[] thirdPartyFolders, HashSet<string> usedThirdParties, string customAppend) { var solutionProjectList = ReferenceWalker.WalkReferencesRecursively(projectSetup, projectLoader, projectLocations, thirdPartyFolders, usedThirdParties); var solutionFile = new StringBuilder(); solutionFile.AppendLine(); solutionFile.AppendLine("Microsoft Visual Studio Solution File, Format Version 12.00"); solutionFile.AppendLine("# Visual Studio 14"); solutionFile.AppendLine("VisualStudioVersion = 14.0.24720.0"); solutionFile.AppendLine("MinimumVisualStudioVersion = 10.0.40219.1"); if (!string.IsNullOrWhiteSpace(customAppend)) { solutionFile.AppendLine(customAppend); } var testProjects = new List<Guid>(); var startProjects = new List<Guid>(); var otherProjects = new List<Guid>(); foreach (var projectId in solutionProjectList) { var project = projectLoader.GetProjectById(projectId); var isTestProject = project.AssemblyName.ToLowerInvariant().Contains("test"); var isStartProject = project.IsLauncher; if (isTestProject) testProjects.Add(projectId); else if (isStartProject) startProjects.Add(projectId); else otherProjects.Add(projectId); // FullProjectPath can be changed to relative, but then root folder is needed var projectFileLocation = MakeRelativePath(solutionFileLocation, project.ProjectFileLocation); solutionFile.AppendFormat("Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\"", "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}", Path.GetFileNameWithoutExtension(projectFileLocation), projectFileLocation, project.ProjectId.ToString("B").ToUpperInvariant()); solutionFile.AppendLine(); #region DEPENDENCIES var dependencies = ReferenceWalker.GetProjectDependencies(projectSetup, projectLoader, project, thirdPartyFolders, usedThirdParties); if (dependencies != null && dependencies.Count > 0) { var projectSectionAdded = false; foreach (var dependentItemId in dependencies) { // do not add dependency to itself if (dependentItemId == project.ProjectId) continue; if (!projectSectionAdded) { solutionFile.AppendLine("\tProjectSection(ProjectDependencies) = postProject"); projectSectionAdded = true; } solutionFile.AppendFormat("\t\t{0} = {0}", dependentItemId.ToString("B").ToUpperInvariant()); solutionFile.AppendLine(); } if (projectSectionAdded) solutionFile.AppendLine("\tEndProjectSection"); } #endregion solutionFile.AppendLine("EndProject"); } var otherProjectId = Guid.NewGuid(); var testProjectId = Guid.NewGuid(); if (startProjects.Count > 0) { solutionFile.AppendLine($"Project(\"{{2150E333-8FDC-42A3-9474-1A3956D46DE8}}\") = \"Projects\", \"Projects\", \"{otherProjectId.ToString("B").ToUpperInvariant()}\""); solutionFile.AppendLine("EndProject"); } if (testProjects.Count > 0) { solutionFile.AppendLine($"Project(\"{{2150E333-8FDC-42A3-9474-1A3956D46DE8}}\") = \"Tests\", \"Tests\", \"{testProjectId.ToString("B").ToUpperInvariant()}\""); solutionFile.AppendLine("EndProject"); } solutionFile.AppendLine("Global"); #region GLOBAL SECTION solutionFile.AppendLine("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution"); solutionFile.AppendLine("\t\tDebug|Any CPU = Debug|Any CPU"); solutionFile.AppendLine("\t\tDebug|Mixed Platforms = Debug|Mixed Platforms"); solutionFile.AppendLine("\t\tDebug|X64 = Debug|X64"); solutionFile.AppendLine("\t\tDebug|x86 = Debug|x86"); solutionFile.AppendLine("\t\tRelease|Any CPU = Release|Any CPU"); solutionFile.AppendLine("\t\tRelease|Mixed Platforms = Release|Mixed Platforms"); solutionFile.AppendLine("\t\tRelease|X64 = Release|X64"); solutionFile.AppendLine("\t\tRelease|x86 = Release|x86"); solutionFile.AppendLine("\tEndGlobalSection"); #endregion #region GLOBAL SECTION solutionFile.AppendLine("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution"); foreach (Guid projectId in solutionProjectList) { string idString = projectId.ToString("B").ToUpperInvariant(); solutionFile.AppendFormat("\t\t{0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU", idString).AppendLine(); solutionFile.AppendFormat("\t\t{0}.Debug|Any CPU.Build.0 = Debug|Any CPU", idString).AppendLine(); solutionFile.AppendFormat("\t\t{0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU", idString).AppendLine(); solutionFile.AppendFormat("\t\t{0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU", idString).AppendLine(); solutionFile.AppendFormat("\t\t{0}.Debug|X64.ActiveCfg = Debug|Any CPU", idString).AppendLine(); solutionFile.AppendFormat("\t\t{0}.Debug|X64.Build.0 = Debug|Any CPU", idString).AppendLine(); solutionFile.AppendFormat("\t\t{0}.Debug|x86.ActiveCfg = Debug|Any CPU", idString).AppendLine(); solutionFile.AppendFormat("\t\t{0}.Debug|x86.Build.0 = Debug|Any CPU", idString).AppendLine(); solutionFile.AppendFormat("\t\t{0}.Release|Any CPU.ActiveCfg = Release|Any CPU", idString).AppendLine(); solutionFile.AppendFormat("\t\t{0}.Release|Any CPU.Build.0 = Release|Any CPU", idString).AppendLine(); solutionFile.AppendFormat("\t\t{0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU", idString).AppendLine(); solutionFile.AppendFormat("\t\t{0}.Release|Mixed Platforms.Build.0 = Release|Any CPU", idString).AppendLine(); solutionFile.AppendFormat("\t\t{0}.Release|X64.ActiveCfg = Release|Any CPU", idString).AppendLine(); solutionFile.AppendFormat("\t\t{0}.Release|X64.Build.0 = Release|Any CPU", idString).AppendLine(); solutionFile.AppendFormat("\t\t{0}.Release|x86.ActiveCfg = Release|Any CPU", idString).AppendLine(); solutionFile.AppendFormat("\t\t{0}.Release|x86.Build.0 = Release|Any CPU", idString).AppendLine(); } solutionFile.AppendLine("\tEndGlobalSection"); solutionFile.AppendLine("\tGlobalSection(SolutionProperties) = preSolution"); solutionFile.AppendFormat("\t\tHideSolutionNode = FALSE").AppendLine(); solutionFile.AppendLine("\tEndGlobalSection"); if (testProjects.Count > 0 || startProjects.Count > 0) // put to folder only we have one of these.. { solutionFile.AppendLine("\tGlobalSection(NestedProjects) = preSolution"); foreach (var projectId in otherProjects) { solutionFile.AppendFormat("\t\t{0} = {1}", projectId.ToString("B").ToUpperInvariant(), otherProjectId.ToString("B").ToUpperInvariant()); solutionFile.AppendLine(); } foreach (var projectId in testProjects) { solutionFile.AppendFormat("\t\t{0} = {1}", projectId.ToString("B").ToUpperInvariant(), testProjectId.ToString("B").ToUpperInvariant()); solutionFile.AppendLine(); } solutionFile.AppendLine("\tEndGlobalSection"); } #endregion solutionFile.AppendLine("EndGlobal"); Logger.Trace("Created solution file with {0} projects", solutionProjectList.Count); var generatedSolution = new GeneratedSolution { Content = solutionFile.ToString(), IncludedProjects = solutionProjectList.Count }; return generatedSolution; }
public List<Guid> WalkReferencesRecursively(ProjectSetup projectSetup, ProjectLoader projectLoader, IEnumerable<string> projectLocations, string[] thirdPartyFolders, HashSet<string> usedThirdParties) { List<Guid> completeReferences = new List<Guid>(); foreach (string projectLocation in projectLocations) { VSProject project = projectLoader.LoadProject(projectSetup, projectLocation); List<Guid> dependentReferences = WalkReferencesRecursively(projectSetup, projectLoader, project, thirdPartyFolders, usedThirdParties); dependentReferences.Add(project.ProjectId); foreach (Guid dependentReference in dependentReferences) { if (!completeReferences.Contains(dependentReference)) completeReferences.Add(dependentReference); } } return completeReferences; }
private void ResolveProject(ProjectSetup projectSetup, ProjectLoader projectLoader, VSProject project, VSProjectReference reference, List<VSProject> referencedProjects) { VSProject vsProject; if (reference.IsProjectReference) { // resolve by ID vsProject = projectLoader.GetProjectById(reference.ProjectReferenceId); } else if (reference.IsSilverlightReference) { vsProject = projectLoader.GetProjectById(reference.ProjectReferenceId); } else { // resolve by output path vsProject = projectLoader.GetProjectByOutput(reference.ResolvedHintPath); } if (vsProject != null) { referencedProjects.Add(vsProject); } else { // fall back scenario, check assembly name in current project output path string outputDirectory = Path.GetDirectoryName(project.ResolvedOutput) ?? "."; string currentFolderAssembly = Path.Combine(outputDirectory, reference.ResolvedInclude) + ".dll"; vsProject = projectLoader.GetProjectByOutput(currentFolderAssembly); if (vsProject== null) { currentFolderAssembly = Path.Combine(outputDirectory, reference.ResolvedInclude) + ".exe"; vsProject = projectLoader.GetProjectByOutput(currentFolderAssembly); } if (vsProject == null) { if (projectSetup.WhenReferenceNotResolved == ProjectSetupBehavior.Fail) { throw new SolutionGeneratorException( "Reference {0} was not resolved. {3}Project {1}. {3}Expected location = {2}{3}", reference.ResolvedInclude, project.ProjectFileLocation, reference.ResolvedHintPath, Environment.NewLine); } if (projectSetup.WhenReferenceNotResolved == ProjectSetupBehavior.Warn) { Logger.Warn( "Reference {0} was not resolved. {3}Project {1}. {3}Expected location = {2}{3}", reference.ResolvedInclude, project.ProjectFileLocation, reference.ResolvedHintPath, Environment.NewLine); } } else { if (projectSetup.WhenReferenceResolvedInDifferentLocation == ProjectSetupBehavior.Fail) { throw new SolutionGeneratorException( "Reference {0} was not resolved. {4}Project {1}. {4}Expected location = {2}{4}However it was found in project output folder {3}.{4}", reference.ResolvedInclude, project.ProjectFileLocation, reference.ResolvedHintPath, outputDirectory, Environment.NewLine); } if (projectSetup.WhenReferenceResolvedInDifferentLocation == ProjectSetupBehavior.Warn) { Logger.Warn( "Reference {0} was not resolved. {4}Project {1}. {4}Expected location = {2}{4}However it was found in project output folder {3}.{4}", reference.ResolvedInclude, project.ProjectFileLocation, reference.ResolvedHintPath, outputDirectory, Environment.NewLine); } } } }
private List<Guid> GetCurrentProjectReferences(ProjectSetup projectSetup, ProjectLoader projectLoader, VSProject project, HashSet<string> thirdPartyFileMap, HashSet<string> usedThirdParties, List<Guid> checkedProjects) { ReferenceCacheItem cacheItem; if (!ProjectReferenceCache.TryGetValue(project.ProjectId, out cacheItem)) { if (checkedProjects.Contains(project.ProjectId)) { StringBuilder builder = new StringBuilder(); for (int i = checkedProjects.Count - 1; i >= 0; i--) { Guid checkedProject = checkedProjects[i]; builder.Insert(0, projectLoader.GetProjectById(checkedProject).ProjectFileLocation + Environment.NewLine); if (checkedProject == project.ProjectId) break; } builder.AppendLine(project.ProjectFileLocation); throw new SolutionGeneratorException("Circular reference detected! {1}Projects: {1}{0}", builder, Environment.NewLine); } checkedProjects.Add(project.ProjectId); cacheItem = new ReferenceCacheItem { References = new List<Guid>(), UsedThirdParties = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase) }; if (project.References != null) { List<VSProject> referencedProjects = new List<VSProject>(); foreach (VSProjectReference reference in project.References) { if (thirdPartyFileMap.Contains(reference.ResolvedHintPath)) { cacheItem.UsedThirdParties.Add(reference.ResolvedHintPath); continue; } if (SystemReferenceFileMap.Contains(reference.ResolvedInclude)) { continue; } if (reference.ResolvedInclude.StartsWith("Microsoft.", StringComparison.InvariantCultureIgnoreCase)) { continue; } ResolveProject(projectSetup, projectLoader, project, reference, referencedProjects); } foreach (VSProject referencedProject in referencedProjects) { if (!cacheItem.References.Contains(referencedProject.ProjectId)) cacheItem.References.Add(referencedProject.ProjectId); } } //cacheItem.UsedThirdParties.UnionWith(usedThirdParties); ProjectReferenceCache.Add(project.ProjectId, cacheItem); } usedThirdParties.UnionWith(cacheItem.UsedThirdParties); return cacheItem.References; }
public List<Guid> GetProjectDependencies(ProjectSetup projectSetup, ProjectLoader projectLoader, VSProject project, string[] thirdPartyFolders, HashSet<string> usedThirdParties) { HashSet<string> thirdPartyFileMap; if (thirdPartyFolders != null && thirdPartyFolders.Length > 0) { string key = string.Join(":", thirdPartyFolders); if (!ThirdPartyFileCache.TryGetValue(key, out thirdPartyFileMap)) { thirdPartyFileMap = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase); List<string> thirdPartyFiles = FileSearcher.Scan("*.dll", thirdPartyFolders); thirdPartyFileMap.UnionWith(thirdPartyFiles); ThirdPartyFileCache.Add(key, thirdPartyFileMap); } } else { thirdPartyFileMap = new HashSet<string>(); } List<Guid> checkedProjects = new List<Guid>(); var completeReferences = GetCurrentProjectReferences(projectSetup, projectLoader, project, thirdPartyFileMap, usedThirdParties, checkedProjects); return completeReferences; }
/// <summary> /// Loads the project. /// </summary> /// <param name="projectSetup">The project setup.</param> /// <param name="projectLocation">The project location.</param> /// <param name="projectLocations">The project locations.</param> /// <returns></returns> public VSProject LoadProject(ProjectSetup projectSetup, string projectLocation) { if (loadedProjects.ContainsKey(projectLocation)) return loadedProjects[projectLocation]; // Load project: IProjectReader reader = ProjectReaderFactory.CreateProjectReader(projectSetup.ProjectReaderType, projectLocation); VSProject project = reader.LoadProject(); // Check for main properties: if (project.ProjectId == Guid.Empty) throw new ApplicationException(string.Format("Property ProjectGuid is empty.")); if (String.IsNullOrEmpty(project.RootNamespace)) throw new ApplicationException(string.Format("Property RootNamespace is empty.")); // // Process references // string projectFileFolder = Path.GetDirectoryName(projectLocation) ?? "."; if (projectSetup.WhenAssemblyKeyFileNotFound != ProjectSetupBehavior.Valid) { string resolvedPath = ResolveFilePath(project.AssemblyOriginatorKeyFile, projectFileFolder); if (string.IsNullOrEmpty(resolvedPath)) { if (projectSetup.WhenRequiredProjectLinkNotFound == ProjectSetupBehavior.Fail) { throw new SolutionGeneratorException("Project {0} does not have key file {1}!", projectLocation, projectSetup.AssemblyKeyFile); } if (projectSetup.WhenRequiredProjectLinkNotFound == ProjectSetupBehavior.Warn) { Logger.Warn("Project {0} does not have key file {1}!", projectLocation, projectSetup.AssemblyKeyFile); } } else if (!string.Equals(resolvedPath, projectSetup.AssemblyKeyFile, StringComparison.InvariantCultureIgnoreCase)) { if (projectSetup.WhenRequiredProjectLinkNotFound == ProjectSetupBehavior.Fail) { throw new SolutionGeneratorException("Project {0} has key file {1} but in wrong location {2}!", projectLocation, projectSetup.AssemblyKeyFile, resolvedPath); } if (projectSetup.WhenRequiredProjectLinkNotFound == ProjectSetupBehavior.Warn) { Logger.Warn("Project {0} has key file {1} but in wrong location {2}!", projectLocation, projectSetup.AssemblyKeyFile, resolvedPath); } } } IList<VSProjectReference> fileReferences = reader.FileReferences; if (fileReferences != null && fileReferences.Count > 0) { if (projectSetup.WhenContainsFileReferences == ProjectSetupBehavior.Fail) { throw new SolutionGeneratorException("Project {0} contains {1} file references!", projectLocation, fileReferences.Count); } if (projectSetup.WhenContainsFileReferences == ProjectSetupBehavior.Warn) { Logger.Warn("Project {0} contains {1} file references!", projectLocation, fileReferences.Count); } } IList<VSProjectReference> projectReferences = reader.ProjectReferences; if (projectReferences != null && projectReferences.Count > 0) { if (projectSetup.WhenContainsProjectReferences == ProjectSetupBehavior.Fail) { throw new SolutionGeneratorException("Project {0} contains {1} project references!", projectLocation, projectReferences.Count); } if (projectSetup.WhenContainsProjectReferences == ProjectSetupBehavior.Warn) { Logger.Warn("Project {0} contains {1} project references!", projectLocation, projectReferences.Count); } } IList<VSProjectReference> silverlightProjectReferences = reader.SilverlightProjectReferences; if (silverlightProjectReferences != null && silverlightProjectReferences.Count > 0) { // if (projectSetup.WhenContainsProjectReferences == ProjectSetupBehavior.Fail) // { // throw new SolutionGeneratorException("Project {0} contains {1} project references!", projectLocation, silverlightProjectReferences.Count); // } if (projectSetup.WhenContainsProjectReferences == ProjectSetupBehavior.Warn) { Logger.Warn("Project {0} contains silverlight {1} project references!", projectLocation, silverlightProjectReferences.Count); } } if (projectSetup.RequiredProjectFiles != null && projectSetup.RequiredProjectFiles.Length > 0 && projectSetup.WhenRequiredProjectLinkNotFound != ProjectSetupBehavior.Valid) { IList<VSIncludedFile> includedFiles = reader.IncludedFiles; IDictionary<string, VSIncludedFile> fileMap = new Dictionary<string, VSIncludedFile>(StringComparer.InvariantCultureIgnoreCase); foreach (VSIncludedFile file in includedFiles) { if (!string.IsNullOrEmpty(file.Include)) { string fileName = Path.GetFileName(file.Include); if (!string.IsNullOrEmpty(fileName)) fileMap[fileName] = file; } } foreach (string projectLink in projectSetup.RequiredProjectFiles) { string fileName = Path.GetFileName(projectLink); if (string.IsNullOrEmpty(fileName)) continue; string filePathToCheck = null; VSIncludedFile includedFile; if (fileMap.TryGetValue(fileName, out includedFile)) { filePathToCheck = ResolveFilePath(includedFile.Include, projectFileFolder); } if (string.IsNullOrEmpty(filePathToCheck)) { if (projectSetup.WhenRequiredProjectLinkNotFound == ProjectSetupBehavior.Fail) { throw new SolutionGeneratorException("Project {0} does not include required file {1}!", projectLocation, projectLink); } if (projectSetup.WhenRequiredProjectLinkNotFound == ProjectSetupBehavior.Warn) { Logger.Warn("Project {0} does not include required file {1}!", projectLocation, projectLink); } } else if (!string.Equals(projectLink, filePathToCheck, StringComparison.InvariantCultureIgnoreCase)) { if (projectSetup.WhenRequiredProjectLinkNotFound == ProjectSetupBehavior.Fail) { throw new SolutionGeneratorException("Project {0} includes required file {1} but it in wrong location {2}!", projectLocation, projectLink, filePathToCheck); } if (projectSetup.WhenRequiredProjectLinkNotFound == ProjectSetupBehavior.Warn) { Logger.Warn("Project {0} includes required file {1} but it in wrong location {2}!", projectLocation, projectLink, filePathToCheck); } } } } foreach (VSProjectReference reference in project.References) { if (!reference.IsSilverlightReference) { reference.ResolvedInclude = ResolveInclude(reference.Include); reference.ResolvedHintPath = ResolveHintPath(reference.HintPath, reference.ResolvedInclude, projectFileFolder, reader.OutputFolder); } else { string pathByReference = ResolveSilverlightProjectPathByReference(projectFileFolder, reference.HintPath); VSProject vsProject = LoadProject(projectSetup, pathByReference); reference.ResolvedHintPath = vsProject.ResolvedOutput; reference.Include = vsProject.AssemblyName; reference.ResolvedInclude = vsProject.ResolvedOutput; } } loadedProjects.Add(projectLocation, project); if (loadedProjectsById.ContainsKey(project.ProjectId)) { throw new SolutionGeneratorException("Duplicated project ID = {0}, {3}location = {1}, {3}location = {2}", project.ProjectId, project.ProjectFileLocation, loadedProjectsById[project.ProjectId], Environment.NewLine); } loadedProjectsById.Add(project.ProjectId, projectLocation); if (loadedProjectsByOutput.ContainsKey(project.ResolvedOutput)) { throw new SolutionGeneratorException("Duplicated project output path = {0}, {3}location = {1}, {3}location = {2}", project.ResolvedOutput, project.ProjectFileLocation, loadedProjectsByOutput[project.ResolvedOutput], Environment.NewLine); } loadedProjectsByOutput.Add(project.ResolvedOutput, projectLocation); if (loadedProjectsByAssemblyName.ContainsKey(project.AssemblyName)) { throw new SolutionGeneratorException("Duplicated project assembly name = {0}, {3}location = {1}, {3}location = {2}", project.AssemblyName, project.ProjectFileLocation, loadedProjectsByAssemblyName[project.AssemblyName], Environment.NewLine); } loadedProjectsByAssemblyName.Add(project.AssemblyName, projectLocation); return project; }