internal Assembly FindRCW(UCOMITypeLib typeLib) { if (rcwCache == null) { return(null); } IntPtr typeLibAttr = NativeMethods.InvalidIntPtr; typeLib.GetLibAttr(out typeLibAttr); try { if (typeLibAttr != NativeMethods.InvalidIntPtr) { // Marshal the returned int as a TLibAttr structure // TYPELIBATTR tlbAttr = (TYPELIBATTR)Marshal.PtrToStructure(typeLibAttr, typeof(TYPELIBATTR)); return((Assembly)rcwCache[tlbAttr.guid]); } } finally { typeLib.ReleaseTLibAttr(typeLibAttr); } return(null); }
//************************************************************************** // Helper to get a PIA from a typelib. //************************************************************************** internal static bool GetPrimaryInteropAssembly(Object TypeLib, out String asmName, out String asmCodeBase) { IntPtr pAttr = (IntPtr)0; TYPELIBATTR Attr; UCOMITypeLib pTLB = (UCOMITypeLib)TypeLib; int Major = 0; int Minor = 0; Guid TlbId; int lcid = 0; // Retrieve the major and minor version from the typelib. try { pTLB.GetLibAttr(out pAttr); Attr = (TYPELIBATTR)Marshal.PtrToStructure(pAttr, typeof(TYPELIBATTR)); Major = Attr.wMajorVerNum; Minor = Attr.wMinorVerNum; TlbId = Attr.guid; lcid = Attr.lcid; } finally { // Release the typelib attributes. if (pAttr != (IntPtr)0) { pTLB.ReleaseTLibAttr(pAttr); } } // Ask the converter for a PIA for this typelib. return(s_TypeLibConverter.GetPrimaryInteropAssembly(TlbId, Major, Minor, lcid, out asmName, out asmCodeBase)); }
internal Assembly GetPrimaryInteropAssembly(UCOMITypeLib typeLib, TypeLibConverter tlbConverter) { Assembly pia = FindRCW(typeLib); if (pia != null) { return(pia); } IntPtr typeLibAttr = NativeMethods.InvalidIntPtr; typeLib.GetLibAttr(out typeLibAttr); if (typeLibAttr != NativeMethods.InvalidIntPtr) { // Marshal the returned int as a TLibAttr structure // TYPELIBATTR tlbAttr = (TYPELIBATTR)Marshal.PtrToStructure(typeLibAttr, typeof(TYPELIBATTR)); string asmName = null; string asmCodeBase = null; try { tlbConverter.GetPrimaryInteropAssembly(tlbAttr.guid, tlbAttr.wMajorVerNum, tlbAttr.wMinorVerNum, tlbAttr.lcid, out asmName, out asmCodeBase); if (asmName != null && asmCodeBase == null) { // We found the PIA in the GAC... we need a codebase for this // so we can pass this to the compiler. // try { pia = Assembly.Load(asmName); asmCodeBase = GetLocalPath(pia.EscapedCodeBase); } catch (Exception e) { Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "Could load assembly from GAC " + asmName + " Exception " + e.Message); } } else if (asmCodeBase != null) { asmCodeBase = GetLocalPath(asmCodeBase); pia = Assembly.LoadFrom(asmCodeBase); } if (pia != null) { AddRCW(typeLib, pia); AddReferencedAssembly(asmCodeBase); } } finally { typeLib.ReleaseTLibAttr(typeLibAttr); } } return(pia); }
private static void UnRegisterMainTypeLib() { UCOMITypeLib Tlb = null; IntPtr pAttr = (IntPtr)0; try { // Try and load the typelib. LoadTypeLibEx(s_Options.m_strTypeLibName, REGKIND.REGKIND_NONE, out Tlb); // Retrieve the version information from the typelib. Tlb.GetLibAttr(out pAttr); // Copy the int we got back from GetLibAttr to a TypeLibAttr struct. TYPELIBATTR Attr = (TYPELIBATTR)Marshal.PtrToStructure((IntPtr)pAttr, typeof(TYPELIBATTR)); // Unregister the typelib. UnRegisterTypeLib(ref Attr.guid, Attr.wMajorVerNum, Attr.wMinorVerNum, Attr.lcid, Attr.syskind); } catch (COMException e) { // TYPE_E_REGISTRYACCESS errors simply mean that the typelib has already been unregistered. if (e.ErrorCode != unchecked ((int)0x8002801C)) { ThrowAppException(Resource.FormatString("Err_UnregistrationFailed"), e); } } catch (Exception e) { ThrowAppException(Resource.FormatString("Err_UnregistrationFailed"), e); } finally { // Release the typelib attributes. if (pAttr != (IntPtr)0) { Tlb.ReleaseTLibAttr(pAttr); } } // Display the success message unless silent mode is enabled. if (!s_Options.m_bSilentMode) { Console.WriteLine(Resource.FormatString("Msg_TypelibUnregistered", s_Options.m_strTypeLibName)); } }
/// <devdoc> /// <para>Gets the file name corresponding to the given TypelibAttribute. </para> /// </devdoc> private static string GetFileOfTypeLib(UCOMITypeLib typeLib) { IntPtr typeLibAttr = NativeMethods.InvalidIntPtr; typeLib.GetLibAttr(out typeLibAttr); if (typeLibAttr != NativeMethods.InvalidIntPtr) { // Marshal the returned int as a TLibAttr structure // TYPELIBATTR typeLibraryAttributes = (TYPELIBATTR)Marshal.PtrToStructure(typeLibAttr, typeof(TYPELIBATTR)); try { return(GetFileOfTypeLib(ref typeLibraryAttributes)); } finally { typeLib.ReleaseTLibAttr(typeLibAttr); } } return(null); }
private static void SetPIAAttributeOnAssembly(AssemblyBuilder asmBldr, Object typeLib) { IntPtr pAttr = Win32Native.NULL; TYPELIBATTR Attr; UCOMITypeLib pTLB = (UCOMITypeLib)typeLib; int Major = 0; int Minor = 0; // Retrieve the PrimaryInteropAssemblyAttribute constructor. Type [] aConsParams = new Type[2] { typeof(int), typeof(int) }; ConstructorInfo PIAAttrCons = typeof(PrimaryInteropAssemblyAttribute).GetConstructor(aConsParams); // Retrieve the major and minor version from the typelib. try { pTLB.GetLibAttr(out pAttr); Attr = (TYPELIBATTR)Marshal.PtrToStructure(pAttr, typeof(TYPELIBATTR)); Major = Attr.wMajorVerNum; Minor = Attr.wMinorVerNum; } finally { // Release the typelib attributes. if (pAttr != Win32Native.NULL) { pTLB.ReleaseTLibAttr(pAttr); } } // Create an instance of the custom attribute builder. Object[] aArgs = new Object[2] { Major, Minor }; CustomAttributeBuilder PIACABuilder = new CustomAttributeBuilder(PIAAttrCons, aArgs); // Set the PrimaryInteropAssemblyAttribute on the assembly builder. asmBldr.SetCustomAttribute(PIACABuilder); }
private void AddTypeLibAttr(UCOMITypeLib typeLib) { // Add the TYPELIBATTR of the TypeLib to our list. // if (tlbAttrs == null) { tlbAttrs = new ArrayList(); } IntPtr typeLibAttr = NativeMethods.InvalidIntPtr; typeLib.GetLibAttr(out typeLibAttr); if (typeLibAttr != NativeMethods.InvalidIntPtr) { // Marshal the returned int as a TLibAttr structure // TYPELIBATTR typeLibraryAttributes = (TYPELIBATTR)Marshal.PtrToStructure(typeLibAttr, typeof(TYPELIBATTR)); tlbAttrs.Add(typeLibraryAttributes); typeLib.ReleaseTLibAttr(typeLibAttr); } }
private void LoadTypeLibrary(string typeLibFile) { // Load type library via DllImported COM f(x). LoadTypeLibEx(typeLibFile, REGKIND.REGKIND_DEFAULT, out theTypeLib); // Get a managed version of type lib attributes. string typLibStats; TYPELIBATTR libAtts = new TYPELIBATTR(); Type TYPELIBATTRType = libAtts.GetType(); int structSize = Marshal.SizeOf(TYPELIBATTRType); IntPtr ptr = IntPtr.Zero; ptr = Marshal.AllocHGlobal(structSize); theTypeLib.GetLibAttr(out ptr); libAtts = (TYPELIBATTR)Marshal.PtrToStructure(ptr, TYPELIBATTRType); // Print out stats and release memory. typLibStats = "LIBID: " + libAtts.guid.ToString() + "\nVersion (Major): " + libAtts.wMajorVerNum.ToString() + "\nVersion (Minor): " + libAtts.wMinorVerNum.ToString(); lblTypeLibStats.Text = typLibStats; theTypeLib.ReleaseTLibAttr(ptr); Marshal.DestroyStructure(ptr, libAtts.GetType()); }
internal void AddRCW(UCOMITypeLib typeLib, Assembly assem) { if (rcwCache == null) { rcwCache = new Hashtable(); } IntPtr typeLibAttr = NativeMethods.InvalidIntPtr; typeLib.GetLibAttr(out typeLibAttr); try { if (typeLibAttr != NativeMethods.InvalidIntPtr) { // Marshal the returned int as a TLibAttr structure // TYPELIBATTR tlbAttr = (TYPELIBATTR)Marshal.PtrToStructure(typeLibAttr, typeof(TYPELIBATTR)); rcwCache.Add(tlbAttr.guid, assem); } } finally { typeLib.ReleaseTLibAttr(typeLibAttr); } }
public ComImporter(string path, OutputMessageCollection outputMessages, string outputDisplayName) { _outputMessages = outputMessages; _outputDisplayName = outputDisplayName; if (NativeMethods.SfcIsFileProtected(IntPtr.Zero, path) != 0) { outputMessages.AddWarningMessage("GenerateManifest.ComImport", outputDisplayName, _resources.GetString("ComImporter.ProtectedFile")); } object obj = null; try { NativeMethods.LoadTypeLibEx(path, NativeMethods.RegKind.RegKind_None, out obj); } catch (COMException) { } #pragma warning disable 618 UCOMITypeLib tlib = (UCOMITypeLib)obj; if (tlib != null) { IntPtr typeLibAttrPtr = IntPtr.Zero; tlib.GetLibAttr(out typeLibAttrPtr); TYPELIBATTR typeLibAttr = (TYPELIBATTR)Marshal.PtrToStructure(typeLibAttrPtr, typeof(TYPELIBATTR)); tlib.ReleaseTLibAttr(typeLibAttrPtr); Guid tlbid = typeLibAttr.guid; string name, docString, helpFile; int helpContext; tlib.GetDocumentation(-1, out name, out docString, out helpContext, out helpFile); string helpdir = Util.FilterNonprintableChars(helpFile); //Path.GetDirectoryName(helpFile); _typeLib = new TypeLib(tlbid, new Version(typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum), helpdir, typeLibAttr.lcid, Convert.ToInt32(typeLibAttr.wLibFlags, CultureInfo.InvariantCulture)); List <ComClass> comClassList = new List <ComClass>(); int count = tlib.GetTypeInfoCount(); for (int i = 0; i < count; ++i) { TYPEKIND tkind; tlib.GetTypeInfoType(i, out tkind); if (tkind == TYPEKIND.TKIND_COCLASS) { UCOMITypeInfo tinfo; tlib.GetTypeInfo(i, out tinfo); IntPtr tinfoAttrPtr = IntPtr.Zero; tinfo.GetTypeAttr(out tinfoAttrPtr); TYPEATTR tinfoAttr = (TYPEATTR)Marshal.PtrToStructure(tinfoAttrPtr, typeof(TYPEATTR)); tinfo.ReleaseTypeAttr(tinfoAttrPtr); Guid clsid = tinfoAttr.guid; string sclsid = clsid.ToString("B"); tlib.GetDocumentation(i, out name, out docString, out helpContext, out helpFile); string description = Util.FilterNonprintableChars(docString); ClassInfo info = GetRegisteredClassInfo(clsid); if (info == null) { continue; } comClassList.Add(new ComClass(tlbid, clsid, info.Progid, info.ThreadingModel, description)); } } if (comClassList.Count > 0) { _comClasses = comClassList.ToArray(); _success = true; } else { outputMessages.AddErrorMessage("GenerateManifest.ComImport", outputDisplayName, _resources.GetString("ComImporter.NoRegisteredClasses")); _success = false; } } else { outputMessages.AddErrorMessage("GenerateManifest.ComImport", outputDisplayName, _resources.GetString("ComImporter.TypeLibraryLoadFailure")); _success = false; } #pragma warning restore 618 }
internal static TypeLibKey GetTypeLibKey(UCOMITypeLib typeLib) { TypeLibKey typeLibKey; IntPtr typeAttrPtr; typeLib.GetLibAttr(out typeAttrPtr); TYPELIBATTR typeLibAttr = (TYPELIBATTR)Marshal.PtrToStructure(typeAttrPtr, typeof(TYPELIBATTR)); typeLibKey = GetTypeLibKey(typeLibAttr); // Release it only after we are not going to touch // even the TYPELIBATTR structure any more typeLib.ReleaseTLibAttr(typeAttrPtr); return typeLibKey; }
public ComImporter(string path, OutputMessageCollection outputMessages, string outputDisplayName) { this.outputMessages = outputMessages; this.outputDisplayName = outputDisplayName; if (Microsoft.Build.Tasks.Deployment.ManifestUtilities.NativeMethods.SfcIsFileProtected(IntPtr.Zero, path) != 0) { outputMessages.AddWarningMessage("GenerateManifest.ComImport", new string[] { outputDisplayName, this.resources.GetString("ComImporter.ProtectedFile") }); } object typeLib = null; try { Microsoft.Build.Tasks.Deployment.ManifestUtilities.NativeMethods.LoadTypeLibEx(path, Microsoft.Build.Tasks.Deployment.ManifestUtilities.NativeMethods.RegKind.RegKind_None, out typeLib); } catch (COMException) { } UCOMITypeLib lib = (UCOMITypeLib)typeLib; if (lib != null) { string str; string str2; string str3; int num; IntPtr zero = IntPtr.Zero; lib.GetLibAttr(out zero); TYPELIBATTR typelibattr = (TYPELIBATTR)Marshal.PtrToStructure(zero, typeof(TYPELIBATTR)); lib.ReleaseTLibAttr(zero); Guid tlbId = typelibattr.guid; lib.GetDocumentation(-1, out str, out str2, out num, out str3); string helpDirectory = Microsoft.Build.Tasks.Deployment.ManifestUtilities.Util.FilterNonprintableChars(str3); this.typeLib = new Microsoft.Build.Tasks.Deployment.ManifestUtilities.TypeLib(tlbId, new Version(typelibattr.wMajorVerNum, typelibattr.wMinorVerNum), helpDirectory, typelibattr.lcid, Convert.ToInt32(typelibattr.wLibFlags, CultureInfo.InvariantCulture)); List <ComClass> list = new List <ComClass>(); int typeInfoCount = lib.GetTypeInfoCount(); for (int i = 0; i < typeInfoCount; i++) { TYPEKIND typekind; lib.GetTypeInfoType(i, out typekind); if (typekind == TYPEKIND.TKIND_COCLASS) { UCOMITypeInfo info; lib.GetTypeInfo(i, out info); IntPtr ppTypeAttr = IntPtr.Zero; info.GetTypeAttr(out ppTypeAttr); TYPEATTR typeattr = (TYPEATTR)Marshal.PtrToStructure(ppTypeAttr, typeof(TYPEATTR)); info.ReleaseTypeAttr(ppTypeAttr); Guid guid = typeattr.guid; guid.ToString("B"); lib.GetDocumentation(i, out str, out str2, out num, out str3); string description = Microsoft.Build.Tasks.Deployment.ManifestUtilities.Util.FilterNonprintableChars(str2); ClassInfo registeredClassInfo = this.GetRegisteredClassInfo(guid); if (registeredClassInfo != null) { list.Add(new ComClass(tlbId, guid, registeredClassInfo.Progid, registeredClassInfo.ThreadingModel, description)); } } } if (list.Count > 0) { this.comClasses = list.ToArray(); this.success = true; } else { outputMessages.AddErrorMessage("GenerateManifest.ComImport", new string[] { outputDisplayName, this.resources.GetString("ComImporter.NoRegisteredClasses") }); this.success = false; } } else { outputMessages.AddErrorMessage("GenerateManifest.ComImport", new string[] { outputDisplayName, this.resources.GetString("ComImporter.TypeLibraryLoadFailure") }); this.success = false; } }
/// <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); } }
internal static AssemblyName GetAssemblyNameFromTypelib(Object typeLib, String asmFileName, byte[] publicKey, StrongNameKeyPair keyPair, Version asmVersion) { // Extract the name of the typelib. TYPELIBATTR Attr; String strTypeLibName = null; String strDocString = null; int dwHelpContext = 0; String strHelpFile = null; UCOMITypeLib pTLB = (UCOMITypeLib)typeLib; pTLB.GetDocumentation(-1, out strTypeLibName, out strDocString, out dwHelpContext, out strHelpFile); // Retrieve the name to use for the assembly. if (asmFileName == null) { asmFileName = strTypeLibName; } else { BCLDebug.Assert(!String.Empty.Equals(asmFileName), "The assembly file name cannot be an empty string!"); String strFileNameNoPath = Path.GetFileName(asmFileName); String strExtension = Path.GetExtension(asmFileName); // Validate that the extension is valid. bool bExtensionValid = ".dll".Equals(strExtension.ToLower(CultureInfo.InvariantCulture)); // If the extension is not valid then tell the user and quit. if (!bExtensionValid) { throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileExtension")); } // The assembly cannot contain the path nor the extension. asmFileName = strFileNameNoPath.Substring(0, strFileNameNoPath.Length - ".dll".Length); } // If the version information was not specified, then retrieve it from the typelib. if (asmVersion == null) { IntPtr pAttr = Win32Native.NULL; try { pTLB.GetLibAttr(out pAttr); Attr = (TYPELIBATTR)Marshal.PtrToStructure(pAttr, typeof(TYPELIBATTR)); asmVersion = new Version(Attr.wMajorVerNum, Attr.wMinorVerNum, 0, 0); } finally { if (pAttr != Win32Native.NULL) { pTLB.ReleaseTLibAttr(pAttr); } } } // Create the assembly name for the imported typelib's assembly. AssemblyName AsmName = new AssemblyName(); AsmName.Init( asmFileName, publicKey, null, asmVersion, null, AssemblyHashAlgorithm.None, AssemblyVersionCompatibility.SameMachine, null, AssemblyNameFlags.None, keyPair, null); return(AsmName); }
internal static Assembly generateAssemblyFromTypeLib(UCOMITypeLib typeLib, bool safeArrayAsArray, string asmFilePath, out bool foundPIAInstead) { foundPIAInstead = false; string typeLibName = Marshal.GetTypeLibName(typeLib); string asmDir, asmName, asmFullPath; if (asmFilePath == "") { // asmFilePath == "" means that user does not want the assembly saved in a file. A filename argument // is required by the conversion function, although no file is actually written by it. Therefore we // supply one in case it is truly necessary. asmName = "interop." + typeLibName + ".dll"; asmDir = ""; } else { asmDir = System.IO.Path.GetDirectoryName(asmFilePath); if (asmDir == null) { // asmFilePath was a root dir, like c:\. string asmRoot = System.IO.Path.GetPathRoot(asmFilePath); asmDir = asmRoot == null ? "" : asmRoot; } else { asmDir = asmDir + System.IO.Path.DirectorySeparatorChar; } // M code ensures that if asmFilePath is a dir and not a filename it ends in \, so asmName will be "" // if it is a dir. asmName = System.IO.Path.GetFileName(asmFilePath); if (asmName == "") { // asmFilePath was just a dir. asmName = "interop." + typeLibName + ".dll"; } } asmFullPath = asmDir + asmName; ImporterNotiferSink sink = new ImporterNotiferSink(safeArrayAsArray, asmDir); TypeLibConverter tlc = new TypeLibConverter(); // Check for an existing PIA and use it if it exists. IntPtr pTLibAttr; typeLib.GetLibAttr(out pTLibAttr); TYPELIBATTR typeLibAttr = (TYPELIBATTR)Marshal.PtrToStructure(pTLibAttr, typeof(TYPELIBATTR)); string piaName, piaCodeBase; bool piaExists = tlc.GetPrimaryInteropAssembly(typeLibAttr.guid, typeLibAttr.wMajorVerNum, typeLibAttr.wMinorVerNum, typeLibAttr.lcid, out piaName, out piaCodeBase); typeLib.ReleaseTLibAttr(pTLibAttr); if (piaExists) { Assembly pia = Assembly.LoadWithPartialName(piaName); if (pia != null) { foundPIAInstead = true; return(pia); } } TypeLoader.isBuildingDynamicAssembly = true; try { AssemblyBuilder asmBuilder = tlc.ConvertTypeLibToAssembly(typeLib, asmFullPath, safeArrayAsArray ? TypeLibImporterFlags.SafeArrayAsSystemArray : 0, sink, null, null, typeLibName, null); Type[] tt = asmBuilder.GetTypes(); if (asmFilePath != "") { asmBuilder.Save(asmName); } return(asmBuilder); } finally { TypeLoader.isBuildingDynamicAssembly = false; } }