private void AddClassToRegistryTable(InstallerTable registryTable, string classGuid, string className, TypeLibRecord tlbRecord) { string registryClassIdKeyPart = @"CLSID\" + classGuid + @"\"; // Insert the Class registryTable.InsertRecord(CreateIdentityGuid(), 0, registryClassIdKeyPart + "InprocServer32", "Class", className, tlbRecord.AssemblyComponent); registryTable.InsertRecord(CreateIdentityGuid(), 0, registryClassIdKeyPart + "InprocServer32", "ThreadingModel", "Both", tlbRecord.AssemblyComponent); // clr version should have format major.minor.build registryTable.InsertRecord(CreateIdentityGuid(), 0, registryClassIdKeyPart + "InprocServer32", "RuntimeVersion", "v"+ Project.TargetFramework.ClrVersion, tlbRecord.AssemblyComponent); registryTable.InsertRecord(CreateIdentityGuid(), 0, registryClassIdKeyPart + "InprocServer32", "Assembly", tlbRecord.AssemblyName.FullName, tlbRecord.AssemblyComponent); registryTable.InsertRecord(CreateIdentityGuid(), 0, registryClassIdKeyPart + "Implemented Categories", "+", null, tlbRecord.AssemblyComponent); registryTable.InsertRecord(CreateIdentityGuid(), 0, registryClassIdKeyPart + @"Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}", "+", null, tlbRecord.AssemblyComponent); }
/// <summary> /// Enumerates the registry to see if an assembly has been registered /// for COM interop, and if so adds these registry keys to the Registry /// table, ProgIds to the ProgId table, classes to the Classes table, /// and a TypeLib to the TypeLib table. /// </summary> /// <param name="database">The MSI database.</param> /// <param name="fileName">The Assembly filename.</param> /// <param name="fileAssembly">The Assembly to check.</param> /// <param name="componentName">The name of the containing component.</param> /// <param name="assemblyComponentName">The name of the containing component's assembly GUID.</param> /// <param name="classTable">View containing the Class table.</param> /// <param name="progIdTable">View containing the ProgId table.</param> private void CheckAssemblyForCOMInterop(InstallerDatabase database, string fileName, Assembly fileAssembly, string componentName, string assemblyComponentName, InstallerTable classTable, InstallerTable progIdTable) { AssemblyName asmName = fileAssembly.GetName(); string featureName = (string)featureComponents[componentName]; string typeLibName = Path.GetFileNameWithoutExtension(fileName) + ".tlb"; string typeLibFileName = Path.Combine(Path.GetDirectoryName(fileName), typeLibName); bool foundTypeLib = false; // Register the TypeLibrary RegistryKey typeLibsKey = Registry.ClassesRoot.OpenSubKey("Typelib", false); string[] typeLibs = typeLibsKey.GetSubKeyNames(); foreach (string typeLib in typeLibs) { RegistryKey typeLibKey = typeLibsKey.OpenSubKey(typeLib, false); if (typeLibKey == null) continue; string[] typeLibSubKeys = typeLibKey.GetSubKeyNames(); foreach (string typeLibSubKey in typeLibSubKeys) { RegistryKey win32Key = typeLibKey.OpenSubKey(typeLibSubKey + @"\0\win32"); if (win32Key == null) continue; string curTypeLibFileName = (string)win32Key.GetValue(null, null); if (curTypeLibFileName != null) { if (String.Compare(curTypeLibFileName, typeLibFileName, true) == 0) { Log(Level.Info, "Configuring '{0}' for COM Interop...", typeLibName); TypeLibRecord tlbRecord = new TypeLibRecord( typeLib, typeLibFileName, asmName, featureName, assemblyComponentName); typeLibRecords.Add(tlbRecord); foundTypeLib = true; win32Key.Close(); break; } } win32Key.Close(); } typeLibKey.Close(); if (foundTypeLib) break; } typeLibsKey.Close(); // Register CLSID(s) RegistryKey clsidsKey = Registry.ClassesRoot.OpenSubKey("CLSID", false); string[] clsids = clsidsKey.GetSubKeyNames(); foreach (string clsid in clsids) { RegistryKey clsidKey = clsidsKey.OpenSubKey(clsid, false); if (clsidKey == null) continue; RegistryKey inprocKey = clsidKey.OpenSubKey("InprocServer32", false); if (inprocKey == null) { clsidKey.Close(); continue; } string clsidAsmName = (string)inprocKey.GetValue("Assembly", null); if (clsidAsmName != null) { if (asmName.FullName == clsidAsmName) { // Register ProgId(s) RegistryKey progIdKey = clsidKey.OpenSubKey("ProgId", false); if (progIdKey != null) { string progId = (string)progIdKey.GetValue(null, null); string className = (string)clsidKey.GetValue(null, null); if (progId != null) { progIdTable.InsertRecord(progId, null, clsid, className, null, 0); classTable.InsertRecord(clsid, "InprocServer32", assemblyComponentName, progId, className, null, null, null, 0, null, null, featureName, 0); } progIdKey.Close(); progIdKey = null; } } } inprocKey.Close(); clsidKey.Close(); } clsidsKey.Close(); }