/// <summary> /// Find all the build products created by compiling the given project file /// </summary> /// <param name="ProjectFiles">Initial project file to read. All referenced projects will also be read.</param> /// <param name="InitialProperties">Mapping of property name to value</param> /// <param name="OutBuildProducts">Receives a set of build products on success</param> /// <param name="OutReferences">Receives a set of non-private references on success</param> static void FindBuildProductsAndReferences(HashSet <FileReference> ProjectFiles, Dictionary <string, string> InitialProperties, out HashSet <FileReference> OutBuildProducts, out HashSet <FileReference> OutReferences) { // Find all the build products and references OutBuildProducts = new HashSet <FileReference>(); OutReferences = new HashSet <FileReference>(); // Read all the project information into a dictionary Dictionary <FileReference, CsProjectInfo> FileToProjectInfo = new Dictionary <FileReference, CsProjectInfo>(); foreach (FileReference ProjectFile in ProjectFiles) { // Read all the projects ReadProjectsRecursively(ProjectFile, InitialProperties, FileToProjectInfo); // Find all the outputs for each project foreach (KeyValuePair <FileReference, CsProjectInfo> Pair in FileToProjectInfo) { CsProjectInfo ProjectInfo = Pair.Value; // Add all the build projects from this project DirectoryReference OutputDir = ProjectInfo.GetOutputDir(Pair.Key.Directory); ProjectInfo.FindBuildProducts(OutputDir, OutBuildProducts, FileToProjectInfo); // Add any files which are only referenced foreach (KeyValuePair <FileReference, bool> Reference in ProjectInfo.References) { if (!Reference.Value) { CsProjectInfo.AddReferencedAssemblyAndSupportFiles(Reference.Key, OutReferences); } } } } OutBuildProducts.RemoveWhere(x => !FileReference.Exists(x)); OutReferences.RemoveWhere(x => !FileReference.Exists(x)); }
/// <summary> /// Find all the build products created by compiling the given project file /// </summary> /// <param name="ProjectFiles">Initial project file to read. All referenced projects will also be read.</param> /// <param name="InitialProperties">Mapping of property name to value</param> /// <param name="OutBuildProducts">Receives a set of build products on success</param> /// <param name="OutReferences">Receives a set of non-private references on success</param> /// <returns>True if the build products were found, false otherwise.</returns> static bool FindBuildProducts(HashSet <FileReference> ProjectFiles, Dictionary <string, string> InitialProperties, out HashSet <FileReference> OutBuildProducts, out HashSet <FileReference> OutReferences) { // Read all the project information into a dictionary Dictionary <FileReference, CsProjectInfo> FileToProjectInfo = new Dictionary <FileReference, CsProjectInfo>(); foreach (FileReference ProjectFile in ProjectFiles) { if (!ReadProjectsRecursively(ProjectFile, InitialProperties, FileToProjectInfo)) { OutBuildProducts = null; OutReferences = null; return(false); } } // Find all the build products and references HashSet <FileReference> BuildProducts = new HashSet <FileReference>(); HashSet <FileReference> References = new HashSet <FileReference>(); foreach (KeyValuePair <FileReference, CsProjectInfo> Pair in FileToProjectInfo) { CsProjectInfo ProjectInfo = Pair.Value; // Add the standard build products DirectoryReference OutputDir = ProjectInfo.GetOutputDir(Pair.Key.Directory); ProjectInfo.AddBuildProducts(OutputDir, BuildProducts); // Add the referenced assemblies foreach (KeyValuePair <FileReference, bool> Reference in ProjectInfo.References) { FileReference OtherAssembly = Reference.Key; if (Reference.Value) { // Add reference from the output dir FileReference OutputFile = FileReference.Combine(OutputDir, OtherAssembly.GetFileName()); BuildProducts.Add(OutputFile); FileReference OutputSymbolFile = OutputFile.ChangeExtension(".pdb"); if (FileReference.Exists(OutputSymbolFile)) { BuildProducts.Add(OutputSymbolFile); } } else { // Add reference directly References.Add(OtherAssembly); FileReference SymbolFile = OtherAssembly.ChangeExtension(".pdb"); if (FileReference.Exists(SymbolFile)) { References.Add(SymbolFile); } } } // Add build products from all the referenced projects. MSBuild only copy the directly referenced build products, not recursive references or other assemblies. foreach (CsProjectInfo OtherProjectInfo in ProjectInfo.ProjectReferences.Where(x => x.Value).Select(x => FileToProjectInfo[x.Key])) { OtherProjectInfo.AddBuildProducts(OutputDir, BuildProducts); } } // Update the output set OutBuildProducts = BuildProducts; OutReferences = References; return(true); }