1 // Copyright (c) Microsoft. All rights reserved. 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information. 3 4 using System; 5 using System.Reflection; 6 using System.Collections; 7 using Microsoft.Build.Shared; 8 using System.Diagnostics; 9 10 namespace Microsoft.Build.Tasks 11 { 12 /// <summary> 13 /// Resolve searchpath type {CandidateAssemblyFiles} 14 /// </summary> 15 internal class CandidateAssemblyFilesResolver : Resolver 16 { 17 /// <summary> 18 /// The candidate assembly files. 19 /// </summary> 20 private string[] _candidateAssemblyFiles; 21 22 /// <summary> 23 /// Construct. 24 /// </summary> 25 /// <param name="candidateAssemblyFiles">List of literal assembly file names to be considered when SearchPaths has {CandidateAssemblyFiles}.</param> 26 /// <param name="searchPathElement"></param> 27 /// <param name="getAssemblyName"></param> 28 /// <param name="fileExists"></param> CandidateAssemblyFilesResolver(string[] candidateAssemblyFiles, string searchPathElement, GetAssemblyName getAssemblyName, FileExists fileExists, GetAssemblyRuntimeVersion getRuntimeVersion, Version targetedRuntimeVesion)29 public CandidateAssemblyFilesResolver(string[] candidateAssemblyFiles, string searchPathElement, GetAssemblyName getAssemblyName, FileExists fileExists, GetAssemblyRuntimeVersion getRuntimeVersion, Version targetedRuntimeVesion) 30 : base(searchPathElement, getAssemblyName, fileExists, getRuntimeVersion, targetedRuntimeVesion, ProcessorArchitecture.None, false) 31 { 32 _candidateAssemblyFiles = candidateAssemblyFiles; 33 } 34 35 /// <summary> 36 /// Resolve a reference to a specific file name. 37 /// </summary> 38 /// <param name="assemblyName">The assemblyname of the reference.</param> 39 /// <param name="rawFileNameCandidate">The reference's 'include' treated as a raw file name.</param> 40 /// <param name="isPrimaryProjectReference">Whether or not this reference was directly from the project file (and therefore not a dependency)</param> 41 /// <param name="wantSpecificVersion">Whether an exact version match is requested.</param> 42 /// <param name="executableExtensions">Allowed executable extensions.</param> 43 /// <param name="hintPath">The item's hintpath value.</param> 44 /// <param name="assemblyFolderKey">Like "hklm\Vendor RegKey" as provided to a reference by the <AssemblyFolderKey> on the reference in the project.</param> 45 /// <param name="assembliesConsideredAndRejected">Receives the list of locations that this function tried to find the assembly. May be "null".</param> 46 /// <param name="foundPath">The path where the file was found.</param> 47 /// <param name="userRequestedSpecificFile">Whether or not the user wanted a specific file (for example, HintPath is a request for a specific file)</param> 48 /// <returns>True if the file was resolved.</returns> Resolve( AssemblyNameExtension assemblyName, string sdkName, string rawFileNameCandidate, bool isPrimaryProjectReference, bool wantSpecificVersion, string[] executableExtensions, string hintPath, string assemblyFolderKey, ArrayList assembliesConsideredAndRejected, out string foundPath, out bool userRequestedSpecificFile )49 public override bool Resolve 50 ( 51 AssemblyNameExtension assemblyName, 52 string sdkName, 53 string rawFileNameCandidate, 54 bool isPrimaryProjectReference, 55 bool wantSpecificVersion, 56 string[] executableExtensions, 57 string hintPath, 58 string assemblyFolderKey, 59 ArrayList assembliesConsideredAndRejected, 60 61 out string foundPath, 62 out bool userRequestedSpecificFile 63 ) 64 { 65 foundPath = null; 66 userRequestedSpecificFile = false; 67 68 if (assemblyName != null) 69 { 70 // {CandidateAssemblyFiles} was passed in. 71 foreach (string candidateAssemblyFile in _candidateAssemblyFiles) 72 { 73 // Filter out disallowed extensions. We don't even want to log them. 74 bool allowedExtension = FileUtilities.HasExtension(candidateAssemblyFile, executableExtensions); 75 if (allowedExtension) 76 { 77 // The file has an allowed extension, so give it a shot. 78 bool matched = false; 79 80 ResolutionSearchLocation considered = null; 81 if (assembliesConsideredAndRejected != null) 82 { 83 considered = new ResolutionSearchLocation(); 84 considered.FileNameAttempted = candidateAssemblyFile; 85 considered.SearchPath = searchPathElement; 86 } 87 88 if (FileMatchesAssemblyName(assemblyName, isPrimaryProjectReference, wantSpecificVersion, false, candidateAssemblyFile, considered)) 89 { 90 matched = true; 91 } 92 else 93 { 94 // Record this as a location that was considered. 95 if (assembliesConsideredAndRejected != null) 96 { 97 Debug.Assert(considered.Reason != NoMatchReason.Unknown, "Expected a no match reason here."); 98 assembliesConsideredAndRejected.Add(considered); 99 } 100 } 101 102 if (matched) 103 { 104 foundPath = candidateAssemblyFile; 105 return true; 106 } 107 } 108 } 109 } 110 111 112 113 return false; 114 } 115 } 116 } 117