//
you're reading...
COM, Programming Issues/Tips

Perform Custom Action during Registration of a Managed COM Server.

1. Introduction.

1.1 When a COM-visible managed class library is COM registered via regasm.exe, it is possible to perform various custom activities, e.g. adding additional registry keys/values.

1.2 In fact, just about anything can be performed, e.g. reading/writing data to a file, launch external processes, etc.

1.3 Then, if the class library is unregistered, reverse activities can be performed to undo the work done during registration.

1.4 This blog provides a guideline on how this can be done.

2. The ComRegisterFunction and the ComUnregisterFunction Attributes.

2.1 The way to do this is to use the ComRegisterFunctionAttribute and the ComUnregisterFunctionAttribute.

2.2 Each C# class that will be registered must supply 2 methods. One is to be called when the assembly is COM registered. The other is to be called when the assembly is unregistered.

2.3 The first (registration) method must be marked with the ComRegisterFunctionAttribute and the second (unregistration) method must be marked with the ComUnregisterFunctionAttribute.

2.4 Note that both methods of the registration/unregistration pair must be provided so that work done during registration may be undone during unregistration.

2.5 Furthermore, each class to be custom registered must provide its own pair of registration/unregistration methods. There is no central registration/unregistration method that is called for each and every class.

2.6 According to the MSDN documentation for the ComRegisterFunctionAttribute and the ComUnregisterFunctionAttribute, methods marked with these attributes can have any visibility (public, private, and so on), but must be static and must take a single Type parameter for the type to register.

2.7 The sample codes in the next section will demonstrate this.

3. Sample Codes.

3.1 Listed below is a sample C# class which is targeted for COM export :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace CSCOMServer01
{
    [ComVisible(true)]
    [Guid("8B7D1DEB-A89E-4e03-BBEB-D66B375713DD")]
    [ProgId("CSCOMServer01.ManagedCOMClass01")]
    public class ManagedCOMClass01
    {
        public ManagedCOMClass01()
        {
        }

        ~ManagedCOMClass01()
        {
        }

        public void Method01()
        {
        }

        // Each class which is to have custom registration performed
        // must contain its own ComRegisterFunctionAttribute marked
        // function.
        [ComRegisterFunction]
        public static void RegisterFunction(Type t)
        {
            // Perform custom action during registration
            // of assembly.

            // Add a custom key to the registry
            Microsoft.Win32.RegistryKey key;
            key = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(
              "CLSID\\" + t.GUID.ToString("B") + "\\My Custom Information");

            if (key != null)
            {
                // Add default value to the custom key.
                key.SetValue(null, "Custom Information 01", Microsoft.Win32.RegistryValueKind.String);
                key.Close();
            }
        }

        // Each class which is to have custom unregistration performed
        // must contain its own ComUnregisterFunctionAttribute marked
        // function.
        [ComUnregisterFunction]
        public static void UnregisterFunction(Type t)
        {
            // Perform custom action during unregistration
            // of assembly.
            //
            // This method should basically undo the work
            // done in the registration function.
            Microsoft.Win32.Registry.ClassesRoot.DeleteSubKey(
              "CLSID\\" + t.GUID.ToString("B") + "\\My Custom Information", false);
        }
    }
}

The code above shows a COM-visible C# class which is to be COM-exported. It provides 2 static methods RegisterFunction() and UnregisterFunction() method which are the custom COM registration and unregistration methods respectively.

3.2 Here are some pertinent points regarding the above code :

  • The custom registration method will attempt to create an additional subkey in the registry subkey for the COM class named “My Custom Information”.
  • Additionally, a string value “Custom Information 01” will be set for the default value of this new subkey.
  • The custom unregistration method will delete the “My Custom Information” subkey.
  • Note that each class that performs custom registration must contain only one ComRegisterFunctionAttribute’d method. Providing more than one such method will cause an exception to be thrown.
  • Similarly, each class that performs custom unregistration must contain only one ComUnregisterFunctionAttribute’d method. Providing more than one such method will cause an exception to be thrown.

3.3 Note that any action may be performed inside a custom registration/unregistration method as the following example shows :

[ComVisible(true)]
[Guid("E712B06C-9D20-4319-8247-C0CB226520D8")]
[ProgId("CSCOMServer01.ManagedCOMClass02")]
public class ManagedCOMClass02
{
  public ManagedCOMClass02()
  {
  }

  ~ManagedCOMClass02()
  {
  }

  public void Method01()
  {
  }

  [ComRegisterFunction]
  public static void RegisterFunction(Type t)
  {
    // Perform custom action during registration
    // of assembly.
    string strMessage = string.Format("RegisterFunction() for type : {0:S}.", t.ToString());
    MessageBox.Show(strMessage.ToString());
  }

  [ComUnregisterFunction]
  public static void UnregisterFunction(Type t)
  {
    // Perform custom action during unregistration
    // of assembly.
    //
    // This method should basically undo the work
    // done in the registration function.
    string strMessage = string.Format("UnregisterFunction() for type : {0:S}.", t.ToString());
    MessageBox.Show(strMessage.ToString());
  }
}

The custom registration and unregistration methods of this ManagedCOMClass02 class simply displays a message box.

Advertisements

About Lim Bio Liong

I've been in software development for nearly 20 years specializing in C , COM and C#. It's truly an exicting time we live in, with so much resources at our disposal to gain and share knowledge. I hope my blog will serve a small part in this global knowledge sharing network. For many years now I've been deeply involved with C development work. However since circa 2010, my current work has required me to use more and more on C# with a particular focus on COM interop. I've also written several articles for CodeProject. However, in recent years I've concentrated my time more on helping others in the MSDN forums. Please feel free to leave a comment whenever you have any constructive criticism over any of my blog posts.

Discussion

2 thoughts on “Perform Custom Action during Registration of a Managed COM Server.

  1. Thanks so much for putting this together. It’s exactly what I was looking for.

    Posted by Notre | April 12, 2012, 7:34 pm
  2. HI i’ll try to make next code to register additional information for IShellIconOverlayIdentifier interface:

    [ComRegisterFunction]
    public static void Register(Type t)
    {
    RegistryKey rk = Registry.LocalMachine.CreateSubKey(@”SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\”
    + t.Name + @”\”);
    rk.SetValue(string.Empty, t.GUID.ToString(“B”).ToUpper());
    rk.Close();
    ShellInterop.SHChangeNotify(0x08000000, 0, IntPtr.Zero, IntPtr.Zero);

    }

    But there is no my Key in Registry. If i call the same code from othere application it’s work correct. But with Regasm not worked.

    Posted by vladimir | June 11, 2013, 9:57 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: