/// <summary>
        /// Log the results.
        /// </summary>
        /// <param name="dependencyTable">Reference table.</param>
        /// <param name="idealAssemblyRemappings">Array of ideal assembly remappings.</param>
        /// <param name="idealAssemblyRemappingsIdentities">Array of identities of ideal assembly remappings.</param>
        /// <param name="generalResolutionExceptions">List of exceptions that were not attributable to a particular fusion name.</param>
        /// <returns></returns>
        private bool LogResults
        (
            ReferenceTable dependencyTable,
            DependentAssembly[] idealAssemblyRemappings,
            AssemblyNameReference[] idealAssemblyRemappingsIdentities,
            ArrayList generalResolutionExceptions
        )
        {
            bool success = true;
#if (!STANDALONEBUILD)
            using (new CodeMarkerStartEnd(CodeMarkerEvent.perfMSBuildRARLogResultsBegin, CodeMarkerEvent.perfMSBuildRARLogResultsEnd))
#endif
            {
                /*
                PERF NOTE: The Silent flag turns off logging completely from the task side. This means
                we avoid the String.Formats that would normally occur even if the verbosity was set to 
                quiet at the engine level.
                */
                if (!Silent)
                {
                    // First, loop over primaries and display information.
                    foreach (AssemblyNameExtension assemblyName in dependencyTable.References.Keys)
                    {
                        string fusionName = assemblyName.FullName;
                        Reference primaryCandidate = dependencyTable.GetReference(assemblyName);

                        if (primaryCandidate.IsPrimary && !(primaryCandidate.IsConflictVictim && primaryCandidate.IsCopyLocal))
                        {
                            LogReference(primaryCandidate, fusionName);
                        }
                    }

                    // Second, loop over dependencies and display information.
                    foreach (AssemblyNameExtension assemblyName in dependencyTable.References.Keys)
                    {
                        string fusionName = assemblyName.FullName;
                        Reference dependencyCandidate = dependencyTable.GetReference(assemblyName);

                        if (!dependencyCandidate.IsPrimary && !(dependencyCandidate.IsConflictVictim && dependencyCandidate.IsCopyLocal))
                        {
                            LogReference(dependencyCandidate, fusionName);
                        }
                    }

                    // Third, show conflicts and their resolution.
                    foreach (AssemblyNameExtension assemblyName in dependencyTable.References.Keys)
                    {
                        string fusionName = assemblyName.FullName;
                        Reference conflictCandidate = dependencyTable.GetReference(assemblyName);

                        if (conflictCandidate.IsConflictVictim)
                        {
                            LogConflict(conflictCandidate, fusionName);

                            // Log the assemblies and primary source items which are related to the conflict which was just logged.
                            Reference victor = dependencyTable.GetReference(conflictCandidate.ConflictVictorName);

                            // Log the winner of the conflict resolution, the source items and dependencies which caused it
                            LogReferenceDependenciesAndSourceItems(conflictCandidate.ConflictVictorName.FullName, victor);

                            // Log the reference which lost the conflict and the dependencies and source items which caused it.
                            LogReferenceDependenciesAndSourceItems(fusionName, conflictCandidate);
                        }
                    }

                    // Fourth, if there were any suggested redirects. Show one message per redirect and a single warning.
                    if (idealAssemblyRemappings != null)
                    {
                        bool foundAtLeastOneValidBindingRedirect = false;
                        bool foundAtLeastOneUnresolvableConflict = false;

                        var buffer = new StringBuilder();
                        var ns = XNamespace.Get("urn:schemas-microsoft-com:asm.v1");

                        // A high-priority message for each individual redirect.
                        for (int i = 0; i < idealAssemblyRemappings.Length; i++)
                        {
                            DependentAssembly idealRemapping = idealAssemblyRemappings[i];
                            AssemblyName idealRemappingPartialAssemblyName = idealRemapping.PartialAssemblyName;
                            Reference reference = idealAssemblyRemappingsIdentities[i].reference;

                            for (int j = 0; j < idealRemapping.BindingRedirects.Length; j++)
                            {
                                AssemblyNameExtension[] conflictVictims = reference.GetConflictVictims();
                                foreach (AssemblyNameExtension conflictVictim in conflictVictims)
                                {
                                    // Make note we only output a conflict suggestion if the reference has at 
                                    // least one conflict victim - that way we don't suggest redirects to 
                                    // assemblies that don't exist at runtime. For example, this avoids us suggesting
                                    // a redirect from Foo 1.0.0.0 -> 2.0.0.0 in the following:
                                    //
                                    //      Project -> Foo, 1.0.0.0
                                    //      Project -> Bar -> Foo, 2.0.0.0
                                    //
                                    // Above, Foo, 1.0.0.0 wins out and is copied to the output directory because 
                                    // it is a primary reference.
                                    foundAtLeastOneValidBindingRedirect = true;

                                    Reference victimReference = dependencyTable.GetReference(conflictVictim);
                                    var newVerStr = idealRemapping.BindingRedirects[j].NewVersion.ToString();
                                    Log.LogMessageFromResources
                                    (
                                        MessageImportance.High,
                                        "ResolveAssemblyReference.ConflictRedirectSuggestion",
                                        idealRemappingPartialAssemblyName,
                                        conflictVictim.Version,
                                        victimReference.FullPath,
                                        newVerStr,
                                        reference.FullPath
                                    );

                                    if (!SupportsBindingRedirectGeneration && !AutoUnify)
                                    {
                                        // When running against projects types (such as Web Projects) where we can't auto-generate
                                        // binding redirects during the build, populate a buffer (to be output below) with the
                                        // binding redirect syntax that users need to add manually to the App.Config.

                                        var assemblyIdentityAttributes = new List<XAttribute>(4);

                                        assemblyIdentityAttributes.Add(new XAttribute("name", idealRemappingPartialAssemblyName.Name));

                                        // We use "neutral" for "Invariant Language (Invariant Country)" in assembly names.
                                        var cultureString = idealRemappingPartialAssemblyName.CultureName;
                                        assemblyIdentityAttributes.Add(new XAttribute("culture", String.IsNullOrEmpty(idealRemappingPartialAssemblyName.CultureName) ? "neutral" : idealRemappingPartialAssemblyName.CultureName));

                                        var publicKeyToken = idealRemappingPartialAssemblyName.GetPublicKeyToken();
                                        assemblyIdentityAttributes.Add(new XAttribute("publicKeyToken", ResolveAssemblyReference.ByteArrayToString(publicKeyToken)));

                                        var node = new XElement(
                                            ns + "assemblyBinding",
                                            new XElement(
                                                ns + "dependentAssembly",
                                                new XElement(
                                                    ns + "assemblyIdentity",
                                                    assemblyIdentityAttributes),
                                                new XElement(
                                                    ns + "bindingRedirect",
                                                    new XAttribute("oldVersion", "0.0.0.0-" + newVerStr),
                                                    new XAttribute("newVersion", newVerStr))));

                                        buffer.Append(node.ToString(SaveOptions.DisableFormatting));
                                    }
                                }

                                if (conflictVictims.Length == 0)
                                {
                                    foundAtLeastOneUnresolvableConflict = true;
                                }
                            }
                        }

                        // Log the warning
                        if (idealAssemblyRemappings.Length > 0 && foundAtLeastOneValidBindingRedirect)
                        {
                            if (SupportsBindingRedirectGeneration)
                            {
                                if (!AutoUnify)
                                {
                                    Log.LogWarningWithCodeFromResources("ResolveAssemblyReference.TurnOnAutoGenerateBindingRedirects");
                                }
                                // else we'll generate bindingRedirects to address the remappings
                            }
                            else if (!AutoUnify)
                            {
                                Log.LogWarningWithCodeFromResources("ResolveAssemblyReference.SuggestedRedirects", buffer.ToString());
                            }
                            // else AutoUnify is on and bindingRedirect generation is not supported
                            // we don't warn in this case since the binder will automatically unify these remappings
                        }

                        if (foundAtLeastOneUnresolvableConflict)
                        {
                            // This warning is logged regardless of AutoUnify since it means a conflict existed where the reference
                            // chosen was not the conflict victor in a version comparison, in other words it was older.
                            Log.LogWarningWithCodeFromResources("ResolveAssemblyReference.FoundConflicts");
                        }
                    }

                    // Fifth, log general resolution problems.

                    // Log general resolution exceptions.
                    foreach (Exception error in generalResolutionExceptions)
                    {
                        if (error is InvalidReferenceAssemblyNameException)
                        {
                            InvalidReferenceAssemblyNameException e = (InvalidReferenceAssemblyNameException)error;
                            Log.LogWarningWithCodeFromResources("General.MalformedAssemblyName", e.SourceItemSpec);
                        }
                        else
                        {
                            // An unknown Exception type was returned. Just throw.
                            throw error;
                        }
                    }
                }
            }

            if (dependencyTable.Resolvers != null)
            {
                foreach (Resolver r in dependencyTable.Resolvers)
                {
                    if (r is AssemblyFoldersExResolver)
                    {
                        AssemblyFoldersEx assemblyFoldersEx = ((AssemblyFoldersExResolver)r).AssemblyFoldersExLocations;

                        MessageImportance messageImportance = MessageImportance.Low;
                        if (assemblyFoldersEx != null && _showAssemblyFoldersExLocations.TryGetValue(r.SearchPath, out messageImportance))
                        {
                            Log.LogMessageFromResources(messageImportance, "ResolveAssemblyReference.AssemblyFoldersExSearchLocations", r.SearchPath);
                            foreach (AssemblyFoldersExInfo info in assemblyFoldersEx)
                            {
                                Log.LogMessageFromResources(messageImportance, "ResolveAssemblyReference.EightSpaceIndent", info.DirectoryPath);
                            }
                        }
                    }
                }
            }

            return success;
        }
Exemple #2
0
        /// <summary>
        /// Figure out the what the CopyLocal state of given assembly should be.
        /// </summary>
        /// <param name="assemblyName">The name of the assembly.</param>
        /// <param name="frameworkPaths">The framework paths.</param>
        /// <param name="targetProcessorArchitecture">Like x86 or IA64\AMD64.</param>
        /// <param name="getRuntimeVersion">Delegate to get runtime version.</param>
        /// <param name="targetedRuntimeVersion">The targeted runtime version.</param>
        /// <param name="fileExists">Delegate to check if a file exists.</param>
        /// <param name="getAssemblyPathInGac">Delegate to get the path to an assembly in the system GAC.</param>
        /// <param name="copyLocalDependenciesWhenParentReferenceInGac">if set to true, copy local dependencies when only parent reference in gac.</param>
        /// <param name="doNotCopyLocalIfInGac">If set to true, do not copy local a reference that exists in the GAC (legacy behavior).</param>
        /// <param name="referenceTable">The reference table.</param>
        internal void SetFinalCopyLocalState
        (
            AssemblyNameExtension assemblyName,
            string[] frameworkPaths,
            ProcessorArchitecture targetProcessorArchitecture,
            GetAssemblyRuntimeVersion getRuntimeVersion,
            Version targetedRuntimeVersion,
            FileExists fileExists,
            GetAssemblyPathInGac getAssemblyPathInGac,
            bool copyLocalDependenciesWhenParentReferenceInGac,
            bool doNotCopyLocalIfInGac,
            ReferenceTable referenceTable
        )
        {
            // If this item was unresolvable, then copy-local is false.
            if (IsUnresolvable)
            {
                _copyLocalState = CopyLocalState.NoBecauseUnresolved;
                return;
            }

            if (EmbedInteropTypes)
            {
                _copyLocalState = CopyLocalState.NoBecauseEmbedded;
                return;
            }

            // If this item was a conflict victim, then it should not be copy-local.
            if (IsConflictVictim)
            {
                _copyLocalState = CopyLocalState.NoBecauseConflictVictim;
                return;
            }

            // If this is a primary reference then see if there's a Private metadata on the source item
            if (IsPrimary)
            {
                bool found;
                bool result = MetadataConversionUtilities.TryConvertItemMetadataToBool
                    (
                        PrimarySourceItem,
                        ItemMetadataNames.privateMetadata,
                        out found
                    );

                if (found)
                {
                    _copyLocalState = result
                        ? CopyLocalState.YesBecauseReferenceItemHadMetadata
                        : CopyLocalState.NoBecauseReferenceItemHadMetadata;
                    return;
                }
            }
            else
            {
                // This is a dependency. If any primary reference that lead to this dependency
                // has Private=false, then this dependency should false too.
                bool privateTrueFound = false;
                bool privateFalseFound = false;
                foreach (DictionaryEntry entry in _sourceItems)
                {
                    bool found;
                    bool result = MetadataConversionUtilities.TryConvertItemMetadataToBool
                        (
                            (ITaskItem)entry.Value,
                            ItemMetadataNames.privateMetadata,
                            out found
                        );

                    if (found)
                    {
                        if (result)
                        {
                            privateTrueFound = true;

                            // Once we hit this once we know there will be no modification to CopyLocal state.
                            // so we can immediately...
                            break;
                        }
                        else
                        {
                            privateFalseFound = true;
                        }
                    }
                }

                if (privateFalseFound && !privateTrueFound)
                {
                    _copyLocalState = CopyLocalState.NoBecauseReferenceItemHadMetadata;
                    return;
                }
            }

            // If the item was determined to be an prereq assembly.
            if (IsPrerequisite && !UserRequestedSpecificFile)
            {
                _copyLocalState = CopyLocalState.NoBecausePrerequisite;
                return;
            }

            // Items in the frameworks directory shouldn't be copy-local
            if (IsFrameworkFile(_fullPath, frameworkPaths))
            {
                _copyLocalState = CopyLocalState.NoBecauseFrameworkFile;
                return;
            }

            // We are a dependency, check to see if all of our parent references have come from the GAC
            if (!IsPrimary && !copyLocalDependenciesWhenParentReferenceInGac)
            {
                // Did we discover a parent reference which was not found in the GAC
                bool foundSourceItemNotInGac = false;

                // Go through all of the parent source items and check to see if they were found in the GAC
                foreach (DictionaryEntry entry in _sourceItems)
                {
                    AssemblyNameExtension primaryAssemblyName = referenceTable.GetReferenceFromItemSpec((string)entry.Key);
                    Reference primaryReference = referenceTable.GetReference(primaryAssemblyName);

                    if (doNotCopyLocalIfInGac)
                    {
                        // Legacy behavior, don't copy local if the assembly is in the GAC at all
                        if (!primaryReference.FoundInGac.HasValue)
                        {
                            primaryReference.FoundInGac = !string.IsNullOrEmpty(getAssemblyPathInGac(primaryAssemblyName, targetProcessorArchitecture, getRuntimeVersion, targetedRuntimeVersion, fileExists, true, false));
                        }

                        if (!primaryReference.FoundInGac.Value)
                        {
                            foundSourceItemNotInGac = true;
                            break;
                        }
                    }
                    else
                    {
                    if (!primaryReference.ResolvedFromGac)
                    {
                        foundSourceItemNotInGac = true;
                        break;
                    }
                }
                }

                // All parent source items were found in the GAC.
                if (!foundSourceItemNotInGac)
                {
                    _copyLocalState = CopyLocalState.NoBecauseParentReferencesFoundInGAC;
                    return;
                }
            }

            if (doNotCopyLocalIfInGac)
            {
                // Legacy behavior, don't copy local if the assembly is in the GAC at all
                if (!FoundInGac.HasValue)
                {
                    FoundInGac = !string.IsNullOrEmpty(getAssemblyPathInGac(assemblyName, targetProcessorArchitecture, getRuntimeVersion, targetedRuntimeVersion, fileExists, true, false));
                }

                if (FoundInGac.Value)
                {
                    _copyLocalState = CopyLocalState.NoBecauseReferenceFoundInGAC;
                    return;
                }
            }

            if (ResolvedFromGac)
            {
                _copyLocalState = CopyLocalState.NoBecauseReferenceResolvedFromGAC;
                return;
            }

            //  It was resolved locally, so copy it.
            _copyLocalState = CopyLocalState.YesBecauseOfHeuristic;
        }
 private bool LogResults(ReferenceTable dependencyTable, DependentAssembly[] idealAssemblyRemappings, AssemblyNameReference[] idealAssemblyRemappingsIdentities, ArrayList generalResolutionExceptions)
 {
     bool flag = true;
     using (new CodeMarkerStartEnd(CodeMarkerEvent.perfMSBuildRARLogResultsBegin, CodeMarkerEvent.perfMSBuildRARLogResultsEnd))
     {
         if (this.Silent)
         {
             return flag;
         }
         foreach (AssemblyNameExtension extension in dependencyTable.References.Keys)
         {
             string fullName = extension.FullName;
             Reference reference = dependencyTable.GetReference(extension);
             if (reference.IsPrimary && (!reference.IsConflictVictim || !reference.IsCopyLocal))
             {
                 this.LogReference(reference, fullName);
             }
         }
         foreach (AssemblyNameExtension extension2 in dependencyTable.References.Keys)
         {
             string fusionName = extension2.FullName;
             Reference reference2 = dependencyTable.GetReference(extension2);
             if (!reference2.IsPrimary && (!reference2.IsConflictVictim || !reference2.IsCopyLocal))
             {
                 this.LogReference(reference2, fusionName);
             }
         }
         foreach (AssemblyNameExtension extension3 in dependencyTable.References.Keys)
         {
             string str3 = extension3.FullName;
             Reference reference3 = dependencyTable.GetReference(extension3);
             if (reference3.IsConflictVictim)
             {
                 this.LogConflict(reference3, str3);
                 Reference conflictCandidate = dependencyTable.GetReference(reference3.ConflictVictorName);
                 this.LogReferenceDependenciesAndSourceItems(reference3.ConflictVictorName.FullName, conflictCandidate);
                 this.LogReferenceDependenciesAndSourceItems(str3, reference3);
             }
         }
         if (this.suggestedRedirects.Length > 0)
         {
             for (int i = 0; i < idealAssemblyRemappings.Length; i++)
             {
                 DependentAssembly assembly = idealAssemblyRemappings[i];
                 AssemblyName partialAssemblyName = assembly.PartialAssemblyName;
                 Reference reference5 = idealAssemblyRemappingsIdentities[i].reference;
                 for (int j = 0; j < assembly.BindingRedirects.Length; j++)
                 {
                     foreach (AssemblyNameExtension extension4 in reference5.GetConflictVictims())
                     {
                         Reference reference6 = dependencyTable.GetReference(extension4);
                         base.Log.LogMessageFromResources(MessageImportance.High, "ResolveAssemblyReference.ConflictRedirectSuggestion", new object[] { partialAssemblyName, extension4.Version, reference6.FullPath, assembly.BindingRedirects[j].NewVersion, reference5.FullPath });
                     }
                 }
             }
             base.Log.LogWarningWithCodeFromResources("ResolveAssemblyReference.SuggestedRedirects", new object[0]);
         }
         foreach (Exception exception in generalResolutionExceptions)
         {
             if (!(exception is InvalidReferenceAssemblyNameException))
             {
                 throw exception;
             }
             InvalidReferenceAssemblyNameException exception2 = (InvalidReferenceAssemblyNameException) exception;
             base.Log.LogWarningWithCodeFromResources("General.MalformedAssemblyName", new object[] { exception2.SourceItemSpec });
         }
     }
     return flag;
 }
 internal void SetFinalCopyLocalState(AssemblyNameExtension assemblyName, string[] frameworkPaths, ProcessorArchitecture targetProcessorArchitecture, GetAssemblyRuntimeVersion getRuntimeVersion, Version targetedRuntimeVersion, Microsoft.Build.Shared.FileExists fileExists, bool copyLocalDependenciesWhenParentReferenceInGac, ReferenceTable referenceTable, CheckIfAssemblyInGac checkIfAssemblyInGac)
 {
     if (this.IsUnresolvable)
     {
         this.copyLocalState = CopyLocalState.NoBecauseUnresolved;
     }
     else if (this.EmbedInteropTypes)
     {
         this.copyLocalState = CopyLocalState.NoBecauseEmbedded;
     }
     else if (this.IsConflictVictim)
     {
         this.copyLocalState = CopyLocalState.NoBecauseConflictVictim;
     }
     else
     {
         if (this.IsPrimary)
         {
             bool flag;
             bool flag2 = MetadataConversionUtilities.TryConvertItemMetadataToBool(this.PrimarySourceItem, "Private", out flag);
             if (flag)
             {
                 if (flag2)
                 {
                     this.copyLocalState = CopyLocalState.YesBecauseReferenceItemHadMetadata;
                     return;
                 }
                 this.copyLocalState = CopyLocalState.NoBecauseReferenceItemHadMetadata;
                 return;
             }
         }
         else
         {
             bool flag3 = false;
             bool flag4 = false;
             foreach (DictionaryEntry entry in this.sourceItems)
             {
                 bool flag5;
                 bool flag6 = MetadataConversionUtilities.TryConvertItemMetadataToBool((ITaskItem) entry.Value, "Private", out flag5);
                 if (flag5)
                 {
                     if (flag6)
                     {
                         flag3 = true;
                         break;
                     }
                     flag4 = true;
                 }
             }
             if (flag4 && !flag3)
             {
                 this.copyLocalState = CopyLocalState.NoBecauseReferenceItemHadMetadata;
                 return;
             }
         }
         if (this.IsPrerequisite && !this.UserRequestedSpecificFile)
         {
             this.copyLocalState = CopyLocalState.NoBecausePrerequisite;
         }
         else if (IsFrameworkFile(this.fullPath, frameworkPaths))
         {
             this.copyLocalState = CopyLocalState.NoBecauseFrameworkFile;
         }
         else
         {
             if (!this.FoundInGac.HasValue)
             {
                 bool flag7 = checkIfAssemblyInGac(assemblyName, targetProcessorArchitecture, getRuntimeVersion, targetedRuntimeVersion, fileExists);
                 this.FoundInGac = new bool?(flag7);
             }
             if (this.FoundInGac.Value)
             {
                 this.copyLocalState = CopyLocalState.NoBecauseReferenceFoundInGAC;
             }
             else
             {
                 if (!this.IsPrimary && !copyLocalDependenciesWhenParentReferenceInGac)
                 {
                     bool flag8 = false;
                     foreach (DictionaryEntry entry2 in this.sourceItems)
                     {
                         AssemblyNameExtension referenceFromItemSpec = referenceTable.GetReferenceFromItemSpec((string) entry2.Key);
                         Reference reference = referenceTable.GetReference(referenceFromItemSpec);
                         bool flag9 = false;
                         if (!reference.FoundInGac.HasValue)
                         {
                             flag9 = checkIfAssemblyInGac(referenceFromItemSpec, targetProcessorArchitecture, getRuntimeVersion, targetedRuntimeVersion, fileExists);
                             reference.FoundInGac = new bool?(flag9);
                         }
                         else
                         {
                             flag9 = reference.FoundInGac.Value;
                         }
                         if (!flag9)
                         {
                             flag8 = true;
                             break;
                         }
                     }
                     if (!flag8)
                     {
                         this.copyLocalState = CopyLocalState.NoBecauseParentReferencesFoundInGAC;
                         return;
                     }
                 }
                 this.copyLocalState = CopyLocalState.YesBecauseOfHeuristic;
             }
         }
     }
 }