/// <summary> /// Get the value of an attribute on a project element /// </summary> /// <param name="attributeName">Name of the attribute to get the value for</param> /// <returns>Value of the attribute</returns> public string GetMetadata(string attributeName) { if (this.IsVirtual) { // For virtual items, use our virtual property collection if (!virtualProperties.ContainsKey(attributeName)) { return(String.Empty); } return(virtualProperties[attributeName]); } // cannot ask MSBuild for Include, so intercept it and return the corresponding property if (String.Compare(attributeName, ProjectFileConstants.Include, StringComparison.OrdinalIgnoreCase) == 0) { return(MSBuildItem.GetEvaluatedInclude(item)); } // Build Action is the type, not a property, so intercept this one as well if (String.Compare(attributeName, ProjectFileConstants.BuildAction, StringComparison.OrdinalIgnoreCase) == 0) { return(MSBuildItem.GetItemType(item)); } return(MSBuildItem.GetMetadataValue(item, attributeName)); }
private void SetProjectItemsThatRelyOnReferencesToBeResolved(bool renameItemNode) { // Call MSBuild to build the target ResolveComReferences bool success; ErrorHandler.ThrowOnFailure(this.ProjectMgr.BuildTarget(MsBuildTarget.ResolveComReferences, out success)); if (!success) { throw new InvalidOperationException(); } // Now loop through the generated COM References to find the corresponding one var instance = this.ProjectMgr.ProjectInstance; AssemblyReferenceNode.BuildInstance(this.ProjectMgr, instance, MsBuildTarget.ResolveAssemblyReferences); var comReferences = MSBuildProjectInstance.GetItems(instance, MsBuildGeneratedItemType.ComReferenceWrappers); foreach (var reference in comReferences) { if (String.Compare(MSBuildItem.GetMetadataValue(reference, ProjectFileConstants.Guid), this.typeGuid.ToString("B"), StringComparison.OrdinalIgnoreCase) == 0 && String.Compare(MSBuildItem.GetMetadataValue(reference, ProjectFileConstants.VersionMajor), this.majorVersionNumber, StringComparison.OrdinalIgnoreCase) == 0 && String.Compare(MSBuildItem.GetMetadataValue(reference, ProjectFileConstants.VersionMinor), this.minorVersionNumber, StringComparison.OrdinalIgnoreCase) == 0 && String.Compare(MSBuildItem.GetMetadataValue(reference, ProjectFileConstants.Lcid), this.lcid, StringComparison.OrdinalIgnoreCase) == 0) { string name = MSBuildItem.GetEvaluatedInclude(reference); if (Path.IsPathRooted(name)) { this.projectRelativeFilePath = name; } else { this.projectRelativeFilePath = Path.Combine(this.ProjectMgr.ProjectFolder, name); } if (renameItemNode) { this.ItemNode.Rename(Path.GetFileNameWithoutExtension(name)); } break; } } }
private void SetHintPathAndPrivateValue(ProjectInstance instance) { // Private means local copy; we want to know if it is already set to not override the default string privateValue = this.ItemNode.GetMetadata(ProjectFileConstants.Private); // Get the list of items which require HintPath IEnumerable <ProjectItemInstance> references = MSBuildProjectInstance.GetItems(instance, MsBuildGeneratedItemType.ReferenceCopyLocalPaths); // Remove the HintPath, we will re-add it below if it is needed if (!String.IsNullOrEmpty(this.assemblyPath)) { this.ItemNode.SetMetadata(ProjectFileConstants.HintPath, null); } // Now loop through the generated References to find the corresponding one foreach (ProjectItemInstance reference in references) { string fileName = Path.GetFileNameWithoutExtension(MSBuildItem.GetEvaluatedInclude(reference)); if (String.Compare(fileName, this.assemblyName.Name, StringComparison.OrdinalIgnoreCase) == 0) { // We found it, now set some properties based on this. string hintPath = MSBuildItem.GetMetadataValue(reference, ProjectFileConstants.HintPath); if (!String.IsNullOrEmpty(hintPath)) { if (Path.IsPathRooted(hintPath)) { hintPath = PackageUtilities.GetPathDistance(this.ProjectMgr.BaseURI.Uri, new Uri(hintPath)); } this.ItemNode.SetMetadata(ProjectFileConstants.HintPath, hintPath); // If this is not already set, we default to true if (String.IsNullOrEmpty(privateValue)) { this.ItemNode.SetMetadata(ProjectFileConstants.Private, true.ToString()); } } break; } } }
/// <summary> /// Does the actual job of resolving an assembly reference. We need a private method that does not violate /// calling virtual method from the constructor. /// </summary> private void ResolveAssemblyReference() { if (this.ProjectMgr == null || this.ProjectMgr.IsClosed) { return; } var instance = this.ProjectMgr.ProjectInstance; BuildInstance(this.ProjectMgr, instance, MsBuildTarget.ResolveAssemblyReferences); IEnumerable <ProjectItemInstance> group = MSBuildProjectInstance.GetItems(instance, ProjectFileConstants.ReferencePath); if (group != null) { foreach (var item in group) { string fullPath = this.GetFullPathFromPath(MSBuildItem.GetEvaluatedInclude(item)); System.Reflection.AssemblyName name = System.Reflection.AssemblyName.GetAssemblyName(fullPath); // Try with full assembly name and then with weak assembly name. if (String.Compare(name.FullName, this.assemblyName.FullName, StringComparison.OrdinalIgnoreCase) == 0 || String.Compare(name.Name, this.assemblyName.Name, StringComparison.OrdinalIgnoreCase) == 0) { if (!NativeMethods.IsSamePath(fullPath, this.assemblyPath)) { // set the full path now. this.assemblyPath = fullPath; // We have a new item to listen too, since the assembly reference is resolved from a different place. this.fileChangeListener.ObserveItem(this.assemblyPath); } this.resolvedAssemblyName = name; // No hint path is needed since the assembly path will always be resolved. return; } } } }