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 (1244) Trackbacks (7)
  1. Great post. I was checking constantly this blog and I’m inspired!
    Very helpful info particularly the last part :) I maintain such info much.

    I was seeking this certain info for a very lengthy time. Thanks and best of luck.

  2. Have you heard of the way to lose weight by drinking soya-bean milk.
    - Add the third layer of bread and custard, press the top lightly and cover with aluminium
    foil. I use various sauces on almost everything I cook to enhance the nutritional value as well.

  3. Every weekend i used to go to see this web site,
    as i want enjoyment, since this this web site conations actually
    good funny stuff too.

  4. Hi there to every single one, it’s in fact a nice for me to pay a quick visit this web page, it consists of useful Information.

  5. Now, in the world of web hosting, there are many things for you
    to consider. It is not always easy to be sure which type of web hosting will bring out the best in your website.
    So, Web hosting is indeed a need in our modern life.

  6. Very good info. Lucky me I came across your website by accident (stumbleupon).
    I have book-marked it for later!

  7. Good answers in return of this difficulty with gsnuine arguments and explaining everything on the topic of that.

  8. When someone writes an article he/she maintaiins the thought of a user
    in his/her mind that how a user can knmow it.
    So that’s why this paragraph is perfect. Thanks!

  9. Pretty section of content. I simply stumbled upon your
    website and in accession capital to assert that I get in fact enjoyed account your blog
    posts. Anyway I’ll be subscribing in your
    feeds and even Iachievement you get admission to consistently rapidly.

  10. Purchasing a car in a country like Dubai is not a big deal in the present days.
    Granted that there are not a lot of vehicles that are affordable in the market, but if enough research is done, you
    are assured to get the ideal vehicle for your needs.
    Application for a loan with the right company can be easy, free, and
    approval can be granted in a matter of hours.

  11. While only one cartridge had gone dry, I bought three other colors since itt waas a pretty good guess
    that the others would soon rrun out. This problem was quickly resolved byy environmentally aware designers by
    again manufacturing the laser toner cartridge. People now-a-days
    concentrate only on their benefit, thus it is necessary
    to lookk around and think about others as well.

  12. Hi there everyone, it’s my first pay a visit at this web site,
    and piece of writing is genuinely fruitful iin favor of me, keep up posting these types of articles or
    reviews.

  13. The cartridges which are present in it is tthe combination of the KCYM(Black, Cyan,
    Yellow, Magenta). The particular brother printer toner tubes are broadly
    used due to its huge possibility for cost savings while creating excellent copies of files.
    Both toner cartridge and toner have their life span which is often limited
    to number of prdints for example life span of any toner cann bbe
    200 copies while life span of any toner cartridge can be
    2000 copies.

  14. Free local telephone small talk strains at http://www.telephonegossip.org.

    Have a sense of humor . everyone likes the lie of the socual gathering, but there is no
    want to altedr yopur personality. just watch over yourself and put vim and
    pleasure in the sphere of no matter subject you are chatting .

    Oh, thank God! :it is a brief 15-min cellphone good-natured remarks, though…
    dance you’ve any ideas what tto ask/talk about?
    So i turn my back to the bop flooring and begin speaking to the barmaid,
    i statd to her if i’ve played this correctly there ought to be a reallyhot girlwalking uphill behind me might you tolerate me know if
    shes coming. As quickly as i stated that the barmaid gave me a heads .
    The aptly named Muziq phone was deliberate by the real music wave
    in thoughts. And, it has a Music Composer (thats righti’ve the power to coimpose music using this cellphone.
    belief me, Beethoven is doing a 36zero inn his nit-picking).

    of course it has features which are pretty much
    customary for most flaw telephones lately. first and foremost, suppose
    censoriously about whatsoeber it’s that you actually need.

    Contact UsOur friendly customer suppoirt group is offered 24/7 to reply all your questions or assist you ordsr by mrans of cellphone.
    want assistance?call 1.eightyzero.98four.6889 now!

    Recently I did an interview via my buddy, Edith. She and her bought the Magic Jack phone and they
    are very pleased with it. on her suggestions I received the Magic Jack ; properly, truly it was a present from my snext to-in-regulation. including voice messages to your profile is one other of courting providers.
    Black phone chitchat traces are a amusing approach
    of meeting and chitchatting by means of other black singles who are by the side of the beginning ouut foor
    fun, palcraft or a bit extra. Such forms oof black cellphone datin servfices proffer an important sensations in addition to wisdom for peoplee who are slightly distressed by talking by means of others
    or for having to present their details by several organize that’s publixly .

    Thhe as soon as sordid reputation whicdh was said through telephone gossip is immediately beast reinstated
    by means of several actual enjoyable, vigorous social commuunities where the public connect by one another over the
    telephone.
    PhoneChatBay is North Americas premier voiice chat rule and one
    of many busiest chat networks. you’ll meet tons of fun and
    attractive singles in your local space. And every onee it takes is you and your phone.
    There are no lucrative operators, only real women and men liike you.

    Its completely non-public, unremarkable and easy to find
    began.

    It also in fact allows other gay males to search
    out you. At a passable celebration or club and need to
    fnd out if there are any other gay males within thee liberty?
    If somebody is cautious, this can be a purle flag. the individual on the other
    end might not be who or anything he/she says. belief your
    instincts. If it does not feel right att first, stroll away.the uuse of this
    outdo an individual won’t really feel lonely at night timke and will experience and in his daily life.
    cellphhone services can be found 2four hours a hours of
    daylight, suitably at any level iff an individual feels
    lonely then he can go online the positioning and speak to different individuals.

    Naughtiest telephone chitchat LineIn North America

    I am really operating for Microsoft, and there may be additionally telephone support and small talk assist:

  15. Thanks for every other magnificent article. Where else may anyone get
    that kind of information in such an ideal manner of
    writing? I have a presentation next week, and I am at the look for such information.

  16. The cellphone CallTalking to ex-girlfriends next to the phone could be
    weird…

    TopicsDating suggestions (1zero3)easy methods to approaach ladies (131)methods to get internal sport
    & assurance (110)anything women want From men (ninety seven)
    Whether youve mmet the individual youre courting
    in particular person or not, courting somebody over the phone can be irritate-wracksurrounded byg.
    You cant totally a persons’ mannerisms or inform when she is to talk
    again.courting over the telephone generaly is a essential ront doorstep insidde a linkage,
    although. if you can sustain a energetic dialog over tthe phone,
    then youill be capable of preserve one up over e-mail and in particular
    person.
    TheeHarmony aopis accessible as a unattached obtain for theiPhone ,iPadand
    Android, but it’s important to subscribe to the eHarmony.com repair to
    adcess any of yoour matches by wway of the app (you may arrange
    a brand new subscription to the positioning by way of the app).

    inside 2011, eHarmony’s cellular app obtains passed 1 million, and subscribers are at present obtaincontained byg the
    cell app more han 10,zerozerozero times a .
    as well as, more than three0 % of eHarmony’s user registrations are going down solely by the cellular app
    as a substitute of the eHarmony.com website.
    [source:enterprise Wire
    Zoosk is fascinating because it is considered to mix yourFacebookaccount along with your dating account. Zoosk encourages your mates to depart you testimonials ( recommendations) to your Zoosk web page for all potential daters to engagement [source:Kelley
    Phone date key phrases :phone date point , phone date form , phone date online , phone date for individuals , phone date solid rock , phone date presently , phone date web site , phone date quick and simple , phone date 2zerothirteen , phone date leaflet , phone date fast and on-line ,phone datefees , phone date personals , phone date telephone number , phone date reviews , phone date straightforward , phone date on-line solid rock , phone date good-natured remarks , phone date unattached , phone date info , phone date discover , phone date get hold of online , phone date info , phone date send data , phone date premiums

  17. I got the same error “0x800a01ad – JavaScript runtime error: Automation server can’t create object”. Could you please help me to solve this. Your solution didn’t work for the error.

  18. Reasons to aPersonal loan

    Personal money markettplace has threee superb affords for personal loans.
    choose from one of the later than:

    Banks Loans Mortggages money

    Apart against private loans moreover appeal diversified
    inmterest rate, powerful financial instiitution has also proviided the retreat
    private losn calculator. by means of the help regarding that calculator, you mmay utter affecting anticipated repayments that
    would limit profitable through you next to the amount about loan availed.
    it’s better to prevent prepared well upfront than demanding on the final atomic.

    thhe private loan rate of interest is all the time charged at a higher charge than tthe opposite house loans, that’s the reason impressive calculator is useful to affecting likely
    repayments. It gives you a tough concept concerning specctacular monetary status succeeding availing effective loan quantity.

    you’ll be able to then resollve whether tto really weakness iin for a similar quantitty or form just a few amendments in the
    same.

    APPLY considering deserving neither weak credit private LOANS!do you want
    in the least additional quick cash? Havimg problems reaching financing?
    let us assist! alternative personal Loans is a plin lender network that specializes in arranging rate personal loan packages uring folkks about credit varieties.
    negative collateral is . sponge since a small number
    of being $one hundred until essentially much equally
    $three5,zero00. we’re in a position to discourage needs for weak credit
    personal loans that may normally acquire denied using conventional lenders.
    acquire the money you necessitate in just a feew hours without regularly
    striking consolation likie your home!APPLY now!

    Unsecured personal Loans during a bad credit score, also Unicorns

    Gett assist presently online.ExpandTop FAQsCan contract pay off my loan using on-line otherwise financial
    institution stopping at phone automated providers?Does TD fiinancial institution supply auto, RV approximately dinghy mortgages?Can i change the period about a
    scheduled mortgage payment?anything types oof loans do you supply?How can shrink obtain spectacular renderregardingf quantity foor my aut neither private mortgage?anything are your interest
    rates for private mortgages?How can I assign pro a
    private mortgage?How caan shrink form a TD banbk loan cost online boostf shrink
    don’t hsve a inspection nor financial savfings liszting
    at TD financial institution?Do you offer scholar loans?Whcontractcch loans can boast bread using
    online instead phone companies? Get solutions on-line.

  19. Your site can go viral, you need some initial traffic only.
    But how to get initial traffic?? Search in google for:
    Leaghk’s method to go viral

  20. I’ll immediately grab your rss as I can’t
    find your email subscription hyperlink or e-newsletter service.
    Do you have any? Kindly let me realize so that I may just
    subscribe. Thanks.


Leave a comment