ActiveX DLL Error

Peter M picture Peter M · Aug 6, 2012 · Viewed 7.9k times · Source

OK while I never thought in 2012 I would be writing my first ActiveX control (and yes there is a good reason for it) I am struggling with getting it running under Windows 7 (x64).

The Solution Short Story: I was missing /codebase from some of my regasm calls and also mixing up 32 and 64 bit processes, but that wasn't being helped by the standard VS2010 command prompt mixing up 32 and 64 bit paths for regasm and cscript.

The long story follows:

I have been bouncing between

Creating an ActiveX control in .Net using C#

(Oops I had the wrong link .. although it looks like the link I initially supplied was someone copying the original blog page)

Creating an ActiveX control in .Net using C#

and

C# ActiveX control (CSActiveX)

And I appear to be building the projects successfully (for the latter one I had to change the resource compiler location to the correct location).

For the first project I am using the suggested installer, for the second project I am trying to use regasm directly.

But after this it all goes down hill. I try and register the all's but either:

  1. I have no idea how I should be registering them, or:
  2. I have no idea how I should be registering them.

My test case has been a simple JScript file containing

var x = new ActiveXObject( "name of object" );

Which fails with the error:

test.js(1,1) Microsoft JScript runtime error: Automation Server can't create object

I am not sure if this is a permissions issue, or a 32 vs 64 bit issue or a combination.

A lot of sites offering help on ActiveX are assuming you will be accessing it via a web page , so I have tried looking at IE permissions (even though I want to load the control into a 3rd part program).

I know if I use either the 'framework' or 'framework64' versions of regasm I can control where in the registry entries get put - and I have seen some references to running cscript as either 32 or 64 bit (which possible affects what part of the registry is searched) depending on the cmd shell invoked (and I have tried both ways, as well as trying an "administrator" shell).

So basically at this point I have no idea what I am doing or what I should be doing.

My goal is to register an ActiveX control on Windows 7 x64 and have it be able to be loaded by:

  1. A test .js script running from the default Windows command prompt
  2. Load the same control into something like Excel 2007 VBA (for testing only)
  3. Load the control into a 3rd part application (RSView Studio from Rockwell) and have it hosted within a VBA application (and I need to check if this isa 32 or 64bit program .. I suspect the former)

Notes

For the project that users the installer (Creating an ActiveX control in .Net using C#), it installs the code into "c:\program Files (x86)\" and looking with regedit I find entries under "Computer\HKEY_CLASSES_ROOT\Wow6432Node\CLSID\" which I believe is telling me that the DLL was installed as a 32 bit process. I have tried running my cscript test from both a 32 and 64 bit cmd and they both fail. NOTE that the installer was creating the equivalent of "regasm /codebase" when it ran.

For the project where I tried using regasm to register it (C# ActiveX control (CSActiveX)), it has some additional code for registering an ActiveX COM control. This code mentions registering 32 bit in-process servers (see ActiveXCtrlHelpers.cs)

(BTW I'm also cursing auto correct in Safari/Lion at the moment, keeps changing lower case "DLL" into "all")


Edit 2012-08-07

Prompted by Art's answer I discovered:

From standard VS2010 command prompt

When running 'regasm /codebase' through the standard VS2010 command prompt (and as administrator to allow regasm to perform changes), the entries got dumped into the registry under HKEY_CLASSES_ROOT\Wow6432Node\CLSID and the test scripts failed from the same prompt.

However I can see the ActiveX control in Excel 2007 (32 bit)

From x64 Win64 VS2010 command prompt

When running under the VS2010 x64 Win64 command prompt (again as admin) the registry entries appeared under HKEY_CLASSES_ROOT\CLSID but this time the test scripts worked from the same prompt and also from a standard Windows cmd prompt (however they fail from a 32 bit prompt)

But!! I can't see the active X control from Excel 2007 (32 bit)

Now I just need to figure out what the windows equivalent of the *nix 'which' command to ensure which regasm I am using) the 'where' command

Looking at the VS2010 and Windows 7 command prompts:

    VS2010 (standard prompt): cscript => c:\windows\system32\cscript.exe
                              regasm  => c:\windows\Microsoft.net\framework\v4.0.30319\regasm.exe

    VS2010 (x64 Win 64):      cscript => c:\windows\system32\cscript
                              regasm  => c:\windows\Microsoft.net\framework64\v4.0.30319\regasm.exe

    Windows 7  std. prompt:   cscript => c:\windows\system32\cscript.exe

    Windows 7 32 bit prompt:  cscript => c:\windows\SysWOW64\cscript.exe

This is all starting to make some of my confusion understandable. I have been unknowingly mixing and matching 32 and 64 bit systems, but the VS2010 standard prompt didn't help either!

(and my latest peeve - VS2010 saving files as UTF-8 with BOM)

Answer

codechurn picture codechurn · Aug 7, 2012

I was able to make this work both via IE and vbscript by doing the following:

  1. Create .NET class library named 'ActiveXTest'
  2. Add a class named MyObject which is defined as follows:

    namespace ActiveXTest
    {
        [System.Runtime.InteropServices.ComVisible(true)]
        [System.Runtime.InteropServices.ProgId("ActiveXTest.MyObject")]
        [System.Runtime.InteropServices.Guid("df2dac4d-ba8a-4ecc-b76e-958c1bc32f1f")]
        public class MyObject
        {
            public string HelloWorld()
            {
                return "This is Hello World from the COM component!";
            }
        }
    }
    
  3. Compile the class. Go to the folder where you compiled the class and do the following from a Visual Studio command prompt: regasm /codebase ActiveXTest.dll

  4. To test from a .vbs script, create a file in notepad call test.vbs. type the following into the file:

    Dim myObject
    set myObject = CreateObject("ActiveXTest.MyObject")
    MsgBox(myObject.HelloWorld)
    

Open a command prompt and navigate to where where you created the Test.vbs and type: wscript test.vbs. A dialog should be displayed stating "This is Hellow World from the COM component"

  1. To test this from IE, I created a TEST.HTML file with the following contents:

    <HTML>
        <HEAD>
            <script language="JScript" language="JavaScript">
              var obj = new ActiveXObject("ActiveXTest.MyObject");
              alert(obj.HelloWorld());          
            </script>
        </HEAD>
    
       <body>
           <span>nothing to see here!</span>
       <body>
    </HTML>
    

Open the TEST.HTML file in IE. You will get a warning about the ActiveX control; just say Yes to allow the interaction. You will get an alert dialog stating "This is Hello World from the COM Component".

Similar steps can be used to make it work from a .js file or from Excel VBA. Note that if you change the COM method signature of the ActiveX assembly I believe you will need to re-register it.