Sunday, September 22, 2013

Registration-Free COM with ActiveX Controls

In my current project, I have beside other things, a form with an ActiveX control on it. Additionally, I am using registration free COM, meaning that the COM information is stored in a manifest file instead of the registry.

Everything worked fine, until I tried to create the form a second time. Also this worked without problems, but not in the Visual Studio debugger. Here I got the strange exception:

System.NotSupportedException: Unable to get the window handle for the 'xxx' control. Windowless ActiveX controls are not supported.
at System.Windows.Forms.AxHost.EnsureWindowPresent()
at System.Windows.Forms.AxHost.InPlaceActivate()
at System.Windows.Forms.AxHost.TransitionUpTo(Int32 state)
at System.Windows.Forms.AxHost.CreateHandle()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.AxHost.EndInit()

After hours of thinking, debugging, code stripping and so on (to be honest, mainly from a colleague of me), we found the solution: the used manifest was not complete. The manifest was created using mt.exe with the typelib of the control. This manifest looked like

<file name="..." hashalg="SHA1">
  <comClass clsid="..." tlbid="..." description="..." />
  <typelib tlbid="..." version="..." helpdir="" />
</file>

When we compared this with the entries in the registry, we saw in the registry much more things. And also in the assembly manifest documentation are more attributes mentioned. Therefore we tried to add as much attributes to the manifest as possible (even if we did not understand every bit completely). And viola, now the error was gone!

In total, we added 4 attributes (in our case):

<file name="..." hashalg="SHA1">
  <comClass clsid="..." tlbid="..." description="..." threadingModel="..." progid="..." miscStatus="..." />
  <typelib tlbid="..." version="..." helpdir="" flags="..." />
</file>

I hope this could help, if you have a similar issue.

2 comments:

  1. Hi,

    Please post a sample code.

    I'm trying to embed .NET component inside my HTML page (using object tag), & I don't want any manual registration of that control. I expect, you click that page & see the action.

    I see your post useful in that direction. A sample would help in realizing that faster, & any new enlightenment would help further.

    I want to get native window handle (HWND), so that I can pass it to that framework for rendering object on it. Which technology is best suited?

    Thanks in advance.

    Vinay

    ReplyDelete
    Replies
    1. Hi Vinay,
      I do not think that it would be a good idea to use COM components in your web page. A COM component has full access to the client's machine. At least I (as a user) would not allow this. Beside this, your approach would not work with registration-free COM.
      In the past, Microsoft provided a technology called "managed browser hosting controls". This made it possible to embed .net controls into a web page. But as soon as .net 4.5 is installed, on the client's computer an additional registry key has to be set. So again to alternative.
      I would suggest to implement your requirements with HTML5. With JavaScript, WebApi and SignalR, you can build really powerful applications. And they work on all platforms, not only Windows with IE.
      I hope this helps
      Markus

      Delete