When using regasm to register an assembly for COM interop, one of things it does is create a HKEY_CLASSES_ROOT\CLSID{000…000} registry key with a default value of the ProgId of the COM class (See MSDN article Registering Assemblies with COM).
Is it possible to specify the string that regasm sets as the default value of the key? I.e. Give it a more meaningful name?
For example:
HKEY_CLASSES_ROOT\CLSID{000…000}\Default = "Descriptive name for my really useful class"
instead of:
HKEY_CLASSES_ROOT\CLSID{000…000}\Default = "An.Obscure.Prog.Id"
I guess it would be possible to tweak the registry values after regasm has set them, but it would be easier if I could just persuade regasm to do it.
I think both question and answer have it wrong. There are three names involved here:
The corresponding entries in the registry are:
CLASSES_ROOT\CLSID\ClassId @= "Human readable name"
CLASSES_ROOT\CLSID\ClassId\ProgId @= "ProgId"
CLASSES_ROOT\ProgId @= "Human readable name"
CLASSES_ROOT\ProgId\CLSID @= "ClassId"
See your own registry for some examples.
If you reflect on regasm.exe, you'll see that it uses Type.FullName as the human readable name, always. This is a pain in the ass because it means you have to set the HRN using a com registration hook. It would have been pretty easy for them to look up the DisplayName attribute, for example, and use this instead. Anyway, here's a helper function that sets the HRN entries. Call it from your registration hook.
For more details on COM registration hooks see http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.comregisterfunctionattribute.aspx
public static void SetHumanReadableName(Type t, string humanReadableName)
{
var classKeyName = string.Format(@"CLSID\{{{0}}}", t.GUID);
var classKey = Registry.ClassesRoot.OpenSubKey(classKeyName, true);
if (classKey == null)
return;
classKey.SetValue(string.Empty, humanReadableName);
// if it has a progid set the HRN on the progid entry too
foreach (ProgIdAttribute progId in t.GetCustomAttributes(typeof(ProgIdAttribute), false))
{
var progIdKey = Registry.ClassesRoot.OpenSubKey(progId.Value, true);
if (progIdKey != null)
progIdKey.SetValue(string.Empty, humanReadableName);
}
}