Click here to Skip to main content
15,867,594 members
Articles / Programming Languages / C#

The Legend of Forever Alone Guy Who Wrote Himself a Wrapper for C# to Use as ActiveX

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
8 Jun 2012CPOL4 min read 8K   6   2
The legend of Forever Alone Guy who wrote himself a wrapper for C# to use as ActiveX

Woa, me and my classmates are planning to go to the cinema to enjoy "Madagascar 3" next week. It's fantastic because the girl I like loves this movie so much. I invited her to join us but she couldn't, that's so sad. It's not the worst thing when I realized that all my guys would go with their girlfriends and I would go alone. In my band of 6 or 7, I am the only one who is single. Ridiculous. Really I am a bad mood, and I can't work for my final exam until I make something crazy. I decide to call some C# code in a VBScript @@, thanks stackoverflow stuff for helping.

Target

Wrap a .NET user control in an ActiveX class.

Solution

1. Create the Class Library in VS 2010

Open your Visual Studio in Administrator mode please (some system access will be made). Create a new, empty Class Library project and add into it a Windows Form.

Drag to the form 1 button named btnDo and 1 label named lblResult. Then bind the button clicking event with this code:

C#
private void radButton1_Click(object sender, EventArgs e)
        {
            this.lblResult.Text = 
               "I am a .NET user control happily living \ninside an ActiveX container. Cheers.";
        }

I'm sure you all know the meaning of that code. If you don't, go to the book store and pick any book about C# programming. I suggest the thin one because it should be cheaper.

Ok, let's move to the next part.

2. Setting for Project

Open the library's Property Settings window and select the Application tab. You should see an “Assembly Information…” button - click on it and it will open a dialog form with various assembly settings. You will see a checkbox named “Make assembly COM-visible”. The checkbox must be checked. You would also see a GUID field. Let's do something with it. Click menu Tools -> Create GUID. In the showing dialog, click Copy. Now close this dialog and paste to GUID field in Property Settings. It is used to set the ID of the typelib if this project is exposed to COM.

Image 1

Figure 1 - Settings

Now, choose tab Build. If you want automatic registration of the freshly created ActiveX wrapper, you should check the “Register for COM interop” checkbox. It runs Regasm.exe after every build to register the types with COM (which you probably shouldn't do until you're stable because your COM GUIDs will change whenever you change the methods unless you specify GUIDs explicitly, so your registry could end up with a lot of registration junk for versions that will never be used). Last thing to do here is to provide your ActiveX a strong name key. Let do it with Microsoft style. The steps below have been copied from http://msdn.microsoft.com/en-us/library/aa559684%28v=bts.20%29.aspx with a small modification.

To create a strong name key file:

  1. Click Start, point to Programs, point to Microsoft Visual Studio 2010, point to Visual Studio Tools, and then click Visual Studio 2010 Command Prompt.
  2. At the command prompt, change directory to your project folder.
  3. At the command prompt, type sn -k ActivX.snk, and then press ENTER.

Now, in the Property Settings, choose Signing tab and Browse ActivX.snk as Strong name key file. Done, now back to the code for a few additions.

3. Thank God We have Interop Services

At the beginning of your Window Form class, insert the below code:

C#
[ProgId("ActiveXTestLibrary.UserControl")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[ComVisible(true)]

The ProgIdattribute which provides a unique name for the created ActiveX interface. You can change ActiveXTestLibrary.UserControl by other string that describes your ActiveX function.

The second ClassInterface attribute states whether and how a COM interface will be generated for the managed assembly. The last ComVisible attibute controls accessibility of member true to COM.

Also you can provide static methods that are invoked when the ActiveX is registered or unregistered through the Regasm.exe:

C#
[ComRegisterFunction()]
public static void RegisterClass(string key)
{
    StringBuilder sb = new StringBuilder(key);
    sb.Replace(@"HKEY_CLASSES_ROOT\", "");

    RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);

    RegistryKey ctrl = k.CreateSubKey("Control");
    ctrl.Close();

    RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
    inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
    inprocServer32.Close();

    k.Close();
}

[ComUnregisterFunction()]
public static void UnregisterClass(string key)
{
    StringBuilder sb = new StringBuilder(key);
    sb.Replace(@"HKEY_CLASSES_ROOT\", "");

    RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);

    if (k == null)
    {
        return;
    }
    k.DeleteSubKey("Control", false);

    RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);

    inprocServer32.DeleteSubKey("CodeBase", false);

    inprocServer32.Close();
}

The methods have predefined names (RegisterClass and UnregisterClass) and should be marked respectively with the ComRegisterFunction/ComUnregisterFunction attributes. Here, we register the category of the ActiveX as a UI control.

4. Write Something to Show the Form

To show a form, you need to start a message loop by calling Application.Run:

C#
[ComVisible(true)]
public void Hello()
{
    Application.Run(this);
    MessageBox.Show("Hello text", "Test");
}

The Show() function will show the form and immediately exit. Application.Run() will not exit until the form is closed.

Now build the project. You will have DLL and your DLL has already been registered to System.

5. Test

Open a text editor for writing about 4, 5 lines of VBS code. I like notepad++ for Window and gedit for Ubuntu, but what you use is up to you. Paste that code, save it as Test.vbs, run the file and see what happens.

VB.NET
Sub main
    set objTest = CreateObject("ActiveXTestLibrary.UserControl")
    objTest.Hello
    Do While (10 > 9)
    Loop
end Sub

call main

Image 2

Figure 2 - C# form is called by vbs

Then click the button. :)

Image 3

Figure 3 - C# event is listened

Thanks for reading a very boring post. Here is your gift: my source code.

Image 4

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Vietnam Vietnam
Oops!

Comments and Discussions

 
GeneralMy vote of 5 Pin
jfriedman12-Jun-12 4:29
jfriedman12-Jun-12 4:29 
QuestionLoved the title Pin
JoseMenendez8-Jun-12 7:52
JoseMenendez8-Jun-12 7:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.