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; }
private void AssertDependenciesContainTypeLib(string message, TYPELIBATTR[] dependencies, MockTypeLib typeLib, bool contains) { bool dependencyExists = false; foreach (TYPELIBATTR attr in dependencies) { if (attr.guid == typeLib.Attributes.guid) { dependencyExists = true; break; } } Assert.Equal(contains, dependencyExists); }
/* * Method: RemapAdoTypeLib * * Tries to remap an ADO type library to ADO 2.7. If the type library passed in is an older ADO tlb, * then remap it to ADO 2.7 if it's registered on the machine (!). Otherwise don't modify the typelib. * Returns true if the type library passed in was successfully remapped. */ internal static bool RemapAdoTypeLib(TaskLoggingHelper log, bool silent, ref TYPELIBATTR typeLibAttr) { // we only care about ADO 2.0, 2.1, 2.5 or 2.6 here. if (typeLibAttr.wMajorVerNum == 2) { if ((typeLibAttr.wMinorVerNum == 0 && typeLibAttr.guid == s_guidADO20) || (typeLibAttr.wMinorVerNum == 1 && typeLibAttr.guid == s_guidADO21) || (typeLibAttr.wMinorVerNum == 5 && typeLibAttr.guid == s_guidADO25) || (typeLibAttr.wMinorVerNum == 6 && typeLibAttr.guid == s_guidADO26)) { // see if ADO 2.7 is registered. if (!Ado27Installed) { if (!silent) { // it's not registered. Don't change the original typelib then. log.LogWarningWithCodeFromResources("ResolveComReference.FailedToRemapAdoTypeLib", typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, Ado27ErrorMessage); } return false; } typeLibAttr.guid = s_guidADO27; typeLibAttr.wMajorVerNum = 2; typeLibAttr.wMinorVerNum = 7; typeLibAttr.lcid = 0; return true; } } return false; }
internal System.Runtime.InteropServices.ComTypes.TYPELIBATTR[] GetDependencies() { System.Runtime.InteropServices.ComTypes.TYPELIBATTR[] array = new System.Runtime.InteropServices.ComTypes.TYPELIBATTR[this.dependencies.Keys.Count]; this.dependencies.Keys.CopyTo(array, 0); return array; }
/* * Method: GetTypeLibNameForTypeLibAttrs * * Gets the name of given type library. */ internal static bool GetTypeLibNameForTypeLibAttrs(TaskLoggingHelper log, bool silent, TYPELIBATTR typeLibAttr, out string typeLibName) { typeLibName = ""; ITypeLib typeLib = null; try { // load our type library try { TYPELIBATTR attr = typeLibAttr; typeLib = (ITypeLib)NativeMethods.LoadRegTypeLib(ref attr.guid, attr.wMajorVerNum, attr.wMinorVerNum, attr.lcid); } catch (COMException ex) { if (!silent) { log.LogWarningWithCodeFromResources("ResolveComReference.CannotLoadTypeLib", typeLibAttr.guid, typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, ex.Message); } return false; } string typeLibId = log.FormatResourceString("ResolveComReference.TypeLibAttrId", typeLibAttr.guid.ToString(), typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum); return GetTypeLibNameForITypeLib(log, silent, typeLib, typeLibId, out typeLibName); } finally { if (typeLib != null) Marshal.ReleaseComObject(typeLib); } }
/* * Method: GetPathOfTypeLib * * Gets the type lib path for given type lib attributes (reused almost verbatim from vsdesigner utils code) * NOTE: If there's a typelib number at the end of the path, does NOT strip it. */ internal static bool GetPathOfTypeLib(TaskLoggingHelper log, bool silent, ref TYPELIBATTR typeLibAttr, out string typeLibPath) { // Get which file the type library resides in. If the appropriate // file cannot be found then a blank string is returned. typeLibPath = ""; try { // Get the path from the registry // This call has known issues. See http://msdn.microsoft.com/en-us/library/ms221436.aspx for the method and // here for the fix http://support.microsoft.com/kb/982110. Most users from Win7 or Win2008R2 should have already received this post Win7SP1. // In Summary: The issue is about calls to The QueryPathOfRegTypeLib function not returning the correct path for a 32-bit version of a // registered type library in a 64-bit edition of Windows 7 or in Windows Server 2008 R2. It either returns the 64bit path or null. typeLibPath = NativeMethods.QueryPathOfRegTypeLib(ref typeLibAttr.guid, typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, typeLibAttr.lcid); typeLibPath = Environment.ExpandEnvironmentVariables(typeLibPath); } catch (COMException ex) { if (!silent) { log.LogWarningWithCodeFromResources("ResolveComReference.CannotGetPathForTypeLib", typeLibAttr.guid, typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, ex.Message); } return false; } if (typeLibPath != null && typeLibPath.Length > 0) { // We have to check for NULL here because QueryPathOfRegTypeLib() returns // a BSTR with a NULL character appended to it. if (typeLibPath[typeLibPath.Length - 1] == '\0') { typeLibPath = typeLibPath.Substring(0, typeLibPath.Length - 1); } } if (typeLibPath != null && typeLibPath.Length > 0) { return true; } else { if (!silent) { log.LogWarningWithCodeFromResources("ResolveComReference.CannotGetPathForTypeLib", typeLibAttr.guid, typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, ""); } return false; } }
/* * Method: AreTypeLibAttrEqual * * Compares two TYPELIBATTR structures */ internal static bool AreTypeLibAttrEqual(TYPELIBATTR attr1, TYPELIBATTR attr2) { return attr1.wMajorVerNum == attr2.wMajorVerNum && attr1.wMinorVerNum == attr2.wMinorVerNum && attr1.lcid == attr2.lcid && attr1.guid == attr2.guid; }
/// <summary> /// Helper method for retrieving type lib attributes for the given type lib /// </summary> /// <param name="typeLib"></param> /// <param name="typeLibAttr"></param> /// <returns></returns> internal static void GetTypeLibAttrForTypeLib(ref ITypeLib typeLib, out TYPELIBATTR typeLibAttr) { IntPtr pAttrs = IntPtr.Zero; typeLib.GetLibAttr(out pAttrs); // GetLibAttr should never return null, this is just to be safe if (pAttrs == IntPtr.Zero) { throw new COMException( ResourceUtilities.FormatResourceString("ResolveComReference.CannotGetTypeLibAttrForTypeLib")); } try { typeLibAttr = (TYPELIBATTR)Marshal.PtrToStructure(pAttrs, typeof(TYPELIBATTR)); } finally { typeLib.ReleaseTLibAttr(pAttrs); } }
// Create a ComReferenceNode via a string to a TLB internal ComReferenceNode(ProjectNode root, string filePath) : base(root) { object otypeLib = null; ComTypes.ITypeLib typeLib = null; IntPtr ptrToLibAttr = IntPtr.Zero; try { LoadTypeLibEx( filePath, RegKind.RegKind_None, out otypeLib ); typeLib = (ComTypes.ITypeLib)otypeLib; if (typeLib == null) { throw new ArgumentException(); } ComTypes.TYPELIBATTR typeAttr = new ComTypes.TYPELIBATTR(); typeLib.GetLibAttr(out ptrToLibAttr); typeAttr = (ComTypes.TYPELIBATTR)Marshal.PtrToStructure(ptrToLibAttr, typeAttr.GetType()); // Initialize state this.typeGuid = typeAttr.guid; this.majorVersionNumber = typeAttr.wMajorVerNum.ToString(CultureInfo.InvariantCulture); this.minorVersionNumber = typeAttr.wMinorVerNum.ToString(CultureInfo.InvariantCulture); this.lcid = typeAttr.lcid; // Check to see if the COM object actually exists. this.SetInstalledFilePath(); // If the value cannot be set throw. if (String.IsNullOrEmpty(this.installedFilePath)) { var message = string.Format(SR.GetString(SR.ReferenceCouldNotBeAdded, CultureInfo.CurrentUICulture), filePath); throw new InvalidOperationException(message); } } finally { if (typeLib != null) typeLib.ReleaseTLibAttr(ptrToLibAttr); } }
internal System.Runtime.InteropServices.ComTypes.TYPELIBATTR[] GetDependencies() { System.Runtime.InteropServices.ComTypes.TYPELIBATTR[] array = new System.Runtime.InteropServices.ComTypes.TYPELIBATTR[this.dependencies.Keys.Count]; this.dependencies.Keys.CopyTo(array, 0); return(array); }
/// <summary> /// Register a COM type library /// </summary> /// <param name="path"></param> private void RegisterTypelib(string path) { IntPtr Typelib = new IntPtr(0); int error = 0; // Load typelib int result = LoadTypeLib(path, ref Typelib); error = Marshal.GetLastWin32Error(); if (error != 0 || result != 0) { int win32error = (error != 0) ? error : result; throw new BuildException(string.Format(CultureInfo.InvariantCulture, "Error loading typelib '{0}' ({1}: {2}).", path, win32error, GetWin32ErrorMessage(win32error)), Location); } try { if (Unregister) { #if NET_2_0 ITypeLib typeLib = null; #else UCOMITypeLib typeLib = null; #endif try { #if NET_2_0 typeLib = (ITypeLib)Marshal.GetTypedObjectForIUnknown( Typelib, typeof(ITypeLib)); #else typeLib = (UCOMITypeLib)Marshal.GetTypedObjectForIUnknown( Typelib, typeof(UCOMITypeLib)); #endif // check for for win32 error error = Marshal.GetLastWin32Error(); if (error != 0) { throw new BuildException(string.Format(CultureInfo.InvariantCulture, "Error retrieving information from typelib '{0}' ({1}: {2}).", path, error, GetWin32ErrorMessage(error)), Location); } IntPtr libAttrPtr = new IntPtr(0); typeLib.GetLibAttr(out libAttrPtr); TYPELIBATTR typeLibAttr = (TYPELIBATTR) Marshal.PtrToStructure(libAttrPtr, typeof(TYPELIBATTR)); // unregister type library UnRegisterTypeLib(ref typeLibAttr.guid, typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, typeLibAttr.lcid, typeLibAttr.syskind); // check for for win32 error error = Marshal.GetLastWin32Error(); // release the TYPELIBATTR typeLib.ReleaseTLibAttr(libAttrPtr); if (error != 0) { // signal error throw new BuildException(string.Format(CultureInfo.InvariantCulture, "Typelib '{0}' could not be unregistered ({1}: {2}).", path, error, GetWin32ErrorMessage(error)), Location); } } finally { if (typeLib != null) { Marshal.ReleaseComObject(typeLib); } } } else { //Perform registration RegisterTypeLib(Typelib, path, null); error = Marshal.GetLastWin32Error(); if (error != 0) { throw new BuildException(string.Format(CultureInfo.InvariantCulture, "Error registering typelib '{0}' ({1}: {2}).", path, error, GetWin32ErrorMessage(error)), Location); } } } finally { Marshal.Release(Typelib); } }
private void AssertDependenciesContainTypeLib(TYPELIBATTR[] dependencies, MockTypeLib typeLib, bool contains) { AssertDependenciesContainTypeLib("", dependencies, typeLib, contains); }
/* * Method: TaskItemToTypeLibAttr * * Gets the TLIBATTR structure based on the reference we have. * Sets guid, versions major & minor, lcid. */ internal static TYPELIBATTR TaskItemToTypeLibAttr(ITaskItem taskItem) { TYPELIBATTR attr = new TYPELIBATTR(); // copy metadata from Reference to our TYPELIBATTR attr.guid = new Guid(taskItem.GetMetadata(ComReferenceItemMetadataNames.guid)); attr.wMajorVerNum = short.Parse(taskItem.GetMetadata(ComReferenceItemMetadataNames.versionMajor), NumberStyles.Integer, CultureInfo.InvariantCulture); attr.wMinorVerNum = short.Parse(taskItem.GetMetadata(ComReferenceItemMetadataNames.versionMinor), NumberStyles.Integer, CultureInfo.InvariantCulture); attr.lcid = int.Parse(taskItem.GetMetadata(ComReferenceItemMetadataNames.lcid), NumberStyles.Integer, CultureInfo.InvariantCulture); return attr; }
/* * Method: ResolveComClassicReference * * Resolves a COM classic reference given the type library attributes and the type of wrapper to use. * If wrapper type is not specified, this method will first look for an existing reference in the project, * fall back to looking for a PIA and finally try to generate a regular tlbimp wrapper. * * This is the method available for references to call back to resolve their dependencies */ bool IComReferenceResolver.ResolveComClassicReference(TYPELIBATTR typeLibAttr, string outputDirectory, string wrapperType, string refName, out ComReferenceWrapperInfo wrapperInfo) { // does this reference exist in the project or is it a dependency? bool topLevelRef = false; wrapperInfo = null; // remap the type lib to ADO 2.7 if necessary TYPELIBATTR oldAttr = typeLibAttr; if (ComReference.RemapAdoTypeLib(Log, Silent, ref typeLibAttr) && !Silent) { // if successfully remapped the reference to ADO 2.7, notify the user Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.RemappingAdoTypeLib", oldAttr.wMajorVerNum, oldAttr.wMinorVerNum); } ComReferenceInfo referenceInfo; // find an existing ref in the project (taking the desired wrapperType into account, if any) if (IsExistingProjectReference(typeLibAttr, wrapperType, out referenceInfo)) { // IsExistingProjectReference should not return null... Debug.Assert(referenceInfo != null, "IsExistingProjectReference should not return null"); topLevelRef = true; wrapperType = referenceInfo.taskItem.GetMetadata(ComReferenceItemMetadataNames.wrapperTool); } // was this dependency already processed? else if (IsExistingDependencyReference(typeLibAttr, out referenceInfo)) { Debug.Assert(referenceInfo != null, "IsExistingDependencyReference should not return null"); // we've seen this dependency before, so we should know what its wrapper type is. if (wrapperType == null || ComReferenceTypes.IsPiaOrTlbImp(wrapperType)) { string typeLibKey = ComReference.UniqueKeyFromTypeLibAttr(typeLibAttr); if (_cachePia.ContainsKey(typeLibKey)) { wrapperType = ComReferenceTypes.primary; } else if (_cacheTlb.ContainsKey(typeLibKey)) { wrapperType = ComReferenceTypes.tlbimp; } } } // if not found anywhere, create a new ComReferenceInfo object and resolve it. else { try { referenceInfo = new ComReferenceInfo(); if (referenceInfo.InitializeWithTypeLibAttrs(Log, Silent, typeLibAttr, null, this.TargetProcessorArchitecture)) { allDependencyRefs.Add(referenceInfo); } else { referenceInfo.ReleaseTypeLibPtr(); return false; } } catch (COMException ex) { if (!Silent) { Log.LogWarningWithCodeFromResources("ResolveComReference.CannotLoadTypeLib", typeLibAttr.guid, typeLibAttr.wMajorVerNum.ToString(CultureInfo.InvariantCulture), typeLibAttr.wMinorVerNum.ToString(CultureInfo.InvariantCulture), ex.Message); } referenceInfo.ReleaseTypeLibPtr(); // can't resolve an unregistered and unknown dependency, so return false return false; } } // if we don't have the reference name, use the typelib name if (refName == null) { refName = referenceInfo.typeLibName; } return ResolveComClassicReference(referenceInfo, outputDirectory, wrapperType, refName, topLevelRef, referenceInfo.dependentWrapperPaths, out wrapperInfo); }
/* * Method: IsExistingDependencyReference * * If given typelib attributes are already a dependency reference (that is, was already * processed) return that reference. */ internal bool IsExistingDependencyReference(TYPELIBATTR typeLibAttr, out ComReferenceInfo referenceInfo) { foreach (ComReferenceInfo dependencyRefInfo in allDependencyRefs) { // found it? return the existing reference if (ComReference.AreTypeLibAttrEqual(dependencyRefInfo.attr, typeLibAttr)) { referenceInfo = dependencyRefInfo; return true; } } referenceInfo = null; return false; }
/* * Method: IsExistingProjectReference * * If given typelib attributes are already a project reference, return that reference. */ internal bool IsExistingProjectReference(TYPELIBATTR typeLibAttr, string neededRefType, out ComReferenceInfo referenceInfo) { for (int pass = 0; pass < 3; pass++) { // First PIAs, then tlbimps, then aximp // Only execute each pass if the needed ref type matches or is null // Important: the condition for Ax wrapper is different, since we don't want to find Ax references // for unknown wrapper types - "unknown" wrapper means we're only looking for a tlbimp or a primary reference if ((pass == 0 && (ComReferenceTypes.IsPia(neededRefType) || neededRefType == null)) || (pass == 1 && (ComReferenceTypes.IsTlbImp(neededRefType) || neededRefType == null)) || (pass == 2 && (ComReferenceTypes.IsAxImp(neededRefType)))) { foreach (ComReferenceInfo projectRefInfo in allProjectRefs) { string wrapperType = projectRefInfo.taskItem.GetMetadata(ComReferenceItemMetadataNames.wrapperTool); // First PIAs, then tlbimps, then aximp if ((pass == 0 && ComReferenceTypes.IsPia(wrapperType)) || (pass == 1 && ComReferenceTypes.IsTlbImp(wrapperType)) || (pass == 2 && ComReferenceTypes.IsAxImp(wrapperType))) { // found it? return the existing reference if (ComReference.AreTypeLibAttrEqual(projectRefInfo.attr, typeLibAttr)) { referenceInfo = projectRefInfo; return true; } } } } } referenceInfo = null; return false; }
static void Main(string[] args) { Usage(); if (args.Length != 1) { Console.WriteLine("Invalid args"); return; } // Download repo var repoZIP = "TLB_REPO.zip"; var outputRepoPath = "."; if (!File.Exists(repoZIP)) { Console.WriteLine("Downloading repo..."); ServicePointManager.Expect100Continue = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; using (var client = new WebClient()) { client.DownloadFile(TLB_REPO_URL, repoZIP); } Console.WriteLine("Extracting ..."); using (ZipFile zip = ZipFile.Read(repoZIP)) { zip.ExtractAll(outputRepoPath); } } Console.WriteLine("Loading TLB infos"); var tlbs = new List <TypeLibInfo>(); foreach (var file in Directory.GetFiles(outputRepoPath, "*.tlb", SearchOption.AllDirectories)) { ITypeLib typeLib = null; try { LoadTypeLibEx(file, RegKind.RegKind_Default, out typeLib); IntPtr ppTLibAttr; typeLib.GetLibAttr(out ppTLibAttr); TYPELIBATTR tlibattr = (TYPELIBATTR)Marshal.PtrToStructure(ppTLibAttr, typeof(TYPELIBATTR)); typeLib.ReleaseTLibAttr(ppTLibAttr); tlbs.Add( new TypeLibInfo() { File = file, GUID = tlibattr.guid.ToString("B").ToUpper(), Major = tlibattr.wMajorVerNum, Minor = tlibattr.wMinorVerNum }); } catch { } finally { if (typeLib != null) { Marshal.ReleaseComObject(typeLib); } } } var inputFile = args[0]; XDocument solution; using (var f = System.IO.File.OpenRead(inputFile)) { solution = XDocument.Load(f); } foreach (var reference in solution.Element("VBUpgradeSolution").Elements("ExternalReference")) { var guid = reference.Attribute("Guid").Value.ToUpper(); int.TryParse(reference.Attribute("MinorVersion").Value, out var minor); int.TryParse(reference.Attribute("MajorVersion").Value, out var major); var refInTlbs = tlbs.Find(x => (x.GUID == guid && x.Minor == minor && x.Major == major)); if (refInTlbs != null) { Console.WriteLine($"Mapping {reference.Attribute("FriendlyName")} using TLB {refInTlbs.File} "); reference.Attribute("AbsolutePath").Value = Path.GetFullPath(refInTlbs.File); } } solution.Save(inputFile); Console.WriteLine("Solution file updated"); }
/// <summary> /// Initialize the object with type library attributes /// </summary> /// <param name="attr"></param> /// <param name="taskItem"></param> internal bool InitializeWithTypeLibAttrs(TaskLoggingHelper log, bool silent, TYPELIBATTR tlbAttr, ITaskItem originalTaskItem, string targetProcessorArchitecture) { TYPELIBATTR remappableTlbAttr = tlbAttr; ComReference.RemapAdoTypeLib(log, silent, ref remappableTlbAttr); // for attribute references, the path is not specified, so we need to get it from the registry if (!ComReference.GetPathOfTypeLib(log, silent, ref remappableTlbAttr, out this.fullTypeLibPath)) { return false; } // Now that we have the path, we can call InitializeWithPath to get the correct TYPELIBATTR set up // and the correct ITypeLib pointer. return InitializeWithPath(log, silent, this.fullTypeLibPath, originalTaskItem, targetProcessorArchitecture); }
/* * Method: UniqueKeyFromTypeLibAttr * * Given a TYPELIBATTR structure, generates a key that can be used in hashtables to identify it. */ internal static string UniqueKeyFromTypeLibAttr(TYPELIBATTR attr) { return String.Format(CultureInfo.InvariantCulture, @"{0}|{1}.{2}|{3}", attr.guid, attr.wMajorVerNum, attr.wMinorVerNum, attr.lcid); }
/// <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; }
private bool CanSkipType(ITypeInfo typeInfo, ITypeLib typeLib, System.Runtime.InteropServices.ComTypes.TYPEATTR typeAttributes, System.Runtime.InteropServices.ComTypes.TYPELIBATTR typeLibAttributes) { if (((typeAttributes.guid == Microsoft.Build.Tasks.NativeMethods.IID_IUnknown) || (typeAttributes.guid == Microsoft.Build.Tasks.NativeMethods.IID_IDispatch)) || (((typeAttributes.guid == Microsoft.Build.Tasks.NativeMethods.IID_IDispatchEx) || (typeAttributes.guid == Microsoft.Build.Tasks.NativeMethods.IID_IEnumVariant)) || (typeAttributes.guid == Microsoft.Build.Tasks.NativeMethods.IID_ITypeInfo))) { return(true); } if (typeLibAttributes.guid == Microsoft.Build.Tasks.NativeMethods.IID_StdOle) { string str; string str2; string str3; int num; typeInfo.GetDocumentation(-1, out str, out str2, out num, out str3); if (string.CompareOrdinal(str, "GUID") == 0) { return(true); } } ITypeLib2 lib = typeLib as ITypeLib2; if (lib != null) { object obj2; lib.GetCustData(ref Microsoft.Build.Tasks.NativeMethods.GUID_ExportedFromComPlus, out obj2); string str4 = obj2 as string; if (!string.IsNullOrEmpty(str4)) { return(true); } } return(false); }