3

I am creating a COM server .dll in C# (.NET 3.0 - external requirement). Some clients work well with it but others do not. Specifically, I'm having problems getting VBScript to like it.

  1. There are two primary components:

    a. an interface
    b. an implementation object

    they both have their own GUID's. The implementation class EXPLICITLY implements the interface.

  2. The 'Assembly Information' dialog check box 'Make assembly COM-Visible' is checked.

  3. The 'Build' dialog check box 'Register for COM interop' is also checked.

  4. I also signed the assembly, created a Strong Name Key.

In desperation, I added the System.EnterpriseServices.ServicedComponent assembly:

[Guid( "0135bc5c-b248-444c-94b9-b0b4577f5a1b" )]
public class TwoPays : ServicedComponent, ITwoPays
{
    void ITwoPays.TestConnect()
    {
...
[Guid( "0135bc5c-b248-444c-94b9-b0b4577f5a1a" )]
public interface ITwoPays
{

I also ran regsvcs.exe.

RegSvcs.exe LandCORC.dll Microsoft (R) .NET Framework Services Installation Utility Version 2.0.50727.5483 Copyright (c) Microsoft Corporation. All rights reserved.

Which failed with:

WARNING: The assembly does not declare an ApplicationAccessControl Attribute. Application security will be enabled by default.

Installed Assembly:
Assembly: C:\Source\LandCORC\bin\Release\LandCORC.dll
Application: LandcORC
TypeLib: C:\Source\LandCORC\bin\Release\LandCORC.tlb

Since I also don't know anything about Application security, I'm not sure if the warning message from RegSvcs.exe is important.

So I've been using VbsEdit to test it. Before I added the ServicedComponent and ran RegSvcs.exe, it would die on the Set objXL = CreateObject("LandCORC.TwoPays") statement.

Now that completes but when I try to call TestConnect it says that objXL is an invalid pointer, for example:

Dim objXL
Set objXL = CreateObject("LandCORC.TwoPays")
objXL.TestConnect

Adding the reference for VbsEdit:

Prog ID: LandCORC.TowPays
TypeLib path: C:\Source\LandCORC\bin\Release\LandCORC.tlb
GUID: {0135BC5C-B248-444C-94B9-B0B4577F5A1B}

But if I change the VbsEdit reference to use the interface GUID instead, then the auto complete for objXL will show the correct list of methods but then when it executes that I get 'Object doesn't support this property or method: TestConnect' instead.

I don't know what I need to complete the puzzle.

NEW INFORMATION Based on Kev's answer, I have corrected the interface and class definitions.

[Guid( "0135bc5c-b248-444c-94b9-b0b4577f5a1a" )]
[InterfaceType( ComInterfaceType.InterfaceIsDual )]
[ComVisible( true )]
public interface ITwoPays
{
    [DispId( 1 )]
    void TestConnect();

    [DispId( 2 )]
    void Terminate();



[Guid( "0135bc5c-b248-444c-94b9-b0b4577f5a1b" )]
[ClassInterface( ClassInterfaceType.None )]
[ComVisible( true )]
public class TwoPays : ITwoPays
{
    [ComVisible( true )]
    public void TestConnect()
    {
        LogInformationMessage( "TestConnect." );
    }

   [ComVisible( true )]
   public void Terminate()
   {

And running RegAsm /codebase /register /tlb comes back clean as does running the gacutil -i which states Assembly successfully added to the cache

Display name
  • 1,228
  • 1
  • 18
  • 29

1 Answers1

3

This is from a project where I had a similar requirement, an InProc COM wrapped .NET component visible to VBScript and Classic ASP (as in IDispatch friendly in COM parlance).

I've renamed the interface, class and methods but you should get the idea.

Declare our interface:

[Guid("0B201484-E388-45eb-9AB8-A6AE1E197AAB")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[ComVisible(true)]
public interface IThingy
{
    [DispId(1)]
    int DoThing1(string name, int age);

    [DispId(2)]
    string DoThing2(int id);

    [DispId(3)]
    bool DoThing3(string address);
}

Implementation:

[Guid("68FAB6AC-9923-425a-85F2-59B50552A5C1")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class Thingy: IThingy
{
    [ComVisible(true)]
    public int DoThing1(string name, int age)
    {
        // ....
    }

    [ComVisible(true)]
    public string DoThing2(int id)
    {
        // ....
    }

    [ComVisible(true)]
    public bool DoThing3(string address)
    {
        // ....
    }
}

I also had to generate an assembly key file, this is because COM wrapped .NET assemblies need to be "strongly named" (I vaguely remember - it's been ten years since I wrote this code).

Next I regasm'd the assembly which does all the fun COM wiring in the registry:

regasm.exe COMExample.Fun.dll /register /codebase /tlb

And then chucked it in the GAC:

gacutil.exe -i COMExample.Fun.dll

To uninstall:

gacutil.exe -u COMExample.Fun.dll,Version=1.0.0.0
regasm.exe COMExample.Fun.dll /unregister /tlb

Get rid of the System.EnterpriseServices and ServicedComponent stuff. You only need that if you're going run up an out of process server in COM+ and need the COM+ transactional infrastructure etc.

Kev
  • 118,037
  • 53
  • 300
  • 385
  • Kev, it seems like it is closer now. But VbsEdit still doesn't like it: it blows up on executing the TestConnect method. At least now the methods populate in VbsEdit. – Display name Jun 02 '15 at 01:49
  • @Dysmondad What version of Visual Studio are you building this with? – Kev Jun 02 '15 at 01:50
  • @Dysmondad - Ok, I'm going to have to hack about on that later today, it's 0300 here, time for bed :) Would be interested to know what a plain old `.vbs` script run from the command line does with this, just in case it's a VBSEdit problem. Post any error messages raised. Cheers. – Kev Jun 02 '15 at 02:12
  • I appreciate your time and effort: I just ran the script from the command line and it gives the same result. I'll keep at it just in case something comes to mind. It does seem like you've gotten me much closer. – Display name Jun 02 '15 at 02:15
  • I created a simple test project will a the points you laid out. That works just fine. Now I need to figure out where my main project differs. Given this, you've earned the answer and my gratitude. – Display name Jun 02 '15 at 04:38
  • Yep, That did it. For some reason my development box has a damaged registry and VBScript don't like it (either command line or VbsEdit don't work); however, I loaded up on a test box and it's all happy. I must have damaged the registry (or something) on my dev box. Maybe it's time to scrap it and start anew. – Display name Jun 02 '15 at 05:15
  • @Dysmondad - fab, and glad I could help :) – Kev Jun 03 '15 at 10:55