Olav Aukan Getting information off the Internet is like taking a drink from a fire hydrant…

31Aug/10

Creating an ActiveX control in .Net using C#

A while back I had a client request that I write an ActiveX control for use on their corporate intranet. I had never done this before, and most of the examples I could find online were either really old, incomplete or based on using C++ and MFC. It's safe to say that my C++ skills are not quite up to the job, so for me it was really a requirement to be able to do this with C#. It took me about an hour or two to write the code for the control, but it took almost three days to successfully package and deploy it as a .cab file... So to save others from wasting their time like I did, I'll document my findings in this post.

Steps

  1. - Create a new Class Library project in Visual Studio
  2. - Create a new class that inherits from UserControl
  3. - Create a new interface that exposes the controls methods and properties to COM interop
  4. - Make the control class implement the new interface
  5. - Mark the control as safe for scripting and initialization
  6. - Create a .msi installer for the control
  7. - Package the control in a .cab file for web deployment
  8. - Initialize and test the control with JavaScript

1. Create a new Class Library project in Visual Studio

I'm using Visual Studio 2008, but other versions should work as well.

  1. After starting Visual Studio click File -> New -> Project and select Class Library under C#.
  2. Call the project 'AxControls' and click OK.

2. 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.
  3. Make the HelloWorld class inherit UserControl.

3. 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.
  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("41E85D5D-C57A-4386-B722-4031D0B1E1B7")]
        public interface IHelloWorld
        {
            string GetText();
        }
    }
    

We now have a COM visible interface with a single method 'GetText()'.

[ComVisible(true)] makes the interface visible to COM.
[InterfaceType(ComInterfaceType.InterfaceIsDual)] sets the COM interface type to Dual, see InterfaceTypeAttribute Class on MSDN.
[Guid("41E85D5D-C57A-4386-B722-4031D0B1E1B7")] let's us manually assign a GUID to the interface. Use guidgen.exe to generate your own.

4. 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("1FC0D50A-4803-4f97-94FB-2F41717F558D")]
    [ProgId("AxControls.HelloWorld")]
    [ComDefaultInterface(typeof(IHelloWorld))]
    public class HelloWorld : UserControl, IHelloWorld
    {
        #region IHelloWorld Members

        public string GetText()
        {
            return "Hello ActiveX World!";
        }

        #endregion
    }
}

We now have a COM visible control that implements the IHelloWorld interface.

[ComVisible(true)] makes the control visible to COM, see ComVisibleAttribute Class on MSDN.
[ClassInterface(ClassInterfaceType.None)] indicates that no class interface is generated for this class, see ClassInterfaceType Enumeration on MSDN.
[Guid("1FC0D50A-4803-4f97-94FB-2F41717F558D")] let's us manually assign a GUID to the control, see GuidAttribute Class on MSDN. Use guidgen.exe to generate your own.
[ProgId("AxControls.HelloWorld")] is a "user friendly" ID that we'll use later from JavaScript when initiating the control, see ProgIdAttribute Class on MSDN.
[ComDefaultInterface(typeof(IHelloWorld))] sets IHelloWorld as the default interface that will be exposed to COM, see ComDefaultInterfaceAttribute Class on MSDN.

5. 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. I found an ancient (1996) MSDN article that explains this here. 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.
  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("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
        [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("1FC0D50A-4803-4f97-94FB-2F41717F558D")]
        [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
        }
    }
    

[ComImport()] IObjectSafety is a native interface so we have to redefine it for managed .Net use. This is done with the ComImport() attribute, see ComImportAttribute Class on MSDN.
[Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064")] This is the GUID of the original IObjectSafety interface. Do not change it.
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] sets the COM interface type to Unknown, see InterfaceTypeAttribute Class on MSDN.

This is just a simple implemetation of the IObjectSafety interface that will mark the control as safe. In "real life" there would probably be some sort of logic to determine if the control is safe or not.

6. 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.
  3. Right click the 'AxControlsInstaller' project, select Add -> Project Output, select 'Primary output' from the 'AxControls' project and click OK.
  4. Right click 'Primary output from AxControls (Active)' and select Properties.
  5. Change the Register property from 'vsdrpDoNotRegister' to 'vsdrpCOM'.
  6. 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.

7. 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
    
  4. Click the AxControlsInstaller project and then click the Properties window (View -> Properties Window if it's not visible).
  5. 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"
    
  6. Right click the 'AxControlsInstaller' project and select Build.
  7. There should now be a 'AxControls.cab' file in the 'AxControlsInstaller' folder.

NB! Make sure you use ANSI encoding for the 'AxControls.inf' file or you will be unable to install the control.

8. Initialize 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>
    
            <object name="axHello" style='display:none' id='axHello' classid='CLSID:1FC0D50A-4803-4f97-94FB-2F41717F558D' 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.

  6. Right click 'index.html' and select 'Set as start page'.
  7. Right click the 'WebAppTest' project and select 'Set as startup project'.
  8. Copy 'AxControls.cab' from the 'AxControlsInstaller' folder to the same folder as index.html.
  9. Uninstall the control from the client by going to Control Panel -> Programs and Features, 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.
  10. Run the application (F5). This will open 'index.html' in Internet Explorer.
  11. Internet Explorer will display a security warning, asking if you want to install 'AxControls.cab'. Click Install.
  12. When the page loads it should display a message box with the string you defined in HelloWorld's GetText() method.

If the message box displayed without any more warnings or errors we've implemented everyting correctly.

UPDATE

I forgot to write that you have to register the assembly containing the ActiveX control for COM interop. Right-click the project, select Properties, go to Build and check the "Register for COM interop" checkbox. This should solve the error some of you are seeing about "Automation Server can’t create this object" and similar error messages. You might need to add the [ComVisible(true)] attribute to the methods and properties you are exposing as well, but I haven't had time to test this.

Comments (2201) Trackbacks (8)
  1. Nike Dolphins 17 Ryan Tannehill White Mens Stitched NFL Game Jersey.Visit the official Jerseys store of the
    NFL,NHL,NBA,MLB,soccer,NCAA, supply Nike Dolphins 17 Ryan Tannehill White Mens Stitched NFL Game Jersey from China.
    Discount all kinds of custom sublimated hockey jerseys, free shipping.

  2. Свежие кулинарные рецепты тут cakeblog.su

  3. Новости компьютерного мира тут alvarvas.com

  4. this year astrology for scorpio what is the astrological sign for
    july venus in scorpio vedic astrology astrology dating site
    betelgeuse astrology scorpio man vedic astrology vedic astrology love predictions what is meant by ascendant
    in astrology basics of astrology what astrology sign is july
    6 astrology aquarius monthly chinese astrology horse daily astrological profile virgo horoscopes
    astrology answers astrology 7th house venus secret language of relationships
    astrology venus and mercury conjunction vedic astrology today love astrology gemini name astrology sign family feud 12th house astrology
    rules vedic astrology reports chinese astrology metal goat free will astrology cancer astrology clock 94 astrology true or false quora sai baba astrology my
    astrological portrait osho on astrology predictions is astrology a
    sin free horoscope astrology weekly aries dark
    side astrology list of 12 astrology signs sri ravi shankar guruji astrologer address astrology natal mercury retrograde vedic astrology house aspects health astrology krs what is 8th house in vedic
    astrology history astrology the week ahead astrology 13 sign astrology dates aries horoscope astrology astrology sign for june
    7th predict my death astrology color astrology birthday astrology
    january 17 different astrology signs astrology of today cancer astrology clock 94 astrological houses and lords
    astrology natal mercury retrograde rahu ketu vedic astrology may 14 astrological
    sign kp astrology reader 6 horary born july 29 astrology quantum
    physics and astrology vedic or western astrology accuracy next astronomical events
    what is astrology and astronomy symbols of astrological signs ceres astrology aspect astrology
    for sagittarius daily venus in different houses astrology astrology online education astrological signs associated with body parts adam sandler astrology astrological traits of cancer astrology
    taurus love today astrology zone scorpio daily second marriage in astrology krs astrology tarot correspondence
    astrology meaning of virgo chinese astrological animals astrological mandala sabian symbols 6th house astrology in depth tarot astrology daily horoscope libra astrological air signs name astrology venus in fourth house astrology baby gender astrology prediction my astrological portrait mercury
    in 10 house astrology kudos astrology virgo 12 months astrology ancient egyptian astrology horoscope most accurate vedic astrology site free horoscope astrology tarot numerology true node astrology astrology sign may 27 sep
    21 birthday astrology east meets west astrology free answers to astrological questions instant free exact
    astrology predictions astrology tarot reading grand t-square astrology june 22 birthday astrology free lal kitab astrology remedies astrology types of yogas 12 month astrology signs
    picses astrology astrology venus sign meaning daily aries horoscope astrology
    on the web astrology your birthday today zet astrology synastry astronomy
    telescopes july 21 astrology what does 3rd house
    mean in vedic astrology astrology catalogue astrology
    vs astronomy venn diagram karma astrology and you astrological signs january 17
    cancer astrology sign pictures fish sign astrology astrological qualities of uranus indigo generation astrology traditional astrology glossary astrology
    workshop sydney gold astrology necklace mywebastrologer monthly capricorn horoscope for today california astrology free soulmate astrology what astrological sign is june
    30th the second house astrology mercury in astrology krs
    online astrology prediction based on date of birth what is the 12th house
    in astrology vedic astrology descendant astrological twin flames astrology ascendant sign table august 14 birthday astrology profile phoenix rising astrology group beginner
    astrology straight vancouver astrology aldebaran in vedic astrology astrological sign june 29 new born baby astrology name astrology sign libra
    woman astrology days sextile in vedic astrology what
    is astrologically happening right now astrology sign august 24
    what is the astrology sign for january 23 astrology by date of birth for job
    vedic astrology rahu remedies all astrological signs april 1st
    astrological sign astrology sings diploma in astrology syllabus days of the week astrology astrology cancer
    man taurus woman eris astrology ephemeris vivian e robson astrology astrological tapestry roman astrology history significance of first house in astrology in conjunction meaning astrology astrology
    phoenix az marrage astrology astrology past life report astrology encyclopedia astrological star sign symbols baby name numerology astrology astrology is bullshit rahul
    name in western astrology bible astrology astrological predictions based on date of birth sexology astrology aquarius astrology of today
    cancer astrology zone libra today astrology sign june 14 astrology tarot correspondence aries daily astrology love what age
    will i meet my soulmate astrology vedic astrology
    marriage date celtic astrology vine quincunx
    in horary astrology advanced vedic astrology articles cancer zodiac sign astrology
    online weak mercury vedic astrology astrology for kids water
    sign astrology astrological signs cancer and scorpio love astrology by date of birth chinese astrology metal horse astrology signs
    may 21 vedic astrology source code daily astrology cancer roman reigns astrology aries energy astrology astrology birth dates and signs vertex astrology age of astrology astrology for marriage based on date of birth nadi astrology accuracy astrology january january 17 astrological sign what is the astrology sign for august 26 small height astrology trine signs in astrology chinese astrology sheep and snake dark pixie astrology cancer

  5. В нашем интернет-магазине самые лучшие цены на растворимый кофе. Убедитесь сами: оптовые цены в розницу при заказе от 1 пачки.
    Тегуаньинь Нунсян 500 грамм

  6. Самые свежие женские новости тут babybynature.ru

  7. We take it that just a able paragrapher can ship academic ease that’s nothing short of best http://expertspaper.biz/2017/12/20/unique-gene-therapy-found-to-reverse-multiple/ and brings the paramount results. Essays on go green save future. Every online essay novelist in our network has a antagonistically track-record of providing research and expos‚ benefit to students. Moral values meaning in kannada

  8. Несмотря на заявления Трампа, что Мексика, Китай и другие правительства виноваты в экономических проблемах Америки, ему, конечно, не привыкать выносить производство за границу, подробнее читайте на сайте polivia.ru

  9. We believe that just a expert novelist can ship academic ease that’s nothing abbreviated of best http://chiefessay.biz/2017/10/29/writing-services-offers-online-writing-learning/ and brings the most skilfully results. Essay language and gender cora kaplan. Every online effort novelist in our network has a concentrated track-record of providing into and expos‚ support to students. Technology advancing too fast essay

  10. Последние строительные советы здесь 495realty.ru

  11. Последние строительные новости здесь dipris-studio.ru

  12. localisation numero telephone – VisionBot Pick and Place Show more>>>

  13. Новости строительного мира тут lakkk.com

  14. Последние новости Томской области здесь tom3.ru

  15. Новости народной медицины здесь medata.org

  16. Последние новости политики здесь vash-deputat.ru

  17. Последние новости мира тут novorossia-news.com

  18. We imagine that barely a expert novelist can cunning erudite ease that’s nothing stubby of fulfilled http://welltermpaper.me/2017/10/22/guide-to-essay-writing-and-research/ and brings the most skilfully results. Essays on summer of the seventeenth doll. Every online essay novelist in our network has a concentrated track-record of providing fact-finding and expos‚ benefit to students. Octavio paz essays on mexican art

  19. Последние компьютерные новости здесь wtsolutions.ru

  20. We suppose that alone a professional paragrapher can ship academic size that’s nothing abbreviated of correct http://essaymonster.me/2017/11/19/content-and-formating-guidelines-for-your/ and brings the best results. Short speech on success comes to those who will and dare. Every online composition journo in our network has a antagonistically track-record of providing check in and writing benefit to students. Business strategy case study on china airline

  21. I’m extremely pleased to discover this great site.
    I want to to thank you for your time just for this wonderful
    read!! I definitely enjoyed every bit of it and i also have you bookmarked to look at new things in your blog.

  22. Новости компьютерного мира тут rebenokboleet.ru

  23. Новости строительного мира тут stportal.ru

  24. Автомобильные новости здесь drive-land.net

  25. Последние женские новости здесь moisekretiki.ru

  26. Новости туризма тут zimnij-turizm.ru

  27. Последние новости шопинга здесь tvoirazmer.ru

  28. Модные женские советы здесь malipuz.ru

  29. Строительные советы здесь nfmuh.ru

  30. I been reviewing online more than four hours today
    for 1/2 Price Pro Calgary Painting & Creating an ActiveX control in .Net using
    C# <Olav Aukan, yet I never found any interesting article like yours. It's pretty worth enough for me. In my view, if all site owners and bloggers made good content as you did, the internet will be a lot more useful than ever before.

  31. Последние строительные новости здесь tppchita.ru

  32. Hello there I am so delighted I found your site, I really found you by accident, while I was looking on Bing for something else,
    Nonetheless I am here now and would just like to say cheers for a fantastic post and a all round exciting blog (I also love the theme/design), I don’t have time to read through it all at the moment but I have saved it and
    also included your RSS feeds, so when I have time I will be back to read a
    great deal more, Please do keep up the great jo.

  33. Losing burden is hard. Losing value and spagap.wahl.amsterdam/anweisungen/verstopfung-durch-obst-09101.html then keeping it shadowy is equilibrium in a word harder. Kibitz with of studies handle that long-wearing flash of an visual acuity trouncing debits ventfi.kremmen.amsterdam/handige-artikelen/middel-tegen-haaruitval-04209.html is not a myth. Basic assumption some of the 57 research-backed victuals, limber up, and lifestyle tips comni.kremmen.amsterdam/instructies/leukofix-tegen-rimpels-37660.html that sift along with into your prescription, and qui vive the pounds start to be received b adopt off. That means if you dodge manifest of breakfast, you’ll be more tempted via pattern of bad-for-you snacks later in the day.


Leave a comment