Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / WinForms / System / WinForms / Design / AxImporter.cs / 1 / AxImporter.cs
namespace System.Windows.Forms.Design { using System.Design; using System; using Microsoft.Win32; using System.ComponentModel; using System.IO; using System.ComponentModel.Design; using System.Reflection; using System.Reflection.Emit; using System.Diagnostics; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using TYPELIBATTR = System.Runtime.InteropServices.TYPELIBATTR; using TYPEKIND = System.Runtime.InteropServices.ComTypes.TYPEKIND; using TYPEATTR = System.Runtime.InteropServices.ComTypes.TYPEATTR; using System.Collections; using System.Globalization; ////// /// public class AxImporter { // Private instance data. // internal Options options; internal string typeLibName; private ArrayList refAssems; private ArrayList genAssems; private ArrayList tlbAttrs; private ArrayList generatedSources; private Hashtable copiedAssems; private Hashtable rcwCache; ////// Imports ActiveX controls and generates a wrapper that can be accessed by a /// designer. /// ///public AxImporter(Options options) { this.options = options; } /// /// /// public string[] GeneratedAssemblies { get { if (genAssems == null || genAssems.Count <= 0) { return new string[0]; } Debug.Assert(tlbAttrs.Count == genAssems.Count, "Number of typelibs not equal to number of generated assemblies"); string[] gen = new string[genAssems.Count]; // Return references to all the generated assemblies. // for (int i = 0; i < genAssems.Count; ++i) { gen[i] = (string)genAssems[i]; } return gen; } } ///[To be supplied.] ////// /// #pragma warning disable 618 public TYPELIBATTR[] GeneratedTypeLibAttributes { get { if (tlbAttrs == null) { return new TYPELIBATTR[0]; } TYPELIBATTR[] gen = new TYPELIBATTR[tlbAttrs.Count]; // Return references to all the generated assemblies. // for (int i = 0; i < tlbAttrs.Count; ++i) { gen[i] = (TYPELIBATTR)tlbAttrs[i]; } return gen; } } #pragma warning restore 618 ///[To be supplied.] ////// /// public string[] GeneratedSources { get { if (options.genSources) { string[] srcs = new string[ generatedSources.Count ]; for (int i = 0; i < generatedSources.Count; i++) { srcs[ i ] = (string) generatedSources[ i ]; } return srcs; } else return null; } } private void AddDependentAssemblies(Assembly assem, string assemPath) { AssemblyName[] refAssems = assem.GetReferencedAssemblies(); foreach(AssemblyName an in refAssems) { if (String.Equals(an.Name, "mscorlib", StringComparison.OrdinalIgnoreCase)) continue; string codebase = GetComReference(an); // If we can't get a valid codebase, see if we can load this // assembly from the AssemblyName (should succeed if this is // in the GAC or some path where Fusion can find this) and then // get the codebase from there. // if (codebase == null) { Assembly dependAssem = null; try { dependAssem = Assembly.Load(an); } catch (FileNotFoundException) { // nope, try looking in the same path as we are currently in... // if (an.CodeBase == null) { AssemblyName newName = AssemblyName.GetAssemblyName(Path.Combine(Path.GetDirectoryName(assemPath), an.Name + ".dll")); dependAssem = Assembly.Load(newName); } else { throw; } } codebase = dependAssem.EscapedCodeBase; if (codebase != null) { codebase = GetLocalPath(codebase); } } Debug.Assert(codebase != null, "No reference found for assembly: " + an.Name); AddReferencedAssembly(codebase); } } private void AddReferencedAssembly(string assem) { if (refAssems == null) { refAssems = new ArrayList(); } refAssems.Add(assem); } private void AddGeneratedAssembly(string assem) { if (genAssems == null) { genAssems = new ArrayList(); } genAssems.Add(assem); } internal void AddRCW(ITypeLib 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 // #pragma warning disable 618 TYPELIBATTR tlbAttr = (TYPELIBATTR) Marshal.PtrToStructure(typeLibAttr, typeof(TYPELIBATTR)); #pragma warning restore 618 rcwCache.Add(tlbAttr.guid, assem); } } finally { typeLib.ReleaseTLibAttr(typeLibAttr); } } internal Assembly FindRCW(ITypeLib 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 // #pragma warning disable 618 TYPELIBATTR tlbAttr = (TYPELIBATTR) Marshal.PtrToStructure(typeLibAttr, typeof(TYPELIBATTR)); #pragma warning restore 618 return (Assembly)rcwCache[tlbAttr.guid]; } } finally { typeLib.ReleaseTLibAttr(typeLibAttr); } return null; } private void AddTypeLibAttr(ITypeLib 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 // #pragma warning disable 618 TYPELIBATTR typeLibraryAttributes = (TYPELIBATTR) Marshal.PtrToStructure(typeLibAttr, typeof(TYPELIBATTR)); #pragma warning restore 618 tlbAttrs.Add(typeLibraryAttributes); typeLib.ReleaseTLibAttr(typeLibAttr); } } private string GetAxReference(ITypeLib typeLib) { if (options.references == null) return null; #pragma warning disable 618 return options.references.ResolveActiveXReference((UCOMITypeLib)typeLib); #pragma warning restore 618 } private string GetReferencedAssembly(string assemName) { if (refAssems == null || refAssems.Count <= 0) return null; foreach(string assemRef in refAssems) { if (String.Equals(assemRef, assemName, StringComparison.OrdinalIgnoreCase)) { return assemRef; } } return null; } private string GetComReference(ITypeLib typeLib) { if (options.references == null) return null; #pragma warning disable 618 return options.references.ResolveComReference((UCOMITypeLib)typeLib); #pragma warning restore 618 } private string GetComReference(AssemblyName name) { if (options.references == null) return name.EscapedCodeBase; return options.references.ResolveComReference(name); } private string GetManagedReference(string assemName) { if (options.references == null) return assemName + ".dll"; return options.references.ResolveManagedReference(assemName); } ///[To be supplied.] ////// private string GetAxTypeFromAssembly(string fileName, Guid clsid) { Assembly a = GetCopiedAssembly(fileName, true, false); Type[] types = a.GetTypes(); foreach(Type t in types) { if (!(typeof(AxHost).IsAssignableFrom(t))) { continue; } object[] attrs = t.GetCustomAttributes(typeof(AxHost.ClsidAttribute), false); Debug.Assert(attrs != null && attrs.Length == 1, "Invalid number of GuidAttributes found on: " + t.FullName); AxHost.ClsidAttribute clsidAttr = (AxHost.ClsidAttribute)attrs[0]; if (clsidAttr.Value == "{" + clsid.ToString() + "}") return t.FullName; } return null; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods")] private Assembly GetCopiedAssembly(string fileName, bool loadPdb, bool isPIA) { if (!File.Exists(fileName)) { return null; } Assembly assembly = null; string upperFileName = fileName.ToUpper(CultureInfo.InvariantCulture); if (copiedAssems == null) { copiedAssems = new Hashtable(); } else { if (copiedAssems.Contains(upperFileName)) return (Assembly)copiedAssems[upperFileName]; } Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "Loading assembly " + fileName + ((!isPIA) ? " from bytes" : " from file")); if (!isPIA) { // Shadow copy the assembly first... // Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); int streamLen = (int)stream.Length; byte[] assemblyBytes = new byte[streamLen]; stream.Read(assemblyBytes, 0, streamLen); stream.Close(); byte[] pdbBytes = null; if (loadPdb) { // See if we can discover a PDB at the same time. // string pdbName = Path.ChangeExtension(fileName, "pdb"); if (File.Exists(pdbName)) { stream = new FileStream(pdbName, FileMode.Open, FileAccess.Read, FileShare.Read); streamLen = (int)stream.Length; pdbBytes = new byte[streamLen]; stream.Read(pdbBytes, 0, streamLen); stream.Close(); Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "Located assembly PDB " + pdbName + " containing " + streamLen + " bytes."); } } if (pdbBytes == null) { assembly = Assembly.Load(assemblyBytes); } else { assembly = Assembly.Load(assemblyBytes, pdbBytes); } } else { assembly = Assembly.LoadFrom(fileName); } copiedAssems.Add(upperFileName, assembly); return assembly; } ///Walks through all AxHost derived classes in the given assembly, /// and returns the type that matches our control's CLSID. ////// private static string GetFileOfTypeLib(ITypeLib typeLib) { IntPtr typeLibAttr = NativeMethods.InvalidIntPtr; typeLib.GetLibAttr(out typeLibAttr); if (typeLibAttr != NativeMethods.InvalidIntPtr) { // Marshal the returned int as a TLibAttr structure // #pragma warning disable 618 TYPELIBATTR typeLibraryAttributes = (TYPELIBATTR) Marshal.PtrToStructure(typeLibAttr, typeof(TYPELIBATTR)); #pragma warning restore 618 try { return GetFileOfTypeLib(ref typeLibraryAttributes); } finally { typeLib.ReleaseTLibAttr(typeLibAttr); } } return null; } ///Gets the file name corresponding to the given TypelibAttribute. ////// /// #pragma warning disable 618 public static string GetFileOfTypeLib(ref TYPELIBATTR tlibattr) { #pragma warning restore 618 // Get which file the type library resides in. If the appropriate // file cannot be found then a blank string is returned. string returnedPath = null; // Get the path from the registry returnedPath = NativeMethods.QueryPathOfRegTypeLib(ref tlibattr.guid, tlibattr.wMajorVerNum, tlibattr.wMinorVerNum, tlibattr.lcid); if (returnedPath.Length > 0) { // Remove the '\0' characters at the end of the string, so File.Exists() // does not get confused. int nullTerminate = returnedPath.IndexOf('\0'); if (nullTerminate > -1) { returnedPath = returnedPath.Substring(0, nullTerminate); } // If we got a path then it might have a type library number appended to // it. If so, then we need to strip it. if (!File.Exists(returnedPath)) { // Strip the type library number // int lastSlash = returnedPath.LastIndexOf(Path.DirectorySeparatorChar); if (lastSlash != -1) { bool allNumbers = true; for (int i = lastSlash + 1; i < returnedPath.Length; i++) { // We have to check for NULL here because QueryPathOfRegTypeLib() returns // a BSTR with a NULL character appended to it. if (returnedPath[i] != '\0' && !Char.IsDigit(returnedPath[i])) { allNumbers = false; break; } } // If we had all numbers past the last slash then we're OK to strip // the type library number if (allNumbers) { returnedPath = returnedPath.Substring(0, lastSlash); if (!File.Exists(returnedPath)) { returnedPath = null; } } else { returnedPath = null; } } else { returnedPath = null; } } } return returnedPath; } ///Gets the file name corresponding to the given TypelibAttribute. ////// This method takes a file URL and converts it to a local path. The trick here is that /// if there is a '#' in the path, everything after this is treated as a fragment. So /// we need to append the fragment to the end of the path. /// private string GetLocalPath(string fileName) { System.Diagnostics.Debug.Assert(fileName != null && fileName.Length > 0, "Cannot get local path, fileName is not valid"); Uri uri = new Uri(fileName); return uri.LocalPath + uri.Fragment; } ////// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2102:CatchNonClsCompliantExceptionsInGeneralHandlers")] internal string GenerateFromActiveXClsid(Guid clsid) { string controlKey = "CLSID\\{" + clsid.ToString() + "}"; RegistryKey key = Registry.ClassesRoot.OpenSubKey(controlKey); if (key == null) { Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "No registry key found for: " + controlKey); throw new ArgumentException(SR.GetString(SR.AXNotRegistered, controlKey.ToString())); } // Load the typelib into memory. // ITypeLib typeLib = null; // Try to get the TypeLib's Guid. // Guid tlbGuid = Guid.Empty; // Open the key for the TypeLib // RegistryKey tlbKey = key.OpenSubKey("TypeLib"); if (tlbKey != null) { // Get the major and minor version numbers. // RegistryKey verKey = key.OpenSubKey("Version"); Debug.Assert(verKey != null, "No version registry key found for: " + controlKey); short majorVer = -1; short minorVer = -1; string ver = (string)verKey.GetValue(""); int dot = ver.IndexOf('.'); if (dot == -1) { majorVer = Int16.Parse(ver, CultureInfo.InvariantCulture); minorVer = 0; } else { majorVer = Int16.Parse(ver.Substring(0, dot), CultureInfo.InvariantCulture); minorVer = Int16.Parse(ver.Substring(dot + 1, ver.Length - dot - 1), CultureInfo.InvariantCulture); } Debug.Assert(majorVer > 0 && minorVer >= 0, "No Major version number found for: " + controlKey); verKey.Close(); object o = tlbKey.GetValue(""); tlbGuid = new Guid((string)o); Debug.Assert(!tlbGuid.Equals(Guid.Empty), "No valid Guid found for: " + controlKey); tlbKey.Close(); try { typeLib = NativeMethods.LoadRegTypeLib(ref tlbGuid, majorVer, minorVer, Application.CurrentCulture.LCID); } catch (Exception e) { Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "Failed to LoadRegTypeLib: " + e.ToString()); } } // Try to load the TLB directly from the InprocServer32. // // If that fails, try to load the TLB based on the TypeLib guid key. // if (typeLib == null) { RegistryKey inprocServerKey = key.OpenSubKey("InprocServer32"); if (inprocServerKey != null) { string inprocServer = (string)inprocServerKey.GetValue(""); Debug.Assert(inprocServer != null, "No valid InprocServer32 found for: " + controlKey); inprocServerKey.Close(); typeLib = NativeMethods.LoadTypeLib(inprocServer); } } key.Close(); if (typeLib != null) { try { #pragma warning disable 618 return GenerateFromTypeLibrary((UCOMITypeLib)typeLib, clsid); #pragma warning restore 618 } finally { Marshal.ReleaseComObject(typeLib); } } else { throw new ArgumentException(SR.GetString(SR.AXNotRegistered, controlKey.ToString())); } } ////// Generates a wrapper for an ActiveX control for use in the design-time /// environment. /// ////// /// public string GenerateFromFile(FileInfo file) { typeLibName = file.FullName; ITypeLib typeLib = null; Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "Loading Typelib from " + typeLibName); typeLib = (ITypeLib)NativeMethods.LoadTypeLib(typeLibName); if (typeLib == null) { throw new Exception(SR.GetString(SR.AXCannotLoadTypeLib, typeLibName)); } try { #pragma warning disable 618 return GenerateFromTypeLibrary((UCOMITypeLib)typeLib); #pragma warning restore 618 } finally { if (typeLib != null) { Marshal.ReleaseComObject(typeLib); } } } ///Generates a wrapper for an ActiveX control for use in the design-time /// environment. ////// /// #pragma warning disable 618 public string GenerateFromTypeLibrary(UCOMITypeLib typeLib) { #pragma warning restore 618 bool foundAxCtl = false; int ctypes = ((ITypeLib)typeLib).GetTypeInfoCount(); Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "Number of TypeInfos found in typelib: " + ctypes); for (int i = 0; i < ctypes; ++i) { IntPtr pAttr; TYPEATTR typeAttr; ITypeInfo pTI; ((ITypeLib)typeLib).GetTypeInfo(i, out pTI); pTI.GetTypeAttr(out pAttr); typeAttr = (TYPEATTR)Marshal.PtrToStructure(pAttr, typeof(TYPEATTR)); if ((int)typeAttr.typekind == (int)TYPEKIND.TKIND_COCLASS) { Guid g = typeAttr.guid; string controlKey = "CLSID\\{" + g.ToString() + "}\\Control"; RegistryKey key = Registry.ClassesRoot.OpenSubKey(controlKey); if (key != null) { Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "Found ActiveX control with the following GUID: " + g.ToString()); foundAxCtl = true; } } pTI.ReleaseTypeAttr(pAttr); pAttr = IntPtr.Zero; Marshal.ReleaseComObject(pTI); pTI = null; } if (foundAxCtl) { Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "Generating Windows Forms wrappers for: " + typeLibName); return GenerateFromTypeLibrary(typeLib, Guid.Empty); } else { string errMsg = SR.GetString(SR.AXNoActiveXControls, (typeLibName != null) ? typeLibName : Marshal.GetTypeLibName((ITypeLib)typeLib)); if (options.msBuildErrors) { errMsg = "AxImp: error aximp000: " + errMsg; } throw new Exception(errMsg); } } ///Generates a wrapper for an ActiveX control for use in the design-time /// environment. ////// /// #pragma warning disable 618 public string GenerateFromTypeLibrary(UCOMITypeLib typeLib, Guid clsid) { #pragma warning restore 618 string axWFW = null; string axctlType = null; Assembly rcw = null; // Look to see if we can find the AxWrapper also for this typeLib. // axWFW = GetAxReference((ITypeLib)typeLib); if (axWFW != null && clsid != Guid.Empty) { axctlType = GetAxTypeFromAssembly(axWFW, clsid); } if (axWFW == null) { string tlbName = Marshal.GetTypeLibName((ITypeLib)typeLib); string rcwName = Path.Combine(options.outputDirectory, tlbName + ".dll"); Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "Converting TypeLib Name: " + tlbName + " in " + rcwName); AddReferencedAssembly(GetManagedReference("System.Windows.Forms")); AddReferencedAssembly(GetManagedReference("System.Drawing")); AddReferencedAssembly(GetManagedReference("System")); string rcwAssem = GetComReference((ITypeLib)typeLib); if (rcwAssem != null) { AddReferencedAssembly(rcwAssem); rcw = GetCopiedAssembly(rcwAssem, false, false); AddDependentAssemblies(rcw, rcwAssem); } else { TypeLibConverter tlbConverter = new TypeLibConverter(); // Try to locate the primary interop assembly first. // rcw = GetPrimaryInteropAssembly((ITypeLib)typeLib, tlbConverter); if (rcw != null) { rcwAssem = GetLocalPath(rcw.EscapedCodeBase); AddDependentAssemblies(rcw, rcwAssem); } else { AssemblyBuilder asmBldr = tlbConverter.ConvertTypeLibToAssembly((ITypeLib)typeLib, rcwName, (TypeLibImporterFlags)0, new ImporterCallback(this), options.publicKey, options.keyPair, null, null); if (rcwAssem == null) { // Save the assembly to the disk only if we did not find it already on the reference list. // rcwAssem = SaveAssemblyBuilder((ITypeLib)typeLib, asmBldr, rcwName); rcw = (Assembly)asmBldr; } } } Debug.Assert(rcw != null, "No assembly obtained from: " + rcwAssem); // Create a list of the referenced assemblies and create the WFW Wrapper for the AxControl. // int i = 0; string[] refAssems = new string[this.refAssems.Count]; foreach(string assem in this.refAssems) { string name = assem; name = name.Replace("%20", " "); Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "Adding " + name + " to the wrapper reference list..."); refAssems[i++] = name; } if (axctlType == null) { string file = GetFileOfTypeLib((ITypeLib)typeLib); DateTime tlbTimeStamp = (file == null) ? DateTime.Now : File.GetLastWriteTime(file); // Hook up the type resolution events for the appdomain so we can delay load // any assemblies/types users gave us in the /i option. // ResolveEventHandler assemblyResolveEventHandler = new ResolveEventHandler(OnAssemblyResolve); AppDomain.CurrentDomain.AssemblyResolve += assemblyResolveEventHandler; AppDomain.CurrentDomain.TypeResolve += new ResolveEventHandler(OnTypeResolve); try { if (options.genSources) AxWrapperGen.GeneratedSources = new ArrayList(); if (options.outputName == null) options.outputName = "Ax" + tlbName + ".dll"; axctlType = AxWrapperGen.GenerateWrappers(this, clsid, rcw, refAssems, tlbTimeStamp, out axWFW); if (options.genSources) generatedSources = AxWrapperGen.GeneratedSources; } finally { AppDomain.CurrentDomain.AssemblyResolve -= assemblyResolveEventHandler; AppDomain.CurrentDomain.TypeResolve -= new ResolveEventHandler(OnTypeResolve); } if (axctlType == null) { string errMsg = SR.GetString(SR.AXNoActiveXControls, ((typeLibName != null) ? typeLibName : tlbName)); if (options.msBuildErrors) { errMsg = "AxImp: error aximp000: " + errMsg; } throw new Exception(errMsg); } } if (axctlType != null) { // Add the WFW assembly to the references list. // Debug.Assert(axWFW != null && axWFW.Length > 0, "Invalid output assembly name"); AddReferencedAssembly(axWFW); AddTypeLibAttr((ITypeLib)typeLib); AddGeneratedAssembly(axWFW); } } return axctlType; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2102:CatchNonClsCompliantExceptionsInGeneralHandlers")] internal Assembly GetPrimaryInteropAssembly(ITypeLib 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 // #pragma warning disable 618 TYPELIBATTR tlbAttr = (TYPELIBATTR) Marshal.PtrToStructure(typeLibAttr, typeof(TYPELIBATTR)); #pragma warning restore 618 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 Assembly OnAssemblyResolve(object sender, ResolveEventArgs e) { string assemblyName = e.Name; Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "In OnAssemblyResolve: " + assemblyName); // Look for the assembly in the RCW cache. // if (rcwCache != null) { foreach (Assembly a in rcwCache.Values) { if (a.FullName == assemblyName) { Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "\t Found " + a.GetName().Name); return a; } } } Assembly assembly = null; if (copiedAssems == null) { copiedAssems = new Hashtable(); } else { assembly = (Assembly)copiedAssems[assemblyName]; if (assembly != null) { return assembly; } } // Now, look for it among the copied assemblies. // if (refAssems == null || refAssems.Count == 0) return null; foreach (string assemName in refAssems) { Assembly assem = GetCopiedAssembly(assemName, false, false); if (assem == null) continue; string s = assem.FullName; if (s == assemblyName) { Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "\t Found " + s); return assem; } } Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "\t Did not find " + assemblyName); return null; } ////// Generates a wrapper for an ActiveX control for use in the design-time /// environment. /// ////// resolves types coming from the referenced assemblies. /// private Assembly OnTypeResolve(object sender, ResolveEventArgs e) { try { string typeName = e.Name; if (refAssems == null || refAssems.Count == 0) return null; foreach (string assemName in refAssems) { Assembly assem = GetCopiedAssembly(assemName, false, false); if (assem == null) continue; if (assem.GetType(typeName, false) != null) { return assem; } } } catch { } return null; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2102:CatchNonClsCompliantExceptionsInGeneralHandlers")] private string SaveAssemblyBuilder(ITypeLib typeLib, AssemblyBuilder asmBldr, string rcwName) { string assembly = null; FileInfo rcwFile = new FileInfo(rcwName); string fullPath = rcwFile.FullName; string assemName = rcwFile.Name; // Check to see if the assembly is already in the referenced set of assemblies. // If so, just use the referenced assembly instead of creating a new one on disk. // // Otherwise, create our assembly by saving to disk. // if (rcwFile.Exists) { if (options.overwriteRCW) { if (typeLibName != null && String.Equals(typeLibName, rcwFile.FullName,StringComparison.OrdinalIgnoreCase)){ throw new Exception(SR.GetString(SR.AXCannotOverwriteFile, rcwFile.FullName)); } if (((int)rcwFile.Attributes & (int)FileAttributes.ReadOnly) == (int)FileAttributes.ReadOnly) { throw new Exception(SR.GetString(SR.AXReadOnlyFile, rcwFile.FullName)); } try { rcwFile.Delete(); asmBldr.Save(assemName); } catch(Exception e) { Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "Exception deleting file " + rcwFile.FullName + " Exception: " + e.ToString()); throw new Exception(SR.GetString(SR.AXCannotOverwriteFile, rcwFile.FullName)); } } } else { asmBldr.Save(assemName); } assembly = rcwFile.FullName; // Add the generated assembly to our list. // AddReferencedAssembly(assembly); AddTypeLibAttr(typeLib); AddGeneratedAssembly(assembly); return assembly; } private class ImporterCallback : ITypeLibImporterNotifySink { AxImporter importer; Options options; public ImporterCallback(AxImporter importer) { this.importer = importer; this.options = importer.options; } void ITypeLibImporterNotifySink.ReportEvent(ImporterEventKind EventKind, int EventCode, String EventMsg) { } Assembly ITypeLibImporterNotifySink.ResolveRef(Object typeLib) { try { string assem = importer.GetComReference((ITypeLib)typeLib); if (assem != null) { importer.AddReferencedAssembly(assem); } Assembly a = importer.FindRCW((ITypeLib)typeLib); if (a != null) { return a; } // Generate the RCW for the typelib. We have to go through the motions of this anyway, // because there is no easy way to find the dependent references for this typelib. // try { string tlbName = Marshal.GetTypeLibName((ITypeLib)typeLib); string rcwName = Path.Combine(options.outputDirectory, tlbName + ".dll"); Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "\tConverting recursive TypeLib Name: " + tlbName + " in " + rcwName); if (importer.GetReferencedAssembly(rcwName) != null) { Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "\t\tFound RCW in referenced assembly list at " + rcwName); return importer.GetCopiedAssembly(rcwName, false, false); } // Create the TypeLibConverter. TypeLibConverter tlbConv = new TypeLibConverter(); // Try to locate the primary interop assembly first. // a = importer.GetPrimaryInteropAssembly((ITypeLib)typeLib, tlbConv); if (a != null) { return a; } else { // Convert the typelib. AssemblyBuilder asmBldr = tlbConv.ConvertTypeLibToAssembly(typeLib, rcwName, (TypeLibImporterFlags)0, new ImporterCallback(importer), options.publicKey, options.keyPair, null, null); if (assem == null) { // Save the assembly to the disk only if we did not find it already on the reference list. // Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "\t\tGenerated RCW at " + rcwName); string rcwAssem = importer.SaveAssemblyBuilder((ITypeLib)typeLib, asmBldr, rcwName); importer.AddRCW((ITypeLib)typeLib, asmBldr); return asmBldr; } else { Debug.WriteLineIf(AxWrapperGen.AxWrapper.Enabled, "\t\tFound COM Reference at " + assem); return importer.GetCopiedAssembly(assem, false, false); } } } catch { return null; } } finally { Marshal.ReleaseComObject(typeLib); } } } ////// /// public sealed class Options { /// The path-included filename of type library containing the definition of the ActiveX control. /// ////// Various options to be set before calling AxImporter to generate wrappers /// for an ActiveX control. /// ///public string outputName = null; /// The output directory for all the generated assemblies. /// /// public string outputDirectory = null; /// The public key used to sign the generated assemblies. /// /// public byte[] publicKey = null; /// The strong name used for the generated assemblies. /// /// public StrongNameKeyPair keyPair = null; /// The file containing the strong name key for the generated assemblies. /// /// public string keyFile = null; /// The file containing the strong name key container for the generated assemblies. /// /// public string keyContainer = null; /// Flag that controls whether we are to generate sources for the ActiveX control wrapper. /// /// public bool genSources = false; /// Flag that controls whether we should output errors in the MSBuild format. /// /// public bool msBuildErrors = false; /// Flag that controls whether we should show the logo. /// /// public bool noLogo = false; /// Flag that controls the output generated. /// /// public bool silentMode = false; /// Flag that controls the output generated. /// /// public bool verboseMode = false; /// The flag that controls when we sign the generated assemblies. /// /// public bool delaySign = false; /// The flag that controls whether we try to overwrite existing generated assemblies. /// /// public bool overwriteRCW = false; /// The object that allows us to resolve types and references needed to generate assemblies. /// /// public IReferenceResolver references = null; } /// /// /// The Reference Resolver service will try to look through the references it can obtain, /// for a reference that matches the given criterion. For now, the only kind of references /// it can look for are COM (RCW) references and ActiveX wrapper references. /// public interface IReferenceResolver { ///string ResolveManagedReference(string assemName); #pragma warning disable 618 /// string ResolveComReference(UCOMITypeLib typeLib); #pragma warning restore 618 /// string ResolveComReference(AssemblyName name); #pragma warning disable 618 /// string ResolveActiveXReference(UCOMITypeLib typeLib); #pragma warning restore 618 } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
![Network programming in C#, Network Programming in VB.NET, Network Programming in .NET](/images/book.jpg)
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DbCommandTree.cs
- ConfigurationValidatorAttribute.cs
- ParseHttpDate.cs
- DataGridViewCellValidatingEventArgs.cs
- SpeechAudioFormatInfo.cs
- CompilationUnit.cs
- Vector3DAnimation.cs
- EncryptedXml.cs
- SqlNodeAnnotations.cs
- Win32MouseDevice.cs
- SqlDataSourceEnumerator.cs
- IsolationInterop.cs
- WorkflowValidationFailedException.cs
- DoubleAnimationBase.cs
- HttpHandlerActionCollection.cs
- EdmSchemaAttribute.cs
- TimeSpanSecondsConverter.cs
- AlternationConverter.cs
- GeneralTransform3D.cs
- SqlCacheDependencySection.cs
- ISAPIWorkerRequest.cs
- Model3DCollection.cs
- ChangeTracker.cs
- DispatcherHooks.cs
- RawUIStateInputReport.cs
- KnownTypesProvider.cs
- ObjectItemLoadingSessionData.cs
- DataSourceGeneratorException.cs
- ResolvedKeyFrameEntry.cs
- ExpressionEvaluator.cs
- SQLSingleStorage.cs
- SoapSchemaImporter.cs
- AttachedPropertyBrowsableForChildrenAttribute.cs
- GZipObjectSerializer.cs
- ThreadAbortException.cs
- CorrelationManager.cs
- ListBase.cs
- SqlVisitor.cs
- SliderAutomationPeer.cs
- CachedPathData.cs
- CopyNamespacesAction.cs
- BitmapCache.cs
- TdsEnums.cs
- ToolboxItem.cs
- DocumentPageHost.cs
- AnnouncementEndpoint.cs
- CounterCreationDataCollection.cs
- GroupBoxRenderer.cs
- SrgsElementList.cs
- MembershipSection.cs
- MD5.cs
- InternalBufferOverflowException.cs
- relpropertyhelper.cs
- SimpleHandlerBuildProvider.cs
- DefaultValueAttribute.cs
- ScriptResourceAttribute.cs
- GroupedContextMenuStrip.cs
- RayHitTestParameters.cs
- ListViewGroup.cs
- GroupItemAutomationPeer.cs
- ValueConversionAttribute.cs
- Identity.cs
- CharAnimationUsingKeyFrames.cs
- CacheVirtualItemsEvent.cs
- BCLDebug.cs
- ToolStripItemCollection.cs
- WriteableBitmap.cs
- WebColorConverter.cs
- XsltInput.cs
- DbConnectionPool.cs
- Registry.cs
- SocketStream.cs
- Types.cs
- BulletedListEventArgs.cs
- SelectionEditor.cs
- SessionStateSection.cs
- DataRelationCollection.cs
- ModelFactory.cs
- ISAPIApplicationHost.cs
- EmptyImpersonationContext.cs
- Selector.cs
- InteropBitmapSource.cs
- Size3DConverter.cs
- ListBoxItemAutomationPeer.cs
- GeometryConverter.cs
- CombinedGeometry.cs
- DataGridViewTextBoxCell.cs
- Opcode.cs
- MetadataPropertyCollection.cs
- WrappedIUnknown.cs
- PersonalizationEntry.cs
- Animatable.cs
- BinaryParser.cs
- RowSpanVector.cs
- IntegerValidator.cs
- IArgumentProvider.cs
- SByteConverter.cs
- BamlTreeMap.cs
- ResourceKey.cs
- TemplateXamlParser.cs