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 (1151) Trackbacks (6)
  1. a) Solo Jet Skis: This may possibly be the first model in thetrue solo jet ski, where exactly the rider stands to the craft rather than sits, as well as the eyes of rather a few purists the only model that can genuinely be referred to because of the identify ski They may be extremely maneuverable and wish for being quickto get execs to do methods on, but novices shouldn genuinelystart out here. Solos are to have people having a good deala large amount moreencounter and athletic power.
    ferragamo vara pump http://www.barbarahaynes.com/mpegs/ferragamo-us-98.html

  2. Right before pondering a dental assistant salary, you might have to think about not simply the extraordinary wages you can be supplied. Gains can differ significantly from occupation to occupation and they must be thought about likewise. Someplace near 86%, in 2009, obtained paid getaway and greater than 50% obtained health benefits. Both may perhaps hinge partly on whether you are utilized whole or piece time. All round even though, when contemplating the earnings of people inside of this industry, it a occupation that gives a good wage for your schooling demanded.
    best christmas sale karen millen http://www.followingjesus.org/images/section_graphics/karenmillenchristmas-228.html

  3. After upon a time in eighteenth century England, men’s hats were just about every uniquely created by hatters, who took amazing care to customise each piece to it happens to be owner. Hence a hat was pretty much as good as your calling card. Future in early nineteenth century The us, when general public boxing contests were a favorite participatory activity (as opposed to the spectator activity of immediately), you signified that you just were joining the contest by throwing your hat in the boxing ring. You would then will have to struggle the champ so you can get it back again or presumably go your home bare headed.
    cannage dior http://www.hotel-tourmalet.fr/ftp_webdev/install_temp/img/dior-fr-478.html

  4. Initiate by drawing up a rough sketch of the to start with room you desire to begin engaged on. It does not should be to scale, although I’d personally recommend highly striving to perform this a tad afterwards on when you get started with contemplating home furnishings preparations.
    valentino orlandi handbags http://www.insurewiz.com/graphics/mainpage/html/us-5059.html

  5. The component blend in Phenocal incorporates Hoodia Gordonii since the key component. Hoodia Gordonii comes from a cactus which is located in Africa. It will be an hunger suppressant. Besides, it incorporates green tea combined with forslean. Green tea is often a effective antioxidant combined with it can help to suppress the hunger when rushing up the rate of metabolism. Forslean is well recognized as an remarkable fats burner. Besides, furthermore, it encourages lean overall body mass. These two ingredients in Phenocal support to shed substantial excess weight.
    ferragamo shirt http://www.price-utah.us/images/ferragamo-us-211.html

  6. Scrapping metal in old homes Advertising scrap metal
    uggs for toddlers http://hotelsuspiro.com/img/icons/tabs/ugg-us-226.html

  7. With respect to the exact situations of one’s injury, point out law, federal law, maritime law, or maybe the law of the international place may perhaps be pertinent. Successful cruise ship accident lawyers need to be expert in navigating the confusing lawful terrain that is certainly encountered in such a form of case. Even one of the most gifted legal professional will have a difficult time succeeding versus a cruise ship service if he, or she has not addressed such a case prior to. South Florida is definitely the dwelling of a variety of expert cruise accident lawyers given that numerous cruises leave from this community and because numerous of those situations need to be litigated in or about Miami.
    prada spring 2011 http://www.umachines.com/ssfm/css/us-3534.html

  8. Zaffaroni: “[La Argentina] no registra cifras alarmantes de criminalidad en relacin con las de la regin”: VERDADERO, PERO.
    north face denali jacket girls http://devinhenry.com/male89/small/northfacedenali-140.html

  9. At the conclusion of the working day I don’t definitely cling about I just push place,cook some tea and afterwards just calm down and fall asleep. I like most meals, but I am really keen on Jamie Oliver’s cooking, so I might do amongst his recipes I significantly just like a Stir fry with ginger and hen with noodles and vegetables. Its definitely painless to cook and only can take about ten minutes, it’s to generally be very painless and fast as I am frequently starving by then
    prada sunglasses pr57ls http://www.alarictay.com/ssfm/data/prada-us-2283.html

  10. To make a sizable area look lesser use darkish, heat colours relating to the walls and/or ceiling, and use substantial home furniture items.
    north face 900 down jacket http://signlady-texas.com/images/css/northfacedown-90.html

  11. They appraise the jewel instantaneously and pay out the perfect earnings in the direction of the patrons within a suitable time The formal web-site supplies the ability to find out the Gold Truly worth via the Calculator without any mistakes This dependable stage guarantees the gratification throughout the promise in addition to the shopper possess the ability to return the funds and declare their report within thirty times and it unquestionably is one particular unique with the proofs they endow with the many shopper pleasant assistance permanently
    sac rouge lancel http://www.novasoft-dz.net/DOUALGEREST/Log/lancelfr-281.html

  12. Or How I Formed In excess of $15,000 in seven Days that has a List of Just one,286 Subscribers!
    used chanel bags http://www.planetsoft.org/index_files/bags-3120.html

  13. Shell out $45 on 50 percent every day camp for my boys, decide to buy myself a box of Poise pads and piss myself in sweet, pungent solace.
    miuccia prada children http://www.wwytc.com/forms_files/prada-us-1679.html

  14. Amongst the massive selection of crops developed throughout India, rice is commonly consumed and beloved by everybody. The take pleasure in for rice around the region is often viewed in the truth that it’s a standard ingredient that blends effectively with diverse curries. A few of the most basic recipes encompass Matar Pulao, Kesar Pulao, Hen Biryani, Kashmiri Pulao, Kadhi Chawal, Rajma Chawal, Chhole Chawal, etc.
    bottega veneta men http://www.consultcp.com/ssfm/img/bottegaveneta-us-58.html

  15. Almost every baby likes so you can get their arms on a electronic digital camera and require photos, they may be lopsided, a bit of outside of focus and perhaps have heads minimize out. Still with practice the ideal photograph will certainly at some time finish up currently being generated.
    ferragamo ballet flats http://www.refinishhardwood.com/_borders/ferragamo-us-155.html

  16. Certainly, allow me guarantee you it most surely is. Dayna Garrett, a mom of 4 from Arizona, is definitely the inventor with the PantyO, tag lined more than a panty! How so?Its bought a nubbin.
    lancel plume http://www.turffinance.com/article/data/lancelfr-605.html

  17. Problem: Let us begin with a person in the most persistent thoughts in firm: Why are some corporations far more powerful and prosperous than many others?
    chanel sunglasses http://www.lindeman.fi/sve/foretag/img/bags-fi-123.html

  18. eBay vs. Amazon You men know I can enable this go devoid of updating you on how the with the Market Titans is going.
    prada bag prices http://www.eastaurora.net/Hawaii/images/prada-uk-836.html

  19. Yes, for $85 for the deluxe product or $52.99 to your normal fare, even though it noteworthy that both equally PantyO designs are adorned with Swarovski crystals, you can also stroll by means of city which has a silicone cooter plug.
    candy by prada http://www.motorcycleturntabledisplay.com/ssfm/themes/us-2900.html

  20. Being a consequence, from the party you are attaining a put into use jet ski you mustbe some you acquireall pieces you will want. A athletics design approximately alllikely delivers the approximately allbeneficial finding out journey as it ismuch moresteady and easier to use compared to the choices. You’re able todiscover out on multi seaters, nonetheless , youare not recommended to get some people out alongside along with you until such time as it’s possible you’ll be proficient singly.
    chaussures giuseppe zanotti http://pro.turffinance.com/article/images/giuseppezanottifr-10.html

  21. Phone the style law enforcement, Helen Flanagan is relating to the free and he or she might possibly induce a targeted visitors accident. Why? How about the set of that she sported on Thursday (July 21)? The British actress, Flanagan entirely outdid herself this time.
    north face denali cheap http://ziaislamic.com/calender2010/img/march/northfacedenali-210.html

  22. To recuperate on the exhaustion associated with continual tension, we want to accomplish things which turn off the adrenal hormones and encourage secretion of anabolic hormones. Some yoga poses, this sort of as inversions assistance to promote glands on the mind (Pituitary, Pineal). Shifting to the ALPHA condition is essential. The alpha condition is taken into account the ideal waking condition, the place we reach the pinnacle of our innovative believed course of action even when your body is inside a therapeutic cycle. Alpha condition is usually attained throughout savasana; ultimate resting pose in yoga exercise.
    the devil wears prada anna wintour http://www.wwytc.com/links_files/prada-us-1642.html

  23. There might be a variety of motives why Insomniacomes to some man or woman and remove ease from his living. Primarily, the will cause include improper diet regime, tension, depression, persistent discomfort, muscle tissues spasm, not enough physical exercise, growing older and a few other situations. Regardless of the motives would be, even so the trouble is always troublesome and concerned for men and women. A variety of scientific tests have revealed that daytime drowsiness, dizziness and daytime headache consequence vehicle crashes, growing older, poor immune strategy, and early death.
    sac ordinateur lancel http://admin-mysql.ks35.kalanda.net/article/data/lancelfr-419.html

  24. restrict my look for to /r/IAmAuse the subsequent look for parameters to narrow your outcome:begin to see the look for faq for data.
    prix sac french flair lancel http://faspppats.kalanda.info/attachments/lancelfr-527.html

  25. Designer sarees are worn by women draped greater than their human body in varied designs. Ordinarily these are wrapped around their waists with just one conclusion hung greater than the shoulder barring the midriff. These are typically essentially the most trendy and admired gown employed by Indian adult females considering that way back to the appearance from the nation itself. A saree is essentially an unstitched fabric of four to nine yards in length worn using a shirt sometimes called a choli which forms the higher garment from the gown. It really is essential the saree shirt styles matches and have got to be the same shade tone.
    ted baker contact http://ascom-cmr.com/ascom/RepMod/p/tedbaker-317.html

  26. eBay proceeds to develop GMV inside the sub 5% rangeAmazon retains expanding 3 4X e commerce As talked about, Amazon EGM is accelerating quite drastically inside the US and that i consider we see that inside the ROW in mid 2011, if that transpires, all bets are off and we could begin to see the strains cross in 2012.
    miu miu bag http://www.teematalot.com/Images/rivitalot/bags-fi-281.html

  27. No animated illustrations or photos. Be sure to submit them to /r/gif, /r/gifs, or /r/reactiongifs as a substitute.
    valentino rosier http://www.mazzolagallery.com/Ceramics/doc/us-5441.html

  28. Aunque las premisas sobre las que se basa el home staging son de aplicación general,
    no hay dos casas iguales.


Leave a comment