/// <summary> /// Writes the entries needed to register a COM-imported type (e.g. a type /// with the <see cref="System.Runtime.InteropServices.ComImportAttribute"/>) /// to the registry file. /// </summary> /// <param name="type">Type to write.</param> /// <param name="codebase">Optional codebase, if it needs to be written.</param> /// <param name="rootKeyName">Name of root key where to add types.</param> /// <param name="writer"><see cref="RegistryFileWriter"/> used to write to the /// registry file.</param> private void WriteComImportInRegistryFile(Type type, string codebase, string rootKeyName, RegistryFileWriter writer) { Debug.Assert(type != null); Debug.Assert(!String.IsNullOrEmpty(rootKeyName)); Debug.Assert(writer != null); // For COM imports, we write the CLSID, but no ProgID. string keyPath = String.Format(@"{0}\CLSID\{1}\InprocServer32", rootKeyName, type.GUID.ToString("B").ToUpper(CultureInfo.InvariantCulture)); using (RegistryKeyWriter keyWriter = writer.AddKey(keyPath)) { keyWriter.AddValue("Class", type.FullName); keyWriter.AddValue("Assembly", assembly.FullName); keyWriter.AddValue("RuntimeVersion", assembly.ImageRuntimeVersion); if (!String.IsNullOrEmpty(codebase)) { keyWriter.AddValue("CodeBase", codebase); } } // Also write versioned key. keyPath += String.Format(@"\{0}", assembly.GetName().Version); using (RegistryKeyWriter keyWriter = writer.AddKey(keyPath)) { keyWriter.AddValue("Class", type.FullName); keyWriter.AddValue("Assembly", assembly.FullName); keyWriter.AddValue("RuntimeVersion", assembly.ImageRuntimeVersion); if (!String.IsNullOrEmpty(codebase)) { keyWriter.AddValue("CodeBase", codebase); } } }
/// <summary> /// Writes the entries needed to register a value type (e.g. structs) to /// the registry file. /// </summary> /// <param name="type">Type to write.</param> /// <param name="codebase">Optional codebase, if it needs to be written.</param> /// <param name="rootKeyName">Name of root key where to add types.</param> /// <param name="writer"><see cref="RegistryKeyWriter"/> used to write /// to the registry file.</param> private void WriteValueTypeInRegistryFile(Type type, string codebase, string rootKeyName, RegistryFileWriter writer) { Debug.Assert(type != null); Debug.Assert(!String.IsNullOrEmpty(rootKeyName)); Debug.Assert(writer != null); // Value types are written to the Classes\Record key, using the type's GUID and its version. string keyPath = String.Format(@"{0}\Record\{1}\{2}", rootKeyName, type.GUID.ToString("B").ToUpper(CultureInfo.InvariantCulture), assembly.GetName().Version); using (RegistryKeyWriter keyWriter = writer.AddKey(keyPath)) { keyWriter.AddValue("Class", type.FullName); keyWriter.AddValue("Assembly", assembly.FullName); keyWriter.AddValue("RuntimeVersion", assembly.ImageRuntimeVersion); if (!String.IsNullOrEmpty(codebase)) { keyWriter.AddValue("CodeBase", codebase); } } }
/// <summary> /// Writes the entries needed to register our assembly as a primary /// interop assembly to the registry file. /// </summary> /// <param name="attrib"><see cref="System.Reflection.CustomAttributeData"/> /// for the assembly's <see cref="System.Runtime.InteropServices.PrimaryInteropAssemblyAttribute"/>.</param> /// <param name="codebase">Optional codebase, if it needs to be written.</param> /// <param name="rootKeyName">Name of root key where to add types.</param> /// <param name="writer"><see cref="RegistryFileWriter"/> used to write to the /// registry file.</param> /// <seealso cref="System.Runtime.InteropServices.PrimaryInteropAssemblyAttribute"/> private void WritePrimaryInteropAssemblyInRegistryFile(CustomAttributeData attrib, string codebase, string rootKeyName, RegistryFileWriter writer) { Debug.Assert(attrib != null); Debug.Assert(!String.IsNullOrEmpty(rootKeyName)); Debug.Assert(writer != null); // For this, we add data to the Classes\TypeLib key, using TypeLib ID and version, // pulled from the PrimaryInteropAssemblyAttribute (and inexplicably expressed as hexadecimal values). string keyPath = String.Format(@"{0}\TypeLib\{1}\{2}.{3}", rootKeyName, Marshal.GetTypeLibGuidForAssembly(assembly).ToString("B").ToUpper(CultureInfo.InvariantCulture), ((int)attrib.ConstructorArguments[0].Value).ToString("x", CultureInfo.InvariantCulture), ((int)attrib.ConstructorArguments[1].Value).ToString("x", CultureInfo.InvariantCulture)); using (RegistryKeyWriter keyWriter = writer.AddKey(keyPath)) { keyWriter.AddValue("PrimaryInteropAssemblyName", assembly.FullName); if (!String.IsNullOrEmpty(codebase)) { keyWriter.AddValue("PrimaryInteropAssemblyCodeBase", codebase); } } }
/// <summary> /// Writes the entries needed to register a class type to the registry file. /// </summary> /// <param name="type">Type to write.</param> /// <param name="codebase">Optional codebase, if it needs to be written.</param> /// <param name="rootKeyName">Name of root key where to add types.</param> /// <param name="writer"><see cref="RegistryFileWriter"/> used to write to the /// registry file.</param> private void WriteClassInRegistryFile(Type type, string codebase, string rootKeyName, RegistryFileWriter writer) { Debug.Assert(type != null); Debug.Assert(!String.IsNullOrEmpty(rootKeyName)); Debug.Assert(writer != null); // For class types, we add ProgID entries AND CLSID entries. string clsid = type.GUID.ToString("B").ToUpper(CultureInfo.InvariantCulture); string progId = regServices.GetProgIdForType(type); string keyPath; // First ProgID if class has one. Link it to CLSID. if (!String.IsNullOrEmpty(progId)) { keyPath = String.Format(@"{0}\{1}", rootKeyName, progId); using (RegistryKeyWriter keyWriter = writer.AddKey(keyPath)) { keyWriter.AddDefaultValue(type.FullName); } keyPath += @"\CLSID"; using (RegistryKeyWriter keyWriter = writer.AddKey(keyPath)) { keyWriter.AddDefaultValue(clsid); } } // Now CLSID. First write class name in root CLSID key. keyPath = String.Format(@"{0}\CLSID\{1}", rootKeyName, clsid); using (RegistryKeyWriter keyWriter = writer.AddKey(keyPath)) { keyWriter.AddDefaultValue(type.FullName); } // Now write all infos in InprocServer32. keyPath += @"\InprocServer32"; using (RegistryKeyWriter keyWriter = writer.AddKey(keyPath)) { keyWriter.AddDefaultValue("mscoree.dll"); keyWriter.AddValue("ThreadingModel", "Both"); keyWriter.AddValue("Class", type.FullName); keyWriter.AddValue("Assembly", assembly.FullName); keyWriter.AddValue("RuntimeVersion", assembly.ImageRuntimeVersion); if (codebase != null) { keyWriter.AddValue("CodeBase", codebase); } } // Also write versioned key. keyPath += String.Format(@"\{0}", assembly.GetName().Version); using (RegistryKeyWriter keyWriter = writer.AddKey(keyPath)) { keyWriter.AddValue("Class", type.FullName); keyWriter.AddValue("Assembly", assembly.FullName); keyWriter.AddValue("RuntimeVersion", assembly.ImageRuntimeVersion); if (codebase != null) { keyWriter.AddValue("CodeBase", codebase); } } // If class has a ProgID, link the CLSID to it. if (!String.IsNullOrEmpty(progId)) { keyPath = String.Format(@"{0}\CLSID\{1}\ProgId", rootKeyName, clsid); using (RegistryKeyWriter keyWriter = writer.AddKey(keyPath)) { keyWriter.AddDefaultValue(progId); } } // Finally, add implemented categories. keyPath = String.Format(@"{0}\CLSID\{1}\Implemented Categories\{2}", rootKeyName, clsid, regServices.GetManagedCategoryGuid().ToString("B").ToUpper(CultureInfo.InvariantCulture)); writer.AddEmptyKey(keyPath); }