/// <summary> /// Internal constructor /// </summary> /// <param name="taskLoggingHelper">task logger instance used for logging</param> /// <param name="silent">true if this task should log only errors, no warnings or messages; false otherwise</param> /// <param name="referenceInfo">cached reference information (typelib pointer, original task item, typelib name etc.)</param> /// <param name="itemName">reference name (for better logging experience)</param> internal ComReference(TaskLoggingHelper taskLoggingHelper, bool silent, ComReferenceInfo referenceInfo, string itemName) { _referenceInfo = referenceInfo; _itemName = itemName; _log = taskLoggingHelper; _silent = silent; }
/// <summary> /// Internal constructor /// </summary> /// <param name="taskLoggingHelper">task logger instance used for logging</param> /// <param name="silent">true if this task should log only errors, no warnings or messages; false otherwise</param> /// <param name="referenceInfo">cached reference information (typelib pointer, original task item, typelib name etc.)</param> /// <param name="itemName">reference name (for better logging experience)</param> internal ComReference(TaskLoggingHelper taskLoggingHelper, bool silent, ComReferenceInfo referenceInfo, string itemName) { ReferenceInfo = referenceInfo; ItemName = itemName; Log = taskLoggingHelper; Silent = silent; }
internal TlbReference(TaskLoggingHelper taskLoggingHelper, IComReferenceResolver resolverCallback, IEnumerable<string> referenceFiles, ComReferenceInfo referenceInfo, string itemName, string outputDirectory, bool hasTemporaryWrapper, bool delaySign, string keyFile, string keyContainer, bool noClassMembers, string targetProcessorArchitecture, bool includeTypeLibVersionInName, bool executeAsTool, string sdkToolsPath, IBuildEngine buildEngine, string[] environmentVariables) : base(taskLoggingHelper, resolverCallback, referenceInfo, itemName, outputDirectory, delaySign, keyFile, keyContainer, includeTypeLibVersionInName, executeAsTool, sdkToolsPath, buildEngine, environmentVariables) { this.hasTemporaryWrapper = hasTemporaryWrapper; this.noClassMembers = noClassMembers; this.targetProcessorArchitecture = targetProcessorArchitecture; this.referenceFiles = referenceFiles; }
internal ComReferenceInfo(ComReferenceInfo copyFrom) { this.attr = copyFrom.attr; this.typeLibName = copyFrom.typeLibName; this.typeLibPath = copyFrom.typeLibPath; this.typeLibPointer = copyFrom.typeLibPointer; this.primaryOfAxImpRef = copyFrom.primaryOfAxImpRef; this.resolvedWrapper = copyFrom.resolvedWrapper; this.taskItem = new TaskItem(copyFrom.taskItem); this.dependentWrapperPaths = copyFrom.dependentWrapperPaths; this.referencePathItem = copyFrom.referencePathItem; }
internal AxTlbBaseReference(TaskLoggingHelper taskLoggingHelper, IComReferenceResolver resolverCallback, ComReferenceInfo referenceInfo, string itemName, string outputDirectory, bool delaySign, string keyFile, string keyContainer, bool includeTypeLibVersionInName, bool executeAsTool, string toolPath, IBuildEngine buildEngine, string[] environmentVariables) : base(taskLoggingHelper, referenceInfo, itemName) { this.resolverCallback = resolverCallback; this.outputDirectory = outputDirectory; this.includeTypeLibVersionInName = includeTypeLibVersionInName; this.BuildEngine = buildEngine; this.EnvironmentVariables = environmentVariables; this.DelaySign = delaySign; this.ExecuteAsTool = executeAsTool; this.KeyFile = keyFile; this.KeyContainer = keyContainer; this.ToolPath = toolPath; }
internal void AddMissingTlbReferences() { List<ComReferenceInfo> list = new List<ComReferenceInfo>(); foreach (ComReferenceInfo info in this.allProjectRefs) { if (!ComReferenceTypes.IsAxImp(info.taskItem.GetMetadata("WrapperTool"))) { continue; } bool flag = false; foreach (ComReferenceInfo info2 in this.allProjectRefs) { string metadata = info2.taskItem.GetMetadata("WrapperTool"); if (((ComReferenceTypes.IsTlbImp(metadata) || ComReferenceTypes.IsPia(metadata)) || ComReferenceTypes.IsPiaOrTlbImp(metadata)) && ComReference.AreTypeLibAttrEqual(info.attr, info2.attr)) { info.taskItem.SetMetadata("TlbReferenceName", info2.typeLibName); string parameterValue = info2.taskItem.GetMetadata("EmbedInteropTypes"); if (ConversionUtilities.CanConvertStringToBool(parameterValue) && ConversionUtilities.ConvertStringToBool(parameterValue)) { base.Log.LogMessageFromResources(MessageImportance.High, "ResolveComReference.TreatingTlbOfActiveXAsNonEmbedded", new object[] { info2.taskItem.ItemSpec, info.taskItem.ItemSpec }); info2.taskItem.SetMetadata("EmbedInteropTypes", "false"); } info.primaryOfAxImpRef = info2; flag = true; break; } } if (!flag) { base.Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.AddingMissingTlbReference", new object[] { info.taskItem.ItemSpec }); ComReferenceInfo item = new ComReferenceInfo(info); item.taskItem.SetMetadata("WrapperTool", "primaryortlbimp"); item.taskItem.SetMetadata("EmbedInteropTypes", "false"); info.primaryOfAxImpRef = item; list.Add(item); info.taskItem.SetMetadata("TlbReferenceName", item.typeLibName); } } foreach (ComReferenceInfo info4 in list) { this.allProjectRefs.Add(info4); } }
private void ConvertAttrReferencesToComReferenceInfo(List<ComReferenceInfo> projectRefs, ITaskItem[] typeLibAttrs) { int num = (typeLibAttrs == null) ? 0 : typeLibAttrs.GetLength(0); for (int i = 0; i < num; i++) { ComReferenceInfo item = new ComReferenceInfo(); try { if (item.InitializeWithTypeLibAttrs(base.Log, TaskItemToTypeLibAttr(typeLibAttrs[i]), typeLibAttrs[i], this.TargetProcessorArchitecture)) { projectRefs.Add(item); } else { item.ReleaseTypeLibPtr(); } } catch (COMException exception) { base.Log.LogWarningWithCodeFromResources("ResolveComReference.CannotLoadTypeLibItemSpec", new object[] { typeLibAttrs[i].ItemSpec, exception.Message }); item.ReleaseTypeLibPtr(); } } }
/* * Method: PiaReference constructor * */ internal PiaReference(TaskLoggingHelper taskLoggingHelper, bool silent, ComReferenceInfo referenceInfo, string itemName) : base(taskLoggingHelper, silent, referenceInfo, itemName) { // do nothing }
private List<string> ScanAndResolveAllDependencies(ComDependencyWalker dependencyWalker, ComReferenceInfo reference) { dependencyWalker.ClearDependencyList(); base.Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.ScanningDependencies", new object[] { reference.SourceItemSpec }); dependencyWalker.AnalyzeTypeLibrary(reference.typeLibPointer); foreach (Exception exception in dependencyWalker.EncounteredProblems) { base.Log.LogWarningWithCodeFromResources("ResolveComReference.FailedToScanDependencies", new object[] { reference.SourceItemSpec, exception.Message }); } dependencyWalker.EncounteredProblems.Clear(); HashSet<string> source = new HashSet<string>(); foreach (System.Runtime.InteropServices.ComTypes.TYPELIBATTR typelibattr in dependencyWalker.GetDependencies()) { if (!ComReference.AreTypeLibAttrEqual(typelibattr, reference.attr)) { ComReferenceInfo info; if (this.IsExistingProjectReference(typelibattr, null, out info)) { ITaskItem item; dependencyWalker.ClearAnalyzedTypeCache(); if (this.ResolveReference(dependencyWalker, info, this.WrapperOutputDirectory, out item)) { source.Add(item.ItemSpec); foreach (string str in info.dependentWrapperPaths) { source.Add(str); } } } else { ComReferenceWrapperInfo info2; base.Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.ResolvingDependency", new object[] { typelibattr.guid, typelibattr.wMajorVerNum, typelibattr.wMinorVerNum }); ((IComReferenceResolver) this).ResolveComClassicReference(typelibattr, this.WrapperOutputDirectory, null, null, out info2); base.Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.ResolvedDependentComReference", new object[] { typelibattr.guid, typelibattr.wMajorVerNum, typelibattr.wMinorVerNum, info2.path }); source.Add(info2.path); } } } return source.ToList<string>(); }
internal bool ResolveReference(ComDependencyWalker dependencyWalker, ComReferenceInfo referenceInfo, string outputDirectory, out ITaskItem referencePathItem) { if (referenceInfo.referencePathItem == null) { ComReferenceWrapperInfo info; base.Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.Resolving", new object[] { referenceInfo.taskItem.ItemSpec, referenceInfo.taskItem.GetMetadata("WrapperTool") }); List<string> list = this.ScanAndResolveAllDependencies(dependencyWalker, referenceInfo); referenceInfo.dependentWrapperPaths = list; referencePathItem = new TaskItem(); referenceInfo.referencePathItem = referencePathItem; if (this.ResolveComClassicReference(referenceInfo, outputDirectory, referenceInfo.taskItem.GetMetadata("WrapperTool"), referenceInfo.taskItem.ItemSpec, true, referenceInfo.dependentWrapperPaths, out info)) { referencePathItem.ItemSpec = info.path; referenceInfo.taskItem.CopyMetadataTo(referencePathItem); string fullName = AssemblyName.GetAssemblyName(info.path).FullName; referencePathItem.SetMetadata("FusionName", fullName); base.Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.ResolvedReference", new object[] { referenceInfo.taskItem.ItemSpec, info.path }); return true; } base.Log.LogWarningWithCodeFromResources("ResolveComReference.CannotFindWrapperForTypeLib", new object[] { referenceInfo.taskItem.ItemSpec }); return false; } bool flag = !string.IsNullOrEmpty(referenceInfo.referencePathItem.ItemSpec); referencePathItem = referenceInfo.referencePathItem; return flag; }
internal bool ResolveComReferencePia(ComReferenceInfo referenceInfo, string refName, out ComReferenceWrapperInfo wrapperInfo) { wrapperInfo = null; string key = ComReference.UniqueKeyFromTypeLibAttr(referenceInfo.attr); if (this.cachePia.ContainsKey(key)) { wrapperInfo = (ComReferenceWrapperInfo) this.cachePia[key]; return true; } try { PiaReference reference = new PiaReference(base.Log, referenceInfo, refName); if (!reference.FindExistingWrapper(out wrapperInfo, this.timestampCache[referenceInfo.typeLibPath])) { return false; } this.cachePia.Add(key, wrapperInfo); } catch (Exception exception) { if (Microsoft.Build.Shared.ExceptionHandling.NotExpectedException(exception)) { throw; } return false; } return true; }
internal bool ResolveComClassicReference(ComReferenceInfo referenceInfo, string outputDirectory, string wrapperType, string refName, bool topLevelRef, List<string> dependencyPaths, out ComReferenceWrapperInfo wrapperInfo) { wrapperInfo = null; bool flag = false; if (ComReferenceTypes.IsPia(wrapperType)) { flag = this.ResolveComReferencePia(referenceInfo, refName, out wrapperInfo); } else if (ComReferenceTypes.IsTlbImp(wrapperType)) { flag = this.ResolveComReferenceTlb(referenceInfo, outputDirectory, refName, topLevelRef, dependencyPaths, out wrapperInfo); } else if (ComReferenceTypes.IsAxImp(wrapperType)) { flag = this.ResolveComReferenceAx(referenceInfo, outputDirectory, refName, out wrapperInfo); } else if ((wrapperType == null) || ComReferenceTypes.IsPiaOrTlbImp(wrapperType)) { flag = this.ResolveComReferencePia(referenceInfo, refName, out wrapperInfo); if (!flag) { flag = this.ResolveComReferenceTlb(referenceInfo, outputDirectory, refName, false, dependencyPaths, out wrapperInfo); } } else { Microsoft.Build.Shared.ErrorUtilities.VerifyThrow(false, "Unknown wrapper type!"); } referenceInfo.resolvedWrapper = wrapperInfo; this.timestampCache[referenceInfo.typeLibPath] = File.GetLastWriteTime(referenceInfo.typeLibPath); return flag; }
public void TestCheckForConflictingReferences() { TYPELIBATTR axAttr, tlbAttr, piaAttr, notInProjectAttr; ComReferenceInfo axRefInfo, tlbRefInfo, piaRefInfo; CreateTestReferences(out axRefInfo, out tlbRefInfo, out piaRefInfo, out axAttr, out tlbAttr, out piaAttr, out notInProjectAttr); ResolveComReference rcr = new ResolveComReference(); rcr.BuildEngine = new MockEngine(); // populate the ResolveComReference's list of project references rcr.allProjectRefs = new List<ComReferenceInfo>(); rcr.allProjectRefs.Add(axRefInfo); rcr.allProjectRefs.Add(tlbRefInfo); rcr.allProjectRefs.Add(piaRefInfo); // no conflicts should be found with just the three initial refs Assert.IsTrue(rcr.CheckForConflictingReferences()); Assert.AreEqual(3, rcr.allProjectRefs.Count); ComReferenceInfo referenceInfo; // duplicate refs should not be treated as conflicts referenceInfo = new ComReferenceInfo(tlbRefInfo); rcr.allProjectRefs.Add(referenceInfo); referenceInfo = new ComReferenceInfo(axRefInfo); rcr.allProjectRefs.Add(referenceInfo); referenceInfo = new ComReferenceInfo(piaRefInfo); rcr.allProjectRefs.Add(referenceInfo); Assert.IsTrue(rcr.CheckForConflictingReferences()); Assert.AreEqual(6, rcr.allProjectRefs.Count); // tlb and ax refs with same lib name but different attributes should be considered conflicting // We don't care about typelib name conflicts for PIA refs, because we don't have to create wrappers for them ComReferenceInfo conflictTlb = new ComReferenceInfo(tlbRefInfo); conflictTlb.attr = notInProjectAttr; rcr.allProjectRefs.Add(conflictTlb); ComReferenceInfo conflictAx = new ComReferenceInfo(axRefInfo); conflictAx.attr = notInProjectAttr; rcr.allProjectRefs.Add(conflictAx); ComReferenceInfo piaRef = new ComReferenceInfo(piaRefInfo); piaRef.attr = notInProjectAttr; rcr.allProjectRefs.Add(piaRef); Assert.IsTrue(!rcr.CheckForConflictingReferences()); // ... and conflicting references should have been removed Assert.AreEqual(7, rcr.allProjectRefs.Count); Assert.IsTrue(!rcr.allProjectRefs.Contains(conflictTlb)); Assert.IsTrue(!rcr.allProjectRefs.Contains(conflictAx)); Assert.IsTrue(rcr.allProjectRefs.Contains(piaRef)); }
/// <summary> /// Scan all the dependencies of the main project references and preresolve them /// so that when we get asked about a previously unknown dependency in the form of a .NET assembly /// we know what to do with it. /// </summary> private List<string> ScanAndResolveAllDependencies(ComDependencyWalker dependencyWalker, ComReferenceInfo reference) { dependencyWalker.ClearDependencyList(); if (!Silent) { Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.ScanningDependencies", reference.SourceItemSpec); } dependencyWalker.AnalyzeTypeLibrary(reference.typeLibPointer); if (!Silent) { foreach (Exception ex in dependencyWalker.EncounteredProblems) { // A failure to resolve a reference due to something possibly being missing from disk is not // an error; the user may not be actually consuming types from it Log.LogWarningWithCodeFromResources("ResolveComReference.FailedToScanDependencies", reference.SourceItemSpec, ex.Message); } } dependencyWalker.EncounteredProblems.Clear(); HashSet<string> dependentPaths = new HashSet<string>(); TYPELIBATTR[] dependentAttrs = dependencyWalker.GetDependencies(); foreach (TYPELIBATTR dependencyTypeLibAttr in dependentAttrs) { // We don't need to even try to resolve if the dependency reference is ourselves. if (!ComReference.AreTypeLibAttrEqual(dependencyTypeLibAttr, reference.attr)) { ComReferenceInfo existingReference; if (IsExistingProjectReference(dependencyTypeLibAttr, null, out existingReference)) { ITaskItem resolvedItem; // If we're resolving another project reference, empty out the type cache -- if the dependencies are buried, // caching the analyzed types can make it so that we don't recognize our dependencies' dependencies. dependencyWalker.ClearAnalyzedTypeCache(); if (ResolveReference(dependencyWalker, existingReference, WrapperOutputDirectory, out resolvedItem)) { // Add the resolved dependency dependentPaths.Add(resolvedItem.ItemSpec); // and anything it depends on foreach (string dependentPath in existingReference.dependentWrapperPaths) { dependentPaths.Add(dependentPath); } } } else { if (!Silent) { Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.ResolvingDependency", dependencyTypeLibAttr.guid, dependencyTypeLibAttr.wMajorVerNum, dependencyTypeLibAttr.wMinorVerNum); } ComReferenceWrapperInfo wrapperInfo; ((IComReferenceResolver)this).ResolveComClassicReference(dependencyTypeLibAttr, WrapperOutputDirectory, null /* unknown wrapper type */, null /* unknown name */, out wrapperInfo); if (!Silent) { Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.ResolvedDependentComReference", dependencyTypeLibAttr.guid, dependencyTypeLibAttr.wMajorVerNum, dependencyTypeLibAttr.wMinorVerNum, wrapperInfo.path); } dependentPaths.Add(wrapperInfo.path); } } } return dependentPaths.ToList<string>(); }
/* * Method: ConvertAttrReferencesToComReferenceInfo * * Helper method. Converts TypeLibAttr references to ComReferenceInfo objects. * This method cannot fail, since we want to proceed with the task even if some references won't load. */ private void ConvertAttrReferencesToComReferenceInfo(List<ComReferenceInfo> projectRefs, ITaskItem[] typeLibAttrs) { int typeLibAttrsLength = (typeLibAttrs == null) ? 0 : typeLibAttrs.GetLength(0); for (int i = 0; i < typeLibAttrsLength; i++) { ComReferenceInfo projectRefInfo = new ComReferenceInfo(); try { if (projectRefInfo.InitializeWithTypeLibAttrs(Log, Silent, TaskItemToTypeLibAttr(typeLibAttrs[i]), typeLibAttrs[i], this.TargetProcessorArchitecture)) { projectRefs.Add(projectRefInfo); } else { projectRefInfo.ReleaseTypeLibPtr(); } } catch (COMException ex) { if (!Silent) { Log.LogWarningWithCodeFromResources("ResolveComReference.CannotLoadTypeLibItemSpec", typeLibAttrs[i].ItemSpec, ex.Message); } projectRefInfo.ReleaseTypeLibPtr(); // we don't want to fail the task if one of the references is not registered, so just continue } } }
/* * Method: ConvertFileReferencesToComReferenceInfo * * Helper method. Converts TypeLibFiles references to ComReferenceInfo objects * This method cannot fail, since we want to proceed with the task even if some references won't load. */ private void ConvertFileReferencesToComReferenceInfo(List<ComReferenceInfo> projectRefs, ITaskItem[] tlbFiles) { int tlbFilesLength = (tlbFiles == null) ? 0 : tlbFiles.GetLength(0); for (int i = 0; i < tlbFilesLength; i++) { string refPath = tlbFiles[i].ItemSpec; if (!Path.IsPathRooted(refPath)) refPath = Path.Combine(Directory.GetCurrentDirectory(), refPath); ComReferenceInfo projectRefInfo = new ComReferenceInfo(); try { if (projectRefInfo.InitializeWithPath(Log, Silent, refPath, tlbFiles[i], this.TargetProcessorArchitecture)) { projectRefs.Add(projectRefInfo); } else { projectRefInfo.ReleaseTypeLibPtr(); } } catch (COMException ex) { if (!Silent) { Log.LogWarningWithCodeFromResources("ResolveComReference.CannotLoadTypeLibItemSpec", tlbFiles[i].ItemSpec, ex.Message); } projectRefInfo.ReleaseTypeLibPtr(); // we don't want to fail the task if one of the references is not registered, so just continue } } }
/* * Method: ResolveReference * * Helper COM resolution method. Creates an appropriate helper class for the given tool and calls * the Resolve method on it. */ internal bool ResolveReference(ComDependencyWalker dependencyWalker, ComReferenceInfo referenceInfo, string outputDirectory, out ITaskItem referencePathItem) { if (referenceInfo.referencePathItem == null) { if (!Silent) { Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.Resolving", referenceInfo.taskItem.ItemSpec, referenceInfo.taskItem.GetMetadata(ComReferenceItemMetadataNames.wrapperTool)); } List<string> dependencyPaths = ScanAndResolveAllDependencies(dependencyWalker, referenceInfo); referenceInfo.dependentWrapperPaths = dependencyPaths; referencePathItem = new TaskItem(); referenceInfo.referencePathItem = referencePathItem; ComReferenceWrapperInfo wrapperInfo; if (ResolveComClassicReference(referenceInfo, outputDirectory, referenceInfo.taskItem.GetMetadata(ComReferenceItemMetadataNames.wrapperTool), referenceInfo.taskItem.ItemSpec, true, referenceInfo.dependentWrapperPaths, out wrapperInfo)) { referencePathItem.ItemSpec = wrapperInfo.path; referenceInfo.taskItem.CopyMetadataTo(referencePathItem); string fusionName = AssemblyName.GetAssemblyName(wrapperInfo.path).FullName; referencePathItem.SetMetadata(ItemMetadataNames.fusionName, fusionName); if (!Silent) { Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.ResolvedReference", referenceInfo.taskItem.ItemSpec, wrapperInfo.path); } return true; } if (!Silent) { Log.LogWarningWithCodeFromResources("ResolveComReference.CannotFindWrapperForTypeLib", referenceInfo.taskItem.ItemSpec); } return false; } else { bool successfullyResolved = !String.IsNullOrEmpty(referenceInfo.referencePathItem.ItemSpec); referencePathItem = referenceInfo.referencePathItem; return successfullyResolved; } }
/// <summary> /// Resolves the COM reference, and adds it to the appropriate item list. /// </summary> /// <param name="projectRefInfo"></param> /// <param name="resolvedReferenceList"></param> /// <param name="moduleList"></param> /// <returns></returns> private bool ResolveReferenceAndAddToList ( ComDependencyWalker dependencyWalker, ComReferenceInfo projectRefInfo, ArrayList resolvedReferenceList, ArrayList moduleList ) { ITaskItem referencePath; if (ResolveReference(dependencyWalker, projectRefInfo, WrapperOutputDirectory, out referencePath)) { resolvedReferenceList.Add(referencePath); bool metadataFound = false; bool isolated = MetadataConversionUtilities.TryConvertItemMetadataToBool(projectRefInfo.taskItem, "Isolated", out metadataFound); if (metadataFound && isolated) { string modulePath = projectRefInfo.strippedTypeLibPath; if (modulePath != null) { ITaskItem moduleItem = new TaskItem(modulePath); moduleItem.SetMetadata("Name", projectRefInfo.taskItem.ItemSpec); moduleList.Add(moduleItem); } else { return false; } } } else { return false; } return true; }
/// <summary> /// Every ActiveX reference (aximp) requires a corresponding tlbimp reference. If the tlbimp reference is /// missing from the project file we pretend it's there to save the user some useless typing. /// </summary> internal void AddMissingTlbReferences() { var newProjectRefs = new List<ComReferenceInfo>(); foreach (ComReferenceInfo axRefInfo in allProjectRefs) { // Try to find the matching tlbimp/pia reference for each aximp reference // There is an obscured case in this algorithm: there may be more than one match. Arbitrarily chooses the first. if (ComReferenceTypes.IsAxImp(axRefInfo.taskItem.GetMetadata(ComReferenceItemMetadataNames.wrapperTool))) { bool matchingTlbRefPresent = false; foreach (ComReferenceInfo tlbRefInfo in allProjectRefs) { string tlbWrapperType = tlbRefInfo.taskItem.GetMetadata(ComReferenceItemMetadataNames.wrapperTool); if (ComReferenceTypes.IsTlbImp(tlbWrapperType) || ComReferenceTypes.IsPia(tlbWrapperType) || ComReferenceTypes.IsPiaOrTlbImp(tlbWrapperType)) { if (ComReference.AreTypeLibAttrEqual(axRefInfo.attr, tlbRefInfo.attr)) { axRefInfo.taskItem.SetMetadata(ComReferenceItemMetadataNames.tlbReferenceName, tlbRefInfo.typeLibName); // Check and demote EmbedInteropTypes to "false" for wrappers of ActiveX controls. The compilers won't embed // the ActiveX control and so will transitively turn this wrapper into a reference as well. We need to know to // make the wrapper CopyLocal=true later so switch to EmbedInteropTypes=false now. string embedInteropTypes = tlbRefInfo.taskItem.GetMetadata(ItemMetadataNames.embedInteropTypes); if (ConversionUtilities.CanConvertStringToBool(embedInteropTypes)) { if (ConversionUtilities.ConvertStringToBool(embedInteropTypes)) { if (!Silent) { Log.LogMessageFromResources(MessageImportance.High, "ResolveComReference.TreatingTlbOfActiveXAsNonEmbedded", tlbRefInfo.taskItem.ItemSpec, axRefInfo.taskItem.ItemSpec); } tlbRefInfo.taskItem.SetMetadata(ItemMetadataNames.embedInteropTypes, "false"); } } axRefInfo.primaryOfAxImpRef = tlbRefInfo; matchingTlbRefPresent = true; break; } } } // add the matching tlbimp ref if not already there if (!matchingTlbRefPresent) { if (!Silent) { Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.AddingMissingTlbReference", axRefInfo.taskItem.ItemSpec); } ComReferenceInfo newTlbRef = new ComReferenceInfo(axRefInfo); newTlbRef.taskItem.SetMetadata(ComReferenceItemMetadataNames.wrapperTool, ComReferenceTypes.primaryortlbimp); newTlbRef.taskItem.SetMetadata(ItemMetadataNames.embedInteropTypes, "false"); axRefInfo.primaryOfAxImpRef = newTlbRef; newProjectRefs.Add(newTlbRef); axRefInfo.taskItem.SetMetadata(ComReferenceItemMetadataNames.tlbReferenceName, newTlbRef.typeLibName); } } } foreach (ComReferenceInfo refInfo in newProjectRefs) { allProjectRefs.Add(refInfo); } }
internal bool IsExistingDependencyReference(System.Runtime.InteropServices.ComTypes.TYPELIBATTR typeLibAttr, out ComReferenceInfo referenceInfo) { foreach (ComReferenceInfo info in this.allDependencyRefs) { if (ComReference.AreTypeLibAttrEqual(info.attr, typeLibAttr)) { referenceInfo = info; return true; } } referenceInfo = null; return false; }
/// <summary> /// Helper function - resolves an ActiveX reference given the type library attributes. /// </summary> /// <param name="referenceInfo">Information about the reference to be resolved</param> /// <param name="outputDirectory">Directory the interop DLL should be written to</param> /// <param name="refName">Name of reference</param> /// <param name="wrapperInfo">Information about wrapper locations</param> /// <returns>True if the reference was already found or successfully generated, false otherwise.</returns> internal bool ResolveComReferenceAx(ComReferenceInfo referenceInfo, string outputDirectory, string refName, out ComReferenceWrapperInfo wrapperInfo) { wrapperInfo = null; string typeLibKey = ComReference.UniqueKeyFromTypeLibAttr(referenceInfo.attr); // look in the Ax cache first if (_cacheAx.ContainsKey(typeLibKey)) { wrapperInfo = (ComReferenceWrapperInfo)_cacheAx[typeLibKey]; return true; } try { // not in the cache? see if anyone was kind enough to generate it for us AxReference reference = new AxReference(Log, Silent, this, referenceInfo, refName, outputDirectory, DelaySign, KeyFile, KeyContainer, IncludeVersionInInteropName, _aximpPath, BuildEngine, EnvironmentVariables); // wrapper doesn't exist or needs regeneration? generate it then if (!reference.FindExistingWrapper(out wrapperInfo, _timestampCache[referenceInfo.strippedTypeLibPath])) { if (!reference.GenerateWrapper(out wrapperInfo)) return false; } // if found or successfully generated, cache it. _cacheAx.Add(typeLibKey, wrapperInfo); } catch (Exception e) when (ExceptionHandling.IsIoRelatedException(e)) { return false; } return true; }
private void ConvertFileReferencesToComReferenceInfo(List<ComReferenceInfo> projectRefs, ITaskItem[] tlbFiles) { int num = (tlbFiles == null) ? 0 : tlbFiles.GetLength(0); for (int i = 0; i < num; i++) { string itemSpec = tlbFiles[i].ItemSpec; if (!Path.IsPathRooted(itemSpec)) { itemSpec = Path.Combine(Directory.GetCurrentDirectory(), itemSpec); } ComReferenceInfo item = new ComReferenceInfo(); try { if (item.InitializeWithPath(base.Log, itemSpec, tlbFiles[i], this.TargetProcessorArchitecture)) { projectRefs.Add(item); } else { item.ReleaseTypeLibPtr(); } } catch (COMException exception) { base.Log.LogWarningWithCodeFromResources("ResolveComReference.CannotLoadTypeLibItemSpec", new object[] { tlbFiles[i].ItemSpec, exception.Message }); item.ReleaseTypeLibPtr(); } } }
internal bool IsExistingProjectReference(System.Runtime.InteropServices.ComTypes.TYPELIBATTR typeLibAttr, string neededRefType, out ComReferenceInfo referenceInfo) { for (int i = 0; i < 3; i++) { if ((((i == 0) && (ComReferenceTypes.IsPia(neededRefType) || (neededRefType == null))) || ((i == 1) && (ComReferenceTypes.IsTlbImp(neededRefType) || (neededRefType == null)))) || ((i == 2) && ComReferenceTypes.IsAxImp(neededRefType))) { foreach (ComReferenceInfo info in this.allProjectRefs) { string metadata = info.taskItem.GetMetadata("WrapperTool"); if (((((i == 0) && ComReferenceTypes.IsPia(metadata)) || ((i == 1) && ComReferenceTypes.IsTlbImp(metadata))) || ((i == 2) && ComReferenceTypes.IsAxImp(metadata))) && ComReference.AreTypeLibAttrEqual(info.attr, typeLibAttr)) { referenceInfo = info; return true; } } } } referenceInfo = null; return false; }
/// <summary> /// internal constructor /// </summary> /// <param name="taskLoggingHelper">task logger instance used for logging</param> /// <param name="resolverCallback">callback interface for resolving dependent COM refs/NET assemblies</param> /// <param name="referenceInfo">cached reference information (typelib pointer, original task item, typelib name etc.)</param> /// <param name="itemName">reference name (for better logging experience)</param> /// <param name="outputDirectory">directory we should write the wrapper to</param> /// <param name="delaySign">delay sign wrappers?</param> /// <param name="keyFile">file containing public/private keys</param> /// <param name="keyContainer">container name for public/private keys</param> /// <param name="executeAsTool">True if GenerateWrapper() should generate the wrapper out-of-proc using aximp.exe</param> /// <param name="sdkToolsPath">Path to the SDK tools directory where aximp.exe can be found</param> /// <param name="buildEngine">BuildEngine of parent task; needed for logging purposes when generating wrapper out-of-proc</param> internal AxReference(TaskLoggingHelper taskLoggingHelper, bool silent, IComReferenceResolver resolverCallback, ComReferenceInfo referenceInfo, string itemName, string outputDirectory, bool delaySign, string keyFile, string keyContainer, bool includeTypeLibVersionInName, string sdkToolsPath, IBuildEngine buildEngine, string[] environmentVariables) : base(taskLoggingHelper, silent, resolverCallback, referenceInfo, itemName, outputDirectory, delaySign, keyFile, keyContainer, includeTypeLibVersionInName, true /* always execute as tool */, sdkToolsPath, buildEngine, environmentVariables) { // do nothing }
bool IComReferenceResolver.ResolveComClassicReference(System.Runtime.InteropServices.ComTypes.TYPELIBATTR typeLibAttr, string outputDirectory, string wrapperType, string refName, out ComReferenceWrapperInfo wrapperInfo) { ComReferenceInfo info; bool topLevelRef = false; wrapperInfo = null; System.Runtime.InteropServices.ComTypes.TYPELIBATTR typelibattr = typeLibAttr; if (ComReference.RemapAdoTypeLib(base.Log, ref typeLibAttr)) { base.Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.RemappingAdoTypeLib", new object[] { typelibattr.wMajorVerNum, typelibattr.wMinorVerNum }); } if (this.IsExistingProjectReference(typeLibAttr, wrapperType, out info)) { topLevelRef = true; wrapperType = info.taskItem.GetMetadata("WrapperTool"); } else if (this.IsExistingDependencyReference(typeLibAttr, out info)) { if ((wrapperType == null) || ComReferenceTypes.IsPiaOrTlbImp(wrapperType)) { string key = ComReference.UniqueKeyFromTypeLibAttr(typeLibAttr); if (this.cachePia.ContainsKey(key)) { wrapperType = "primary"; } else if (this.cacheTlb.ContainsKey(key)) { wrapperType = "tlbimp"; } } } else { try { info = new ComReferenceInfo(); if (info.InitializeWithTypeLibAttrs(base.Log, typeLibAttr, null, this.TargetProcessorArchitecture)) { this.allDependencyRefs.Add(info); } else { info.ReleaseTypeLibPtr(); return false; } } catch (COMException exception) { base.Log.LogWarningWithCodeFromResources("ResolveComReference.CannotLoadTypeLib", new object[] { typeLibAttr.guid, typeLibAttr.wMajorVerNum.ToString(CultureInfo.InvariantCulture), typeLibAttr.wMinorVerNum.ToString(CultureInfo.InvariantCulture), exception.Message }); info.ReleaseTypeLibPtr(); return false; } } if (refName == null) { refName = info.typeLibName; } return this.ResolveComClassicReference(info, outputDirectory, wrapperType, refName, topLevelRef, info.dependentWrapperPaths, out wrapperInfo); }
internal ComReference(TaskLoggingHelper taskLoggingHelper, ComReferenceInfo referenceInfo, string itemName) { this.referenceInfo = referenceInfo; this.itemName = itemName; this.log = taskLoggingHelper; }
internal bool ResolveComReferenceAx(ComReferenceInfo referenceInfo, string outputDirectory, string refName, out ComReferenceWrapperInfo wrapperInfo) { wrapperInfo = null; string key = ComReference.UniqueKeyFromTypeLibAttr(referenceInfo.attr); if (this.cacheAx.ContainsKey(key)) { wrapperInfo = (ComReferenceWrapperInfo) this.cacheAx[key]; return true; } try { AxReference reference = new AxReference(base.Log, this, referenceInfo, refName, outputDirectory, this.DelaySign, this.KeyFile, this.KeyContainer, this.IncludeVersionInInteropName, this.aximpPath, base.BuildEngine, this.EnvironmentVariables); if (!reference.FindExistingWrapper(out wrapperInfo, this.timestampCache[referenceInfo.typeLibPath]) && !reference.GenerateWrapper(out wrapperInfo)) { return false; } this.cacheAx.Add(key, wrapperInfo); } catch (Exception exception) { if (Microsoft.Build.Shared.ExceptionHandling.NotExpectedException(exception)) { throw; } return false; } return true; }
internal PiaReference(TaskLoggingHelper taskLoggingHelper, ComReferenceInfo referenceInfo, string itemName) : base(taskLoggingHelper, referenceInfo, itemName) { }
internal bool ResolveComReferenceTlb(ComReferenceInfo referenceInfo, string outputDirectory, string refName, bool topLevelRef, List<string> dependencyPaths, out ComReferenceWrapperInfo wrapperInfo) { wrapperInfo = null; string key = ComReference.UniqueKeyFromTypeLibAttr(referenceInfo.attr); if (this.cacheTlb.ContainsKey(key)) { wrapperInfo = (ComReferenceWrapperInfo) this.cacheTlb[key]; return true; } bool hasTemporaryWrapper = false; if (!topLevelRef) { foreach (ComReferenceInfo info in this.allProjectRefs) { if ((ComReferenceTypes.IsTlbImp(info.taskItem.GetMetadata("WrapperTool")) && !ComReference.AreTypeLibAttrEqual(referenceInfo.attr, info.attr)) && (string.Compare(referenceInfo.typeLibName, info.typeLibName, StringComparison.OrdinalIgnoreCase) == 0)) { hasTemporaryWrapper = true; } } } try { List<string> referenceFiles = new List<string>(this.GetResolvedAssemblyReferenceItemSpecs()); if (dependencyPaths != null) { referenceFiles.AddRange(dependencyPaths); } TlbReference reference = new TlbReference(base.Log, this, referenceFiles, referenceInfo, refName, outputDirectory, hasTemporaryWrapper, this.DelaySign, this.KeyFile, this.KeyContainer, this.NoClassMembers, this.TargetProcessorArchitecture, this.IncludeVersionInInteropName, this.ExecuteAsTool, this.tlbimpPath, base.BuildEngine, this.EnvironmentVariables); if (!reference.FindExistingWrapper(out wrapperInfo, this.timestampCache[referenceInfo.typeLibPath]) && !reference.GenerateWrapper(out wrapperInfo)) { return false; } this.cacheTlb.Add(key, wrapperInfo); } catch (Exception exception) { if (Microsoft.Build.Shared.ExceptionHandling.NotExpectedException(exception)) { throw; } return false; } return true; }
/// <summary> /// internal constructor /// </summary> /// <param name="taskLoggingHelper">task logger instance used for logging</param> /// <param name="silent">true if this task should log only errors, no warnings or messages; false otherwise</param> /// <param name="resolverCallback">callback interface for resolving dependent COM refs/NET assemblies</param> /// <param name="referenceInfo">cached reference information (typelib pointer, original task item, typelib name etc.)</param> /// <param name="itemName">reference name (for better logging experience)</param> /// <param name="outputDirectory">directory we should write the wrapper to</param> /// <param name="delaySign">delay sign wrappers?</param> /// <param name="keyFile">file containing public/private keys</param> /// <param name="keyContainer">container name for public/private keys</param> /// <param name="includeTypeLibVersionInName">True if the interop name should include the typelib's version</param> /// <param name="executeAsTool">True if GenerateWrapper() should generate the wrapper out-of-proc using aximp.exe or tlbimp.exe</param> /// <param name="toolPath">Path to the SDK tools directory where aximp.exe or tlbimp.exe can be found</param> /// <param name="buildEngine">BuildEngine of parent task; needed for logging purposes when generating wrapper out-of-proc</param> /// <param name="environmentVariables">Array of equals-separated pairs of environment variables that should be passed to the spawned executable, in addition to (or selectively overriding) the regular environment block.</param> internal AxTlbBaseReference(TaskLoggingHelper taskLoggingHelper, bool silent, IComReferenceResolver resolverCallback, ComReferenceInfo referenceInfo, string itemName, string outputDirectory, bool delaySign, string keyFile, string keyContainer, bool includeTypeLibVersionInName, bool executeAsTool, string toolPath, IBuildEngine buildEngine, string[] environmentVariables) : base(taskLoggingHelper, silent, referenceInfo, itemName) { ResolverCallback = resolverCallback; OutputDirectory = outputDirectory; IncludeTypeLibVersionInName = includeTypeLibVersionInName; BuildEngine = buildEngine; EnvironmentVariables = environmentVariables; DelaySign = delaySign; ExecuteAsTool = executeAsTool; KeyFile = keyFile; KeyContainer = keyContainer; ToolPath = toolPath; }
private bool ResolveReferenceAndAddToList(ComDependencyWalker dependencyWalker, ComReferenceInfo projectRefInfo, ArrayList resolvedReferenceList, ArrayList moduleList) { ITaskItem item; if (!this.ResolveReference(dependencyWalker, projectRefInfo, this.WrapperOutputDirectory, out item)) { return false; } resolvedReferenceList.Add(item); bool metadataFound = false; bool flag2 = MetadataConversionUtilities.TryConvertItemMetadataToBool(projectRefInfo.taskItem, "Isolated", out metadataFound); if (metadataFound && flag2) { string typeLibPath = projectRefInfo.typeLibPath; if (typeLibPath == null) { return false; } ITaskItem item2 = new TaskItem(typeLibPath); item2.SetMetadata("Name", projectRefInfo.taskItem.ItemSpec); moduleList.Add(item2); } return true; }
/// <summary> /// internal constructor /// </summary> /// <param name="taskLoggingHelper">task logger instance used for logging</param> /// <param name="resolverCallback">callback interface for resolving dependent COM refs/NET assemblies</param> /// <param name="referenceInfo">cached reference information (typelib pointer, original task item, typelib name etc.)</param> /// <param name="itemName">reference name (for better logging experience)</param> /// <param name="outputDirectory">directory we should write the wrapper to</param> /// <param name="delaySign">delay sign wrappers?</param> /// <param name="keyFile">file containing public/private keys</param> /// <param name="keyContainer">container name for public/private keys</param> /// <param name="executeAsTool">True if GenerateWrapper() should generate the wrapper out-of-proc using tlbimp.exe</param> /// <param name="sdkToolsPath">Path to the SDK tools directory where tlbimp.exe can be found</param> /// <param name="buildEngine">BuildEngine of parent task; needed for logging purposes when generating wrapper out-of-proc</param> internal TlbReference(TaskLoggingHelper taskLoggingHelper, bool silent, IComReferenceResolver resolverCallback, IEnumerable <string> referenceFiles, ComReferenceInfo referenceInfo, string itemName, string outputDirectory, bool hasTemporaryWrapper, bool delaySign, string keyFile, string keyContainer, bool noClassMembers, string targetProcessorArchitecture, bool includeTypeLibVersionInName, bool executeAsTool, string sdkToolsPath, IBuildEngine buildEngine, string[] environmentVariables) : base(taskLoggingHelper, silent, resolverCallback, referenceInfo, itemName, outputDirectory, delaySign, keyFile, keyContainer, includeTypeLibVersionInName, executeAsTool, sdkToolsPath, buildEngine, environmentVariables) { _hasTemporaryWrapper = hasTemporaryWrapper; _noClassMembers = noClassMembers; _targetProcessorArchitecture = targetProcessorArchitecture; _referenceFiles = referenceFiles; }
/// <summary> /// Helper function for creating a ComReferenceInfo object using an existing TaskInfo object and /// typelib name/path. The type lib pointer will obviously not be initialized, so this object cannot /// be used in any code that uses it. /// </summary> private ComReferenceInfo CreateComReferenceInfo(ITaskItem taskItem, string typeLibName, string typeLibPath) { ComReferenceInfo referenceInfo = new ComReferenceInfo(); referenceInfo.taskItem = taskItem; referenceInfo.attr = ResolveComReference.TaskItemToTypeLibAttr(taskItem); referenceInfo.typeLibName = typeLibName; referenceInfo.fullTypeLibPath = typeLibPath; referenceInfo.strippedTypeLibPath = typeLibPath; referenceInfo.typeLibPointer = null; return referenceInfo; }
/// <summary> /// Create a few test references for unit tests /// </summary> private void CreateTestReferences( out ComReferenceInfo axRefInfo, out ComReferenceInfo tlbRefInfo, out ComReferenceInfo piaRefInfo, out TYPELIBATTR axAttr, out TYPELIBATTR tlbAttr, out TYPELIBATTR piaAttr, out TYPELIBATTR notInProjectAttr) { // doing my part to deplete the worldwide guid reserves... Guid axGuid = Guid.NewGuid(); Guid tlbGuid = Guid.NewGuid(); Guid piaGuid = Guid.NewGuid(); // create reference task items TaskItem axTaskItem = CreateComReferenceTaskItem("axref", axGuid.ToString(), "1", "0", "1033", ComReferenceTypes.aximp); TaskItem tlbTaskItem = CreateComReferenceTaskItem("tlbref", tlbGuid.ToString(), "5", "1", "0", ComReferenceTypes.tlbimp); TaskItem piaTaskItem = CreateComReferenceTaskItem("piaref", piaGuid.ToString(), "999", "444", "123", ComReferenceTypes.primary); // create reference infos axRefInfo = CreateComReferenceInfo(axTaskItem, "AxRefLibName", "AxRefLibPath"); tlbRefInfo = CreateComReferenceInfo(tlbTaskItem, "TlbRefLibName", "TlbRefLibPath"); piaRefInfo = CreateComReferenceInfo(piaTaskItem, "PiaRefLibName", "PiaRefLibPath"); // get the references' typelib attributes axAttr = ResolveComReference.TaskItemToTypeLibAttr(axTaskItem); tlbAttr = ResolveComReference.TaskItemToTypeLibAttr(tlbTaskItem); piaAttr = ResolveComReference.TaskItemToTypeLibAttr(piaTaskItem); // create typelib attributes not matching any of the project refs notInProjectAttr = new TYPELIBATTR(); notInProjectAttr.guid = tlbGuid; notInProjectAttr.wMajorVerNum = 5; notInProjectAttr.wMinorVerNum = 1; notInProjectAttr.lcid = 1033; }