Adsense

Sunday, March 04, 2007

Creating ActiveX Controls using C# in VS2005

This will be a short tutorial on how to create a simple ActiveX control that opens a windows forms Message Box while living in an aspx page. Pretty useless, I know, but it will illustrate the basics of how to create and interact with an ActiveX control from a web page in Visual Studio 2005.
A co-worker and myself worked on this for a current project and found bits and pieces of this information and figured it would be a great resource to compile it all into one location. It can get a bit tricky (especially if you add in security issues when handling ActiveX control events) but its not too bad.
Step 1
This first step in this tutorial is to create a web project in Visual Studio. I called mine ActiveXTest.
Step 2
Next, add a new Windows Control Library project to your solution.
This project is where you will develop your ActiveX control. Rename the default user control cs file and double click on it to open up the designer. You can build your control just like you would any other Windows User Control by adding controls and code-behind as necessary. This example doesn't need any controls, but I'll add a picture box just so that we can see it on the aspx page.
Step 3
Now that our project is setup with a web project, a Default.aspx page and a Windows Control Library with our new User Control in it, we are ready to turn the User Control into an ActiveX control by exposing and implementing an interface.
Next, create in interface that will expose parts of your ActiveX control to the browser.
public interface IComInterface { string Msg { set; } // Exposes the Msg property through the interface }
Implement this interface in your User Control.
public partial class MessageBoxControl : UserControl, IComInterface { // Implement IComInterface public string Msg { // Implement the Property set{ MessageBox.Show(value); } // When the property's set is called, show the message box } public MessageBoxControl() { InitializeComponent(); } }
You have just created an ActiveX control that is ready to be embeded in a web page and exposes a property (Msg) to COM through an interface (IComInterface).

Step 4

The next step is to embed your newly created ActiveX control in your web page (Default.aspx.) To do this, you will use the <object> tag like this.
<object id="MessageBoxControl " name="MessageBoxControl " classid="ActiveXControls.dll#ActiveXControls.MessageBoxControl "> </object>
The id and name should be self explanatory. The class id is comprised of the name of your dll file, a # sign, and the namespace.classname of your control. That's all it takes to embed the control into your page. There are a couple of thing you will need to do to allow this to happen, but the coding is done.

Other things to consider...

1. You must have a copy of your Windows Control library dll on the same level of your web project as the default.aspx page. The dll cannot contained in the bin folder.
2. Add your local computer as a trusted zone through Internet Explorer. This will help bypass some of the security issues inherent with ActiveX controls. Do this through the Internet Options of Internet Explorer.
3. You may need to increase the trust level of your assembly before it will load correctly in Internet Explorer. You can do this from the .Net Configuration Tool located in the Administrator Tools of the Control Panel. (Configure Code Access Security Policy -> Increase Assembly Trust)
4. Strongly name your ActiveXControl assembly. (Note: You can do this through the properties page of the project.) This must be done prior to registering the dll in the gac.
5. You may also need to register your assembly/dll in the gac before it will work. You can do this by using gacutil from the command line from the directory of your dll. (gacutil /i ActiveXControls.dll) (Note: You might have to do this after every build of the project.)
6. Modify your AssemblyInfo.cs file and change the ComVisible attribute to true. ([assembly: ComVisible(true)]) This is maily when you want to expose ActiveX control events to your web page.
7. Set ISS so that Execute Permissions on your Virtual Directory are set to "Scripts Only". This is the only option in ISS that would work for me when deploying the ActiveX control and accessing it remotely and was a pain to track down.
Step 5

You can then access properties of your control exposed through your interface by using JavaScript on that page. Something similar to this.
<script type="text/javascript"> function showMessageBox(){ var control = document.getElementById('MessageBoxControl'); control.Msg = document.getElementById('txtMsg').value; } </script>
Tips/Tricks

You can add a build event to your Windows Control Library project that will automatically copy it's dll to the web project when you build it. Open the properties of the project by right clicking on it and add a line like this to the build events.

copy "$(TargetPath)" "C:\Projects\vs2005\ActiveXTest\ActiveXTest"

16 comments:

gv_pradeep said...

Nice article. Clears a lot of things.

gv_pradeep said...

When is the part2?

Paul Fox said...

I did have Part 2 posted in March. But I can't find it on the site. I will look through my backups and see if I can find it and get it up. Wonder what happened to it. =/

gv_pradeep said...

Ya sure. That would be great!

Paul Fox said...

Looked for the old post, but it looks like I might have lost it when I changed blog hosting. =/ I'll see if I can recreate it and get it posted...

Anonymous said...

hi!! this article helped me a lot :) i know its been like a year since you posted it but i was wondering if you could help me.
my activex will run perfectly when i do it from VS2005 (without signing it of course). but when i sign it and do everything else, it won't run outside VS2005 (using IIS)... suggestions????

Paul Fox said...

Thanks for the comment.

I would review and double check the items in the "Other things to consider..." section. If everything still looks good, I would look at your javascript syntax and make sure everything looks good, and try to run some kind of javascript console that will show you if you are getting any exceptions on that end.

If nothing seems to work, I would probably chalk it up to some kind of security issue on your local machine/iss. I remember that being my biggest hangup while developing activex and deploying it afterwards. I wish I could be more specific, but would probably need some kind of error or javascript exception to go off of.

Anonymous said...

I ve implemented ur code, but its not worked at all. when i called the object id using getElementById, an error saying "object doesn't support this property" is displaying. Can u pl let me know the issue with this???
Email: gururaj_jupiter@yahoo.com

Anonymous said...

Thanx, this is good stuff.

You still watching this?
If you are I would love to hear from you about this.

I have created a component with a couple of methods in it and getting the object using getElementById() is ok until I then try to call one of those methods.

It says that the property or method is not supported by the object.

It clearly is, I even ran it through reflector to check the class was defined correctly.

Any ideas?

ps: i followed all the advice above in detail :)

Paul Fox said...

I haven't looked at this example in quite some time actually. I just tried to get it up and running in my current environment (windows Vista and IE 7.) I wasn't able to get it to work either.

I'd imagine that the problem lies with Vista or IE7 and their "enhanced" security models. I'll play around with it a bit and see if I can't find out what's going on. =) If I do, I'll post here and possibly write a follow-up post.

~ Paul

Anonymous said...

In the end I gave up using the component.

It was for printing and I kept getting sporatic client configuration problems like missing drivers so I setup a server side printing application.

I am however looking at implementing a component to handle drag and drop events from the users desktop on to a tree within a web application to handle file uploads as current methods seem a little "bloated".

Interested in having a go at that?

The only thing I can think of for not using ActiveX is "platform compatability" so I think it might be easier to forget drag and drop right now and look at building somehting like a multiple file upload component within silverlight.

With the release of new versions of both OS'es and browsers ActiveX is slowly becoming the beast that few are willing to play with, although perfect for a LAN environment where you can use constraints on the software at both ends of the communication its perfect but for the outside world (the internet) this may prove to bea kick in the balls.

Paul Fox said...

I think you've got the right idea. I haven't had a need to play with ActiveX for the last two years, and the couple of attempts I've made to even get this example working in Vista with IE7 haven't worked. It seems like current MS security makes it much harder to get a simple control like this setup. (probably for the good of all in the end.)

I agree that it is still very feasible for an internal, LAN-type setting where you can really open up your security zones and where you know that you can trust your users, but for standard web dev (for the very reasons you mentioned) it seems to be going the way of the Dodo.

sri said...

this code does not works in firefix..is anyone know how to fix this issue?

Paul Fox said...

Active X controls only work in Internet Explorer without a plug-in or other 3rd party software. You might be able to find an Ad-in for Firefox, but I wouldn't count on it being 100% compatible. Good luck.

Harish said...

i did everything the way you suggested. It worked fine when i test in local system. After deploying the html page was not able to display the activeX control. Please suggest

Anonymous said...

wow. Instructions 1 and 2 are so descriptive.