Skip to content

Creating an ActiveX control in .Net using C#

May 31, 2011

Create a new Class Library project in Visual Studio 2010

* This post is taken from: Creating an ActiveX control in .Net using C# by Olav Aukan

  1. Start-Run-devenv or Click- Microsoft Visual Studio 2010.
  2. After starting Visual Studio click File – New – Project and select Class Library under C#.
  3. Call the project ‘AxControls’ and click OK.
Class

Class

Create a new class that inherits from UserControl

  1. Rename ‘Class1.cs’ to “HelloWorld.cs”, making sure to rename the class name as well.
  2. Add a project reference to System.Windows.Forms.
Reference

Reference

Create a new interface that exposes the controls methods and properties to COM interop

  1. Right click the project in Visual Studio and click Add –> New Item.
  2. Select ‘Interface’ from the list of components, name it ‘IHelloWorld.cs’ and click Add.
iHelloWorld

iHelloWorld

3.  Edit the ‘IHelloWorld.cs’ file so it looks like this:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace AxControls
{
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    [Guid("E66C39CB-BB8B-4738-AA0E-5E0D1F2DB230")]
    public interface IHelloWorld
    {
        string GetText();
    }
}
[ComVisible(true)] makes the interface visible to COM.
[Guid("E66C39CB-BB8B-4738-AA0E-5E0D1F2DB230")] let's us manually assign a GUID to the interface. Use guidgen.exe to generate your own.

Make the control class implement the new interface

Make the HelloWorld class implement the IHelloWorld interface and have the GetText() method return a string of your choice. This is what the file might look like:

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

namespace AxControls
{
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [Guid("D100C392-030A-411C-92B6-4DBE9AC7AA5A")]
    [ProgId("AxControls.HelloWorld")]
    [ComDefaultInterface(typeof(IHelloWorld))]
    public class HelloWorld : UserControl, IHelloWorld
    {
        #region IHelloWorld Members
        public string GetText()
        {
            return "Hello ActiveX World!";
        }
        #endregion
    }
}

Mark the control as safe for scripting and initialization

By default IE will not allow initializing and scripting an ActiveX control unless it is marked as safe. This means that we won’t be able to create instances of our ActiveX class with JavaScript by default. We can get around this by modifying the browser security settings, but a more elegant way would be to mark the control as safe. Before you do this to a “real” control, be sure to understand the consequences. . We will mark the control as safe by implementing the IObjectSafety interface.

  1. Right click the project in Visual Studio and click Add -> New Item.
  2. Select ‘Interface’ from the list of components, name it ‘IObjectSafety.cs’ and click Add.
iObjectSafety

iObjectSafety

3.   Edit the ‘IObjectSafety.cs’ file so it looks like this:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace AxControls
{
    [ComImport()]
    [Guid("51105418-2E5C-4667-BFD6-50C71C5FD15C")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IObjectSafety
    {
        [PreserveSig()]
        int GetInterfaceSafetyOptions(ref Guid riid, out int pdwSupportedOptions, out int pdwEnabledOptions);
        [PreserveSig()]
        int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions);
    }
}
4.  Make the HelloWorld class implement the IObjectSafety interface. The end result should look something like this:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace AxControls
{
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [Guid("D100C392-030A-411C-92B6-4DBE9AC7AA5A")]
    [ProgId("AxControls.HelloWorld")]
    [ComDefaultInterface(typeof(IHelloWorld))]
    public class HelloWorld : UserControl, IHelloWorld, IObjectSafety
    {
        #region IHelloWorld Members
        public string GetText()
        {
            return "Hello ActiveX World!";
        }
        #endregion
        #region IObjectSafety Members
        public enum ObjectSafetyOptions
        {
            INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001,
            INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002,
            INTERFACE_USES_DISPEX = 0x00000004,
            INTERFACE_USES_SECURITY_MANAGER = 0x00000008
        };

        public int GetInterfaceSafetyOptions(ref Guid riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
        {
            ObjectSafetyOptions m_options = ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_CALLER | ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_DATA;
            pdwSupportedOptions = (int) m_options;
            pdwEnabledOptions = (int) m_options;
            return 0;
        }
        public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
        {
            return 0;
        }
        #endregion
    }
}

Create a .msi installer for the control

Before an ActiveX control can be used it must be installed and registered on the client. This can be done in a number of ways, from manually editing the registry to using regasm.exe, but we’re going to create a Vistual Studio setup project to handle the installation for us.

  1. Right click the Visual Studio solution, select Add -> New Project and select Setup Project under Other Project Types.
  2. Call the project ‘AxControlsInstaller’ and click OK.
AxControlsInstaller

AxControlsInstaller

3.        Right click the ‘AxControlsInstaller’ project, select Add -> Project Output, select ‘Primary output’ from the ‘AxControls’

Primary Output

Primary Output

project and Click ‘OK’.

  1. Right click ‘Primary output from AxControls (Active)’ and select Properties.
  2. Change the Register property from ‘vsdrpDoNotRegister’ to ‘vsdrpCOM’.
  3. Right click the ‘AxControlsInstaller’ project and select Build.
The installer should now be located in the AxControlsInstaller’s output folder (bin\Debug or bin\Release). In the corporate domain this .msi file can de run manually on the client, or automatically with a Group Policy.

Package the installer in a .cab file for web deployment

For public web sites we obviously can’t deploy our ActiveX control to the client with a Group Policy. In this case we’re gonna have to use Internet Explores built-in ability to download and install controls that are packaged in .cab files.

  1. Download the Microsoft Cabinet Software Development Kit.
  2. Unpack the kit to a local folder and copy Cabarc.exe to the ‘AxControlsInstaller’ folder.
  3. Create a new file named ‘AxControls.inf’ in the ‘AxControlsInstaller’ folder and add the following content:
[version]
signature="$CHICAGO$"
AdvancedINF=2.0

[Add.Code]
AxControlsInstaller.msi=AxControlsInstaller.msi

[AxControlsInstaller.msi]
file-win32-x86=thiscab
clsid={1FC0D50A-4803-4f97-94FB-2F41717F558D}
FileVersion=1,0,0,0

[Setup Hooks]
RunSetup=RunSetup

[RunSetup]
run="""msiexec.exe""" /i """%EXTRACT_DIR%\AxControlsInstaller.msi""" /qn
  • Click the AxControlsInstaller project and then press F4 or (View -> Properties Window if it’s not visible).
  • Click the ‘…’ button next to the PostBuildEvent property and add the following content:
"$(ProjectDir)\CABARC.EXE" N "$(ProjectDir)AxControls.cab" 
"$(ProjectDir)AxControls.inf" "$(ProjectDir)$(Configuration)\AxControlsInstaller.msi"
  • Right click the ‘AxControlsInstaller’ project and select Build.
  • There should now be a ‘AxControls.cab’ file in the ‘AxControlsInstaller’ folder.

Ininitalize and test the control with JavaScript

  1. Right click the AxControls solution, select Add -> New Project and select ‘ASP.Net Web Application’ under ‘Web’.
  2. Call the project ‘WebAppTest’ and click OK.
  3. Right click the ‘WebAppTest’ project, select Add -> New Item and select ‘HTML Page’.
  4. Call it ‘index.html’ and click OK.
  5. Add the following content to index.html:
<html>
    <head>

        <objectname="axHello" style='display:none' id='axHello' classid='CLSID:D100C392-030A-411C-92B6-4DBE9AC7AA5A'
 codebase='AxControls.cab#version=1,0,0,0'></object>
      <script language="javascript">

        <!-- Load the ActiveX object  -->
        var x = new ActiveXObject("AxControls.HelloWorld");

        <!-- Display the String in a messagebox -->
        alert(x.GetText());

      </script>
    </head>
    <body>
    </body>
</html>
Note that 'classid' matches the GUID of the HelloWorld control.
  • Right click ‘index.html’ and select ‘Set as start page’.
  • Right click the ‘WebAppTest’ project and select ‘Set as startup project’.
  • Copy ‘AxControls.cab’ from the ‘AxControlsInstaller’ folder to the same folder as index.html.
  • Uninstall the control from the client by going to Control Panel -> Add or Remove.., selecting ‘AxControlsInstaller’ on the list and clicking Uninstall. This forces Internet Explorer to download and install the .cab file and is an important step in case you’ve already installed the control.
  • Run the application (F5). This will open ‘index.html’ in Internet Explorer.
  • Internet Explorer will display a security warning, asking if you want to install ‘AxControls.cab’. Click Install.
install

Install ActiveX

When the page loads it should display a message box with the string you defined in HelloWorld’s GetText() method.
Hello ActiveX World!
About these ads

From → .Net

36 Comments
  1. Sandeep Gupta permalink

    Please let me know what should I do to create an upgrade of the same ActiveX Control?

    I tried incrementing Class library version & MSI version but it failed to install.

  2. Sandeep Gupta permalink

    Exactly which GUID you are refering to from above example?

  3. vrushali permalink

    hi,
    i have used this method to access the ActiveX control in web server it’s working fine .
    But when i have put something into the user control it will not display anything ,message box displayed into the web page but i want to access the user control design can you please tell me how to access the ActiveX control into the web page through web server .

  4. Sachin Suryawanshi permalink

    Realy nice Article… Its working fine..
    Using this code i have find the MAC address of Client Machine.

    But when i add this .cab file in my web application and run it on server then in Internet explorer it does not show me the Install option. Its showing me the message like

    “Windows has blocked this software because it cant verify the publisher”

    I have done all settings in my IE browser version IE 8

    Hence i have install this file manualy and run the application.

    Then its working fine.

    Thanks.

    • kannan permalink

      Dear Sachin Suryawanshi, can you share the cab file to Get client MAC address.

  5. Cleber permalink

    Haseeb, this is an excellent article. I searched at Internet and I found only the yours. Congratulations!!

  6. Cleber permalink

    Hi, I would like to learn more about “Mark the control as safe for scripting and initialization”. I did some tests with and without the interface (IObjectSafety) implementaion and I can not see the diference. In both cases IE browser (IE6, 7 and 8) alert me that is not safe.

    For tests purposes, I am using a fake signing to the CAB following instructions on this blog http://blogs.msdn.com/b/thehelpguy/archive/2010/01/22/how-to-sign-your-cab-files.aspx. Can’t I see the difference due this?

    I added my localhost into trusted sites and reduced the security to run the activeX.
    Tks,

  7. Alex permalink

    Good work!!!

  8. programmer permalink

    Thank you for very useful article. However, when I created and registered the test ActiveX control using “regasm name.dll /codebase”, I got error trying to instantiate it from javascript: “Automation server cann’t create object”. How can I make it work?

  9. Hi,
    I used this sample and it works with vs2010. Now I need to make a window that contains a datagridview into an OCX for an older development system Clarion8 that only has COM for OCXs. I did as you have above but added a form with datagridview. Compiles/registers great but when I add the generated COM object to the child window of a midi app i get:Unable to get window handle for AxControl control. Windowless ActiveX controls are not supported. I’ve been searching for days trying to figure it out. Most suggested fix is turn off DEP. Obviously can’t do that for commercial app. Is it possible to make an OCX Custom Control for the DataGridView using C#.net? It needs to behave like OCX that would be used in VB6. (Really Clarion8 but doubt you heard of that)Thanks Doug

  10. Hi, very useful information, do you know how is the comand line in “PosBuiltEvent”, because, visual studio 2010 doesn’t have it. MAKECAB is the replace, but how is the code with it?

  11. Steve permalink

    This works as is when called from *.vbs or other CScript applicaions.
    How do we enable to be called from Internent Exploders JavaScript when compiled as .NET 4.0 (Client profile) project?

    As is the following error: “Can not create object.”

    var oAx = new ActiveXObject(“AxControls.HelloWorld”);

    • did you solve this? i have the same error JavaScript runtime error: Automation server can’t create object

  12. heytherelameman permalink

    You are my new best friend!!!! It works great! :)

  13. Tony permalink

    Is there a way to get a UI to display? I added a simple button to the HelloWorld control but it doesn’t show whether in a windows form or on a web page. I need my UI to be hosted in an activeX control on a web page. Any ideas?

  14. Owais permalink

    Thanks, It was a very good article. Integrated Samsung Bixolon SRP-350Plus printer in Internet Explorer for a web site with the help of this.
    It would be great if you can point at settings of Internet explorer as control need’s that and automated method described here didn’t work out.

  15. Farooq permalink

    It worked like a charm! Thanks bro, I think I will go through all your articles :)

  16. I didn’t work !! the dll couldn’t self-register after ActiveX installation and javascript doesn’t show the message.

    The complete solution needs to set “true” the option “Register for COM interop” in AxControls “Project properties” and setting “[assembly: ComVisible(true)]” instead of false in AssemblyInfo.cs in “Properties” folder of the same project.

    For additional info:

    http://stackoverflow.com/questions/3360160/how-do-i-create-an-activex-com-in-c

    Good luck.

  17. Elsa permalink

    the interface of this website is awful!
    the lines which are too long are cut !
    look at the “Package the installer in a .cab file for web deployment” chapter,
    the line “”$(ProjectDir)AxControls.inf” “$(ProjectDir)$(Configuration)\AxControlsInstaller” is cut when you are at 100%.
    if we zoom out at 85%, what we see ? => “AxControlsInstaller.msi”

    and it that all long

  18. Elsa permalink

    Ty for modify the interface
    this is much better to read the code

  19. Shalabh permalink

    Thanks for this post.. Great work!

  20. Rajesh permalink

    Hello Sir,
    One of the best and useful forum for creating activex control. But there is a problem on the step when we create the cab file. In my VS2008 pro it made a corrupted cab. So else one can execute the command ” CABARC.EXE N AxControls.cab AxControls.inf Debug\AxControlsInstaller.msi” from cmd run as admin and have the cab file generated.
    Anyways was successful in completing my project to make a screenshot Activex. Thanks.

  21. Areeb permalink

    This ActiveX is worked with html page when I save it and run. but when I include it with asp.net and try to browes from iis I am getting error.
    “HTTP Error 500.19 – Internal Server Error
    The requested page cannot be accessed because the related configuration data for the page is invalid.”
    its Urgent please reply ASAP

  22. Martin Lines permalink

    Fantastic article – I now have an IE addin that calls the active X to write registry values. Thank you so much for publishing

  23. subhash permalink

    Great man ur article is excellent. Thank u for sharing ur knowledge. Honorable job.

  24. Flauzer permalink

    I’ve a problem with debuggin the COM object from VS2010.

    After setting the class library Debug option to start an external program (a simple w32 app client exe) , ..nothing….everything works well but i can’t debug my C# code…

    Any suggest?

    Thanks in advance.

  25. COMSurrogate permalink

    VS 2010 C#4. Simply all works well but I can’t debug the assembly….Any suggestions?

  26. Ankit permalink

    Great..! I have followed all the steps that you have mentioned. When i run HTML page from file system it works. but when I hosted it on IIS and then tried to browse it failed. I think there is something wrong to IIS or IE. I’ve never done this before so could someone guide me or point me to an aricle that would walk me through this problem.

  27. Phil permalink

    This is hands down the best explanation on the net of creating an active-x control. I will be doing a on prem deployment and all works great.

    The only question I have is that I get the warning “An ActiveX control on this page might not be safe…”

    I added the safe control code and I am using IE9. Is there any way to sign my dll and trust it IE to remove this warning or a IE setting for just this AX / DLL?

    Thanks again for taking the time to share this!
    Phil

  28. Mrunal Buch permalink

    Hi,

    Can I have 2 side by side versions of this ? I have 2 sites supporting different versions.

    I am having some issues. following are the details

    Example:

    version 1.0 = Site 1 = GetText() returns “Hello Version 1.0″
    version 1.1 = Site 2 = GetText() returns “Hello Version 1.1″

    browser: I.E 9+

    1) Open Site 1
    2) Shows Hello Version 1.0
    3) Without closing the browser hot Site 2
    4) Still shows Hello Version 1.0 –> This should be Hello Version 1.1

    If I close the browser and hot Site 2 it is working fine

    Thanks

  29. Error 8 The command “”D:\C#_sample_projects\AxControls\AxControls\\CABARC.EXE” N “D:\C#_sample_projects\AxControls\AxControls\AxControls.cab”
    “D:\C#_sample_projects\AxControls\AxControls\AxControls.inf” “D:\C#_sample_projects\AxControls\AxControls\Debug\AxControlsInstaller.msi”

    ” exited with code 9009. AxControls

  30. LOKESH permalink

    Super i liked very much i got out put

  31. amb123 permalink

    Note that the Guid for IObjectSafety.cs MUST BE:
    [Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]

  32. Thanks a ton for spending time to publish “Creating an ActiveX
    control in .Net using C# | Haseeb Akhtar’s Blog”. Thank you so much yet again ,Lucie

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

Follow

Get every new post delivered to your Inbox.

Join 47 other followers

%d bloggers like this: