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> /// Helper function - resolves a regular tlb COM classic 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="topLevelRef">True if this is a top-level 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 ResolveComReferenceTlb(ComReferenceInfo referenceInfo, string outputDirectory, string refName, bool topLevelRef, List<string> dependencyPaths, out ComReferenceWrapperInfo wrapperInfo) { wrapperInfo = null; string typeLibKey = ComReference.UniqueKeyFromTypeLibAttr(referenceInfo.attr); // look in the TLB cache first if (_cacheTlb.ContainsKey(typeLibKey)) { wrapperInfo = (ComReferenceWrapperInfo)_cacheTlb[typeLibKey]; return true; } // is it a temporary wrapper? bool isTemporary = false; // no top level (included in the project) refs can have temporary wrappers if (!topLevelRef) { // wrapper is temporary if there's a top level tlb reference with the same typelib name, but different attributes foreach (ComReferenceInfo projectRefInfo in allProjectRefs) { if (ComReferenceTypes.IsTlbImp(projectRefInfo.taskItem.GetMetadata(ComReferenceItemMetadataNames.wrapperTool))) { // conflicting typelib names for different typelibs? generate a temporary wrapper if (!ComReference.AreTypeLibAttrEqual(referenceInfo.attr, projectRefInfo.attr) && String.Compare(referenceInfo.typeLibName, projectRefInfo.typeLibName, StringComparison.OrdinalIgnoreCase) == 0) { isTemporary = true; } } } } try { List<string> referencePaths = new List<string>(GetResolvedAssemblyReferenceItemSpecs()); if (dependencyPaths != null) { referencePaths.AddRange(dependencyPaths); } // not in the cache? see if anyone was kind enough to generate it for us TlbReference reference = new TlbReference(Log, Silent, this, referencePaths, referenceInfo, refName, outputDirectory, isTemporary, DelaySign, KeyFile, KeyContainer, this.NoClassMembers, this.TargetProcessorArchitecture, IncludeVersionInInteropName, ExecuteAsTool, _tlbimpPath, 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. _cacheTlb.Add(typeLibKey, wrapperInfo); } catch (Exception e) when (ExceptionHandling.IsIoRelatedException(e)) { return false; } return true; }