4

I've recently been looking for a way to use an unregistered DLL in VBScript. This accepted answer says that it can be accomplished using GetObject provided that (mentioned in the comments by the person who gave the answer) the DLL exposes a COM interface. I've never coded in C# before but I wanted to try it since the answer was for that language. After some searching, I found the following code example on this site:

using System;
using System.Runtime.InteropServices;

namespace Tester
{
    [Guid("D6F88E95-8A27-4ae6-B6DE-0542A0FC7039")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface _Numbers
    {
        [DispId(1)]
        int GetDay();

        [DispId(2)]
        int GetMonth();

        [DispId(3)]
        int GetYear();

        [DispId(4)]
        int DayOfYear();
    }

    [Guid("13FE32AD-4BF8-495f-AB4D-6C61BD463EA4")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("Tester.Numbers")]
    public class Numbers : _Numbers
    {
        public Numbers() { }

        public int GetDay()
        {
            return (DateTime.Today.Day);
        }

        public int GetMonth()
        {
            return (DateTime.Today.Month);
        }

        public int GetYear()
        {
            return (DateTime.Today.Year);
        }

        public int DayOfYear()
        {
            return (DateTime.Now.DayOfYear);
        }
    }
}

Using Visual Studio 2010 Professional, I created a new C# class library and named it Tester. I copied the above code into the default Class1.cs file and compiled it. Then, I made a .vbs file with the following code:

Option Explicit

Dim Obj

' This part gives the following error message:
'   ActiveX component can't create object: 'GetObject'
Set Obj = GetObject("C:\MyFolderPath\Tester.dll", "Tester.Numbers")
MsgBox Obj.GetDay

However, the code threw an error and would not instantiate the object. I tried running the .vbs file on the 32 and 64 bit version of wscript.exe because I'm on windows 7 64 bit. But, the error was the same both times. So, is there something I need to change in the C# code and/or some other option(s) I need to change in Visual Studio, or is the person's claim in the linked answer simply incorrect?

EDIT 1

My question is not a duplicate of this one. I realize the request there is of a similar nature. However, my question has to do with burden of proof. Nilpo has stated that GetObject will allow VBScript to instantiate an object using an unregistered C# DLL so long as it exposes a COM interface and even defended his position in that same question. I did the best I could to utilize the method he described and was unsuccessful. So, if it is possible, I would like to see a simple working example. And, if not, I was hoping to see some kind of documentation showing why not.

Furthermore, I will gladly use another programming language if that is truly the only way to allow the functionality I'm seeking. As such, I've removed C# from my question title and taken out the C# tag.

EDIT 2

I fixed the syntax highlighting for the original C# code I posted. It broke after I removed the C# tag from the question in my first edit.

7
  • 1
    In the project properties of the C# project check "Register for COM interop" in the "Build" tab. Commented Oct 23, 2017 at 20:09
  • @OlivierJacot-Descombes Unfortunately, we don't have admin access to our PC's at work so registering the DLL is not an option. Commented Oct 23, 2017 at 20:23
  • 1
    First I've seen it. This would be technically possible if it were a normal COM dll, one with a DllGetClassObject() export and an embedded type library. Neither is the case for a DLL created with C#. Doing this kind of development without having admin access to the dev machine is not practical. I suppose you could limp along by using Regasm.exe's /regfile option and edit the generated .reg file, replacing HKLM with HKCU, but that gets to be painful busywork in a hurry. A custom [ComRegisterFunction] that registers in HKCU is more practical but hard to get right. Commented Oct 23, 2017 at 20:37
  • Why not do the whole stuff in VB.NET? If you google for "C# to VB converter" you will find several online converters. Commented Oct 23, 2017 at 20:40
  • @OlivierJacot-Descombes I would happily attempt to code the DLL in another language so long as it would work in VBScript without needing to be registered. However, I do not have the option of avoiding VBScript entirely. Commented Oct 23, 2017 at 20:53

1 Answer 1

-1

You are on the right track but that CodeProject link expects you to register the library with COM, which does require elevated privileges.

However, if you add the ComVisible attribute to the class you want to expose, once you have compiled the DLL you should be able to call it through GetObject().

[Guid("13FE32AD-4BF8-495f-AB4D-6C61BD463EA4")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("Tester.Numbers")]
[ComVisible(true)]
public class Numbers : _Numbers
{
    public Numbers() { }

    public int GetDay()
    {
        return (DateTime.Today.Day);
    }

    public int GetMonth()
    {
        return (DateTime.Today.Month);
    }

    public int GetYear()
    {
        return (DateTime.Today.Year);
    }

    public int DayOfYear()
    {
        return (DateTime.Now.DayOfYear);
    }
} 
Sign up to request clarification or add additional context in comments.

11 Comments

I just tried the modification you posted and received the exact same error when I ran the .vbs file.
@ChrisD you're certain you compiled it (fresh build) for 32 bit and ran your VBScript through the 32 bit subsystem or vice versa?
I know that my Visual Studio program is 32 bit and I'm pretty sure the DLL would compile in 32 bit mode by default. I definitely didn't see or modify any settings to enable 64 bit compiling. And, I made sure to test the .vbs file in both the 32 and 64 bit versions of wscript.exe.
@ChrisD I would double check that assumption, go to the Build tab of your project properties to make sure it is compiling to x86.
It doesn't have anything to do with [ComVisible], the OP surely used the project setting. This is about getting the registry keys created.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.