Expose dll for COM Interop

10,856

There could be a few different things at play here. First, you'll want to use the regasm tool with the /codebase /tlb switch from an elevated command prompt (assuming Windows Vista, 7 or Windows Server 2008). Something like:

regasm "Path to Smurf.dll" /codebase /tlb

Once you have registered the dll using regasm you should be able to invoke it using VBS, VBA or VB6.

I was able to use early binding and late binding from VBA to call the Explode method. However, when I tried from VBScript I received the "ActiveX can't create object error as you did."

I'm running on Windows 7 64 bit, and I recalled that this can cause problems when compiling to 32 bit dlls and running them on 64 bit operating systems. On a whim, I fired up a command prompt and entered:

C:\Windows\SysWow64\CScript.exe "Path to VBScript"

The result was that the script ran correctly and displayed "Pop" on screen.

Here's the somewhat simplified C# code I used as well as the contents of the VBScript file.

namespace Smurf
{
    [Guid("EAA4976A-45C3-4BC5-BC0B-E474F4C3C83F")]
    public interface IPants
    {
        string Explode(bool Loud);
    }

    [Guid("7BD20046-DF8C-44A6-8F6B-687FAA26FA71"),
     InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IPantsEvents
    {
        string Explode(bool Loud);
    }

    [ComVisible(true)]
    [Guid("0D53A3E8-E51A-49C7-944E-E72A2064F938")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComSourceInterfaces(typeof(IPantsEvents))]
    public class Pants : IPants
    {

        [ComVisible(true)]
        public string Explode(bool Loud)
        {
            string result;
            if (Loud)
                result = "BANG";
            else
                result = "pop";
            return result;
        }
    }
}

VBScript:

Dim x 
Set x = CreateObject("Smurf.Pants")
MsgBox (x.Explode(False))
Set x = Nothing
Share:
10,856
CompanyDroneFromSector7G
Author by

CompanyDroneFromSector7G

C# Go JavaScript jQuery LUA PHP SQL VB

Updated on June 04, 2022

Comments

  • CompanyDroneFromSector7G
    CompanyDroneFromSector7G almost 2 years

    I thought I knew how to do this, but obviously not so I'd appreciate some help! I can't get my dll to register so I can instantiate it in a VBS, or elsewhere.

    I wrote the following sample class, checked "Make assembly COM Visible", checked "Register for COM Interop", then built it. When I try to instantiate it from VBS I get the "Activex component can't create object" error.

    This is the class code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Smurf
    {
        public class Pants
        {
            public string Explode(bool Loud)
            {
                string result;
                if (Loud)
                    result = "BANG";
                else
                    result = "pop";
                return result;
            }
        }
    }
    

    ...and this is the VBS:

    Dim a
    
    Set a = CreateObject("Smurf.Pants")
    
    msgbox("ok")
    

    What else do I need to do?

    Thanks :)

    [edit]

    Forgot to mention, after the first failure I tried REGSVR32 and REGASM - no help!

    [/edit]

    Note that when I try REGSVR32, I get this message:

    The Module "C:...\Smurf.dll" was loaded but the entry-point DllRegisterServer was not found. Make sure that "C:...\Smurf.dll" is a valid DLL or OCX file and then try again.

    How helpful is that??

    This is the latest version of the code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace Smurf
    {
        [Guid("EAA4976A-45C3-4BC5-BC0B-E474F4C3C83F")]
        public interface IPants
        {
            [DispId(1)]
            string Explode(bool Loud);
        }
    
        [Guid("7BD20046-DF8C-44A6-8F6B-687FAA26FA71"),
            InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
        public interface IPantsEvents
        {
            string Explode(bool Loud);
        }
    
        [ComVisible(true)]
        [Guid("0D53A3E8-E51A-49C7-944E-E72A2064F938"),
            ClassInterface(ClassInterfaceType.None),
            ComSourceInterfaces(typeof(IPantsEvents))]
        public class Pants : IPants
        {
            public Pants() { }
    
            [ComVisible(true)]
            [ComRegisterFunction()]
            public static void DllRegisterServer(string key) { }
            [ComVisible(true)]
            [ComUnregisterFunction()]
            public static void DllUnregisterServer(string key) { }
    
            [ComVisible(true)]
            public string Explode(bool Loud)
            {
                string result;
                if (Loud)
                    result = "BANG";
                else
                    result = "pop";
                return result;
            }
        }
    }