My simple solution works with some restrictions. Do not calls methods marked by
[ComRegisterFunction]. Also works only for "Any CPU" assemlies.
Assembly assembly = Assembly.LoadFile("drive:\\my.dll");
Type[] Types = assembly.GetExportedTypes();
foreach (Type type in Types)
{
ComVisibleAttribute[] attributes = (ComVisibleAttribute[])type.GetCustomAttributes(typeof(ComVisibleAttribute), false);
if (attributes.Length > 0 && attributes[0].Value)
{
Register(type);
}
}
static void Register(Type type)
{
string ProgID = type.FullName;
string Version = type.Assembly.GetName().Version.ToString();
string GUIDstr = "{" + type.GUID.ToString() + "}";
string keyPath = @"Software\Classes\";
RegistryKey regularx86View = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry32);
RegistryKey regularx64View = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64);
RegistryKey[] keys = {regularx86View.OpenSubKey(keyPath, RegistryKeyPermissionCheck.ReadWriteSubTree, System.Security.AccessControl.RegistryRights.FullControl),
regularx64View.OpenSubKey(keyPath, RegistryKeyPermissionCheck.ReadWriteSubTree, System.Security.AccessControl.RegistryRights.FullControl)};
ProgIdAttribute[] attributes = (ProgIdAttribute[])type.GetCustomAttributes(typeof(ProgIdAttribute), false);
if (attributes.Length > 0)
ProgID = attributes[0].Value;
foreach(RegistryKey RootKey in keys)
{
RegistryKey keyProgID = RootKey.CreateSubKey(ProgID);
keyProgID.SetValue(null, type.FullName);
keyProgID.CreateSubKey(@"CLSID").SetValue(null, GUIDstr);
RegistryKey keyCLSID = RootKey.OpenSubKey(@"CLSID", RegistryKeyPermissionCheck.ReadWriteSubTree, System.Security.AccessControl.RegistryRights.FullControl).CreateSubKey(GUIDstr);
keyCLSID.SetValue(null, type.FullName);
keyCLSID.CreateSubKey("ProgId").SetValue(null, ProgID);
RegistryKey InprocServer32 = keyCLSID.CreateSubKey("InprocServer32");
SetInprocServer(InprocServer32, type, false);
SetInprocServer(InprocServer32.CreateSubKey("Version"), type, true);
keyCLSID.CreateSubKey(@"Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}");
keyCLSID.Close();
}
}
static void SetInprocServer(RegistryKey key, Type type, bool versionNode)
{
if (!versionNode)
{
key.SetValue(null, "mscoree.dll");
key.SetValue("ThreadingModel", "Both");
}
key.SetValue("Class", type.FullName);
key.SetValue("Assembly", type.Assembly.FullName);
key.SetValue("RuntimeVersion", type.Assembly.ImageRuntimeVersion);
key.SetValue("CodeBase", type.Assembly.CodeBase);
}