예제 #1
0
파일: Resolver.cs 프로젝트: 3F/IeXod
        /// <summary>
        /// Resolve a single file.
        /// </summary>
        /// <returns>True if the file was a match, false otherwise.</returns>
        protected bool ResolveAsFile
        (
            string fullPath,
            AssemblyNameExtension assemblyName,
            bool isPrimaryProjectReference,
            bool wantSpecificVersion,
            bool allowMismatchBetweenFusionNameAndFileName,
            List <ResolutionSearchLocation> assembliesConsideredAndRejected
        )
        {
            ResolutionSearchLocation considered = null;

            if (assembliesConsideredAndRejected != null)
            {
                considered = new ResolutionSearchLocation
                {
                    FileNameAttempted = fullPath,
                    SearchPath        = searchPathElement
                };
            }

            if (FileMatchesAssemblyName(assemblyName, isPrimaryProjectReference, wantSpecificVersion, allowMismatchBetweenFusionNameAndFileName, fullPath, considered))
            {
                return(true);
            }

            // Record this as a location that was considered.
            assembliesConsideredAndRejected?.Add(considered);

            return(false);
        }
예제 #2
0
        /// <summary>
        /// Resolve a reference to a specific file name.
        /// </summary>
        /// <param name="assemblyName">The assembly name object of the assembly.</param>
        /// <param name="sdkName"></param>
        /// <param name="rawFileNameCandidate">The reference's 'include' treated as a raw file name.</param>
        /// <param name="isPrimaryProjectReference">Whether or not this reference was directly from the project file (and therefore not a dependency)</param>
        /// <param name="wantSpecificVersion">Whether an exact version match is requested.</param>
        /// <param name="executableExtensions">Allowed executable extensions.</param>
        /// <param name="hintPath">The item's hintpath value.</param>
        /// <param name="assemblyFolderKey">Like "hklm\Vendor RegKey" as provided to a reference by the <AssemblyFolderKey> on the reference in the project.</param>
        /// <param name="assembliesConsideredAndRejected">Receives the list of locations that this function tried to find the assembly. May be "null".</param>
        /// <param name="foundPath">The path where the file was found.</param>
        /// <param name="userRequestedSpecificFile">Whether or not the user wanted a specific file (for example, HintPath is a request for a specific file)</param>
        /// <returns>True if the file was resolved.</returns>
        public override bool Resolve
        (
            AssemblyNameExtension assemblyName,
            string sdkName,
            string rawFileNameCandidate,
            bool isPrimaryProjectReference,
            bool wantSpecificVersion,
            string[] executableExtensions,
            string hintPath,
            string assemblyFolderKey,
            List <ResolutionSearchLocation> assembliesConsideredAndRejected,
            out string foundPath,
            out bool userRequestedSpecificFile
        )
        {
            foundPath = null;
            userRequestedSpecificFile = false;

            if (assemblyName != null)
            {
                // {GAC} was passed in.
                string gacResolved = _getAssemblyPathInGac(assemblyName, targetProcessorArchitecture, getRuntimeVersion,
                                                           targetedRuntimeVersion, fileExists, fullFusionName: false, specificVersion: wantSpecificVersion);

                if (!string.IsNullOrEmpty(gacResolved) && fileExists(gacResolved))
                {
                    foundPath = gacResolved;
                    return(true);
                }
                else
                {
                    // Record this as a location that was considered.
                    if (assembliesConsideredAndRejected != null)
                    {
                        var considered = new ResolutionSearchLocation
                        {
                            FileNameAttempted = assemblyName.FullName,
                            SearchPath        = searchPathElement,
                            AssemblyName      = assemblyName,
                            Reason            = NoMatchReason.NotInGac
                        };
                        assembliesConsideredAndRejected.Add(considered);
                    }
                }
            }

            return(false);
        }
예제 #3
0
        /// <summary>
        /// Resolve a reference to a specific file name.
        /// </summary>
        /// <param name="assemblyName">The assemblyname of the reference.</param>
        /// <param name="sdkName"></param>
        /// <param name="rawFileNameCandidate">The reference's 'include' treated as a raw file name.</param>
        /// <param name="isPrimaryProjectReference">Whether or not this reference was directly from the project file (and therefore not a dependency)</param>
        /// <param name="wantSpecificVersion">Whether an exact version match is requested.</param>
        /// <param name="executableExtensions">Allowed executable extensions.</param>
        /// <param name="hintPath">The item's hintpath value.</param>
        /// <param name="assemblyFolderKey">Like "hklm\Vendor RegKey" as provided to a reference by the &lt;AssemblyFolderKey&gt; on the reference in the project.</param>
        /// <param name="assembliesConsideredAndRejected">Receives the list of locations that this function tried to find the assembly. May be "null".</param>
        /// <param name="foundPath">The path where the file was found.</param>
        /// <param name="userRequestedSpecificFile">Whether or not the user wanted a specific file (for example, HintPath is a request for a specific file)</param>
        /// <returns>True if the file was resolved.</returns>
        public override bool Resolve
        (
            AssemblyNameExtension assemblyName,
            string sdkName,
            string rawFileNameCandidate,
            bool isPrimaryProjectReference,
            bool wantSpecificVersion,
            string[] executableExtensions,
            string hintPath,
            string assemblyFolderKey,
            List <ResolutionSearchLocation> assembliesConsideredAndRejected,
            out string foundPath,
            out bool userRequestedSpecificFile
        )
        {
            foundPath = null;
            userRequestedSpecificFile = false;

            if (rawFileNameCandidate != null)
            {
                // {RawFileName} was passed in.
                if (fileExists(rawFileNameCandidate))
                {
                    userRequestedSpecificFile = true;
                    foundPath = rawFileNameCandidate;
                    return(true);
                }

                if (assembliesConsideredAndRejected != null)
                {
                    var considered = new ResolutionSearchLocation
                    {
                        FileNameAttempted = rawFileNameCandidate,
                        SearchPath        = searchPathElement,
                        Reason            = NoMatchReason.NotAFileNameOnDisk
                    };
                    assembliesConsideredAndRejected.Add(considered);
                }
            }

            return(false);
        }
예제 #4
0
        /// <summary>
        /// Resolve a reference to a specific file name.
        /// </summary>
        /// <param name="assemblyName">The assemblyname of the reference.</param>
        /// <param name="sdkName"></param>
        /// <param name="rawFileNameCandidate">The reference's 'include' treated as a raw file name.</param>
        /// <param name="isPrimaryProjectReference">Whether or not this reference was directly from the project file (and therefore not a dependency)</param>
        /// <param name="wantSpecificVersion">Whether an exact version match is requested.</param>
        /// <param name="executableExtensions">Allowed executable extensions.</param>
        /// <param name="hintPath">The item's hintpath value.</param>
        /// <param name="assemblyFolderKey">Like "hklm\Vendor RegKey" as provided to a reference by the &lt;AssemblyFolderKey&gt; on the reference in the project.</param>
        /// <param name="assembliesConsideredAndRejected">Receives the list of locations that this function tried to find the assembly. May be "null".</param>
        /// <param name="foundPath">The path where the file was found.</param>
        /// <param name="userRequestedSpecificFile">Whether or not the user wanted a specific file (for example, HintPath is a request for a specific file)</param>
        /// <returns>True if the file was resolved.</returns>
        public override bool Resolve
        (
            AssemblyNameExtension assemblyName,
            string sdkName,
            string rawFileNameCandidate,
            bool isPrimaryProjectReference,
            bool wantSpecificVersion,
            string[] executableExtensions,
            string hintPath,
            string assemblyFolderKey,
            List <ResolutionSearchLocation> assembliesConsideredAndRejected,
            out string foundPath,
            out bool userRequestedSpecificFile
        )
        {
            foundPath = null;
            userRequestedSpecificFile = false;

            if (assemblyName != null)
            {
                // {CandidateAssemblyFiles} was passed in.
                foreach (string candidateAssemblyFile in _candidateAssemblyFiles)
                {
                    // Filter out disallowed extensions. We don't even want to log them.
                    bool allowedExtension = FileUtilities.HasExtension(candidateAssemblyFile, executableExtensions);
                    if (allowedExtension)
                    {
                        // The file has an allowed extension, so give it a shot.
                        bool matched = false;

                        ResolutionSearchLocation considered = null;
                        if (assembliesConsideredAndRejected != null)
                        {
                            considered = new ResolutionSearchLocation
                            {
                                FileNameAttempted = candidateAssemblyFile,
                                SearchPath        = searchPathElement
                            };
                        }

                        if (FileMatchesAssemblyName(assemblyName, isPrimaryProjectReference, wantSpecificVersion, false, candidateAssemblyFile, considered))
                        {
                            matched = true;
                        }
                        else
                        {
                            // Record this as a location that was considered.
                            if (assembliesConsideredAndRejected != null)
                            {
                                Debug.Assert(considered.Reason != NoMatchReason.Unknown, "Expected a no match reason here.");
                                assembliesConsideredAndRejected.Add(considered);
                            }
                        }

                        if (matched)
                        {
                            foundPath = candidateAssemblyFile;
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
예제 #5
0
파일: Resolver.cs 프로젝트: 3F/IeXod
        /// <summary>
        /// Determines whether an assembly name matches the assembly pointed to by pathToCandidateAssembly
        /// </summary>
        /// <param name="assemblyName">The assembly name to look up.</param>
        /// <param name="isPrimaryProjectReference">True if this is a primary reference directly from the project file.</param>
        /// <param name="wantSpecificVersion">Whether the version needs to match exactly or loosely.</param>
        /// <param name="pathToCandidateAssembly">Path to a possible file.</param>
        /// <param name="searchLocation">Information about why the candidate file didn't match</param>
        protected bool FileMatchesAssemblyName
        (
            AssemblyNameExtension assemblyName,
            bool isPrimaryProjectReference,
            bool wantSpecificVersion,
            bool allowMismatchBetweenFusionNameAndFileName,
            string pathToCandidateAssembly,
            ResolutionSearchLocation searchLocation
        )
        {
            if (searchLocation != null)
            {
                searchLocation.FileNameAttempted = pathToCandidateAssembly;
            }

            // Base name of the target file has to match the Name from the assemblyName
            if (!allowMismatchBetweenFusionNameAndFileName)
            {
                string candidateBaseName = Path.GetFileNameWithoutExtension(pathToCandidateAssembly);
                if (String.Compare(assemblyName?.Name, candidateBaseName, StringComparison.CurrentCultureIgnoreCase) != 0)
                {
                    if (searchLocation != null)
                    {
                        if (candidateBaseName.Length > 0)
                        {
                            searchLocation.AssemblyName = new AssemblyNameExtension(candidateBaseName);
                            searchLocation.Reason       = NoMatchReason.FusionNamesDidNotMatch;
                        }
                        else
                        {
                            searchLocation.Reason = NoMatchReason.TargetHadNoFusionName;
                        }
                    }
                    return(false);
                }
            }

            bool isSimpleAssemblyName = assemblyName != null && assemblyName.IsSimpleName;

            if (fileExists(pathToCandidateAssembly))
            {
                // If the resolver we are using is targeting a given processor architecture then we must crack open the assembly and make sure the architecture is compatible
                // We cannot do these simple name matches.
                if (!compareProcessorArchitecture)
                {
                    // If the file existed and the reference is a simple primary reference which does not contain an assembly name (say a raw file name)
                    // then consider this a match.
                    if (assemblyName == null && isPrimaryProjectReference && !wantSpecificVersion)
                    {
                        return(true);
                    }

                    if (isPrimaryProjectReference && !wantSpecificVersion && isSimpleAssemblyName)
                    {
                        return(true);
                    }
                }

                // We have strong name information, so do some added verification here.
                AssemblyNameExtension targetAssemblyName = null;
                try
                {
                    targetAssemblyName = getAssemblyName(pathToCandidateAssembly);
                }
                catch (FileLoadException)
                {
                    // Its pretty hard to get here, you need an assembly that contains a valid reference
                    // to a dependent assembly that, in turn, throws a FileLoadException during GetAssemblyName.
                    // Still it happened once, with an older version of the CLR.

                    // ...falling through and relying on the targetAssemblyName==null behavior below...
                }

                if (searchLocation != null)
                {
                    searchLocation.AssemblyName = targetAssemblyName;
                }

                // targetAssemblyName may be null if there was no metadata for this assembly.
                // In this case, there's no match.
                if (targetAssemblyName != null)
                {
                    // If we are targeting a given processor architecture check to see if they match, if we are targeting MSIL then any architecture will do.
                    if (compareProcessorArchitecture)
                    {
                        // Only reject the assembly if the target processor architecture does not match the assemby processor architecture and the assembly processor architecture is not NONE or MSIL.
                        if (
                            targetAssemblyName.AssemblyName.ProcessorArchitecture != targetProcessorArchitecture &&                                                            /* The target and assembly architectures do not match*/
                            (targetProcessorArchitecture != ProcessorArchitecture.None && targetAssemblyName.AssemblyName.ProcessorArchitecture != ProcessorArchitecture.None) && /*The assembly is not none*/
                            (targetProcessorArchitecture != ProcessorArchitecture.MSIL && targetAssemblyName.AssemblyName.ProcessorArchitecture != ProcessorArchitecture.MSIL) /*The assembly is not MSIL*/
                            )
                        {
                            if (searchLocation != null)
                            {
                                searchLocation.Reason = NoMatchReason.ProcessorArchitectureDoesNotMatch;
                            }
                            return(false);
                        }
                    }

                    bool matchedSpecificVersion = (wantSpecificVersion && assemblyName != null && assemblyName.Equals(targetAssemblyName));
                    bool matchPartialName       = !wantSpecificVersion && assemblyName != null && assemblyName.PartialNameCompare(targetAssemblyName);

                    if (matchedSpecificVersion || matchPartialName)
                    {
                        return(true);
                    }
                    else
                    {
                        // Reason was: FusionNames did not match.
                        if (searchLocation != null)
                        {
                            searchLocation.Reason = NoMatchReason.FusionNamesDidNotMatch;
                        }
                    }
                }
                else
                {
                    // Reason was: Target had no fusion name.
                    if (searchLocation != null)
                    {
                        searchLocation.Reason = NoMatchReason.TargetHadNoFusionName;
                    }
                }
            }
            else
            {
                // Reason was: No file found at that location.
                if (searchLocation != null)
                {
                    searchLocation.Reason = NoMatchReason.FileNotFound;
                }
            }

            return(false);
        }