none
.net com interop DLL not working from vbscript RRS feed

  • Question

  • I have created a c# com object and regasm'd it.  I can call it from VBA with no problem doing
    CreateObject(), but when I try it from a vbscript, I get "ActiveX component can't create object"
    Same thing when I run the script as Administrator.

    I've gone through every Internet article I can find on Com Interop, and am doing everything
    they say.  The dll is in the GAC - I see it.  I created a vbscript that calls System.Collections.ArrayList
    as a test and that runs fine.

    What am I missing here?   (Running on Win7 and using VS2008 express)

    -jtg
    Thursday, December 17, 2009 2:46 AM

Answers

  • Ok, I took the time to dig into this.

    Your problem most likely is that you are compiling a 32-bit dll and trying to run it under a 64-bit operating system.  I encounter the same problem as you the first time I tried this.  Remember that 64-bit processes cannot load 32-bit DLL's and vice versa.

    If you created a strong name and registered the COM dll in the GAC, then all you need to do is use CScript.exe or WScript.exe from C:\Windows\SysWow64.  If you did what I did (just compile, register and test), then compile and copy the DLL to C:\Windows\SysWow64 and re-test.  It should work just fine.

    If you are testing with a 32-bit OS, then most likely the problem is that .Net will look for the DLL in the path of CScript.exe or WScript.exe, which is C:\Windows\System32.  Copy your DLL here and your problem should go away.
    MCP
    Monday, December 28, 2009 9:17 AM

All replies

  • Sounds to me that maybe your interfaces are not OLE-Automation, meaning they do not inherit from IDispatch.  You can use the InterfaceTypeAttribute attribute to make the interface dual or IDispatch:

        [System.Runtime.InteropServices.InterfaceType(ComInterfaceType.InterfaceIsDual)]
        interface MyInterface
        {
            //Interface methods here.
        }
    


    MCP
    Thursday, December 17, 2009 4:33 AM
  • Thanks, but that didn't help either.  Again, it works fine in VBA, but not in vbscript.
    Here's the c# code snippet:



    using System;
    using System.Runtime.InteropServices;

    namespace SMGDotNetCom
    {

        [System.Runtime.InteropServices.InterfaceType(ComInterfaceType.InterfaceIsDual)]
        public interface IPerson
        {
            string PersonFullName { get; set; }
            int PersonAge { get; set; }
        }


        [ClassInterface(ClassInterfaceType.None)]
        public class Person:IPerson
        {
            private string person_name;
            private int person_age;

            public Person()
            {
                this.person_name = "[none]";
                person_age = 0;
            }

            public string PersonFullName
            {
                get { return person_name; }
                set { person_name = value; }
            }

            public int PersonAge
            {
                get { return person_age; }
                set { person_age = value; }
            }
        }
    }

    Thursday, December 17, 2009 11:48 PM
  • I haven't done COM in managed code before, so I cannot tell from experience.  Theory says, though, that your code should work OK.  Just a watchout:  I don't see GUID's for the interface or the object.  Will those change every time you compile?  If yes, then you will break things in the future.  Add explicit UUID's to the interface and the object.

    Back to your problem, I don't see much of a problem in your code.  Could it be possible that VBScript is attempting to load two different .Net versions at the same time?  Are you loading other COM objects that are also managed code before loading this one?
    MCP
    Friday, December 18, 2009 2:09 PM
  • The only thing the VBA and VBScript program do right now are these 2 lines:

         Dim obj
         set obj = CreateObject("SMGDotNetCom.Person")

    Runs in VBA, not in VBScript.


    (As for GUID's changing - I'll look into that.  Can't hurt to put them inline anyway.)   -john
    Friday, December 18, 2009 6:47 PM
  • Ok, I took the time to dig into this.

    Your problem most likely is that you are compiling a 32-bit dll and trying to run it under a 64-bit operating system.  I encounter the same problem as you the first time I tried this.  Remember that 64-bit processes cannot load 32-bit DLL's and vice versa.

    If you created a strong name and registered the COM dll in the GAC, then all you need to do is use CScript.exe or WScript.exe from C:\Windows\SysWow64.  If you did what I did (just compile, register and test), then compile and copy the DLL to C:\Windows\SysWow64 and re-test.  It should work just fine.

    If you are testing with a 32-bit OS, then most likely the problem is that .Net will look for the DLL in the path of CScript.exe or WScript.exe, which is C:\Windows\System32.  Copy your DLL here and your problem should go away.
    MCP
    Monday, December 28, 2009 9:17 AM
  • Thanks man.  That was it.  You can't IMAGINE how much time I've spent on this!!!!   UGHHHHHHHH!

    Yes, I'm running all of this under Win7 64-bit Pro.  I was under the impression that SysWow64 housed the 64-bit apps and System32 was the good old 32-bit ones.
    I see that it's just the reverse - real intuitive MS!!!  ("64-bit entities go into the System32 folder, and 32-bit entities go into the SysWOW64 folder.")

    OK, I need to re-group here and cleanup my folder with all these 'test cases'.  (I don't even remember why I started down this path to begin with now....)


    The next beer is on me....  thanks again.     -jtg
    Tuesday, December 29, 2009 1:17 AM
  • I open an MS Project (MPP) file, like such:

     

            Dim projectApp As New ApplicationClass()

     

            projectApp.FileOpen(ofdOpen.FileName, True, Missing.Value, Missing.Value, Missing.Value,

            Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value,

            PjPoolOpen.pjDoNotOpenPool, Missing.Value, Missing.Value, Missing.Value, Missing.Value)

     

     

    And I read the nodes and populate a list , like such:

     

    For Each p As System.Reflection.PropertyInfo In proj.GetType().GetProperties()

                If p.CanRead Then

                    Try

                        Console.WriteLine("{0}: {1}", p.Name, p.GetValue(proj, Nothing))

                        Dim item As RadListBoxItem = New RadListBoxItem

                        item.Name = p.Name

                        item.Text = p.Name

                        item.Value = p.GetValue(proj, Nothing)

                        lbNodes.SelectedIndex = 0

     

                        If blnComboboxItemSelected = False Then

                            lbNodes.SelectedItem = p.Name

                            blnComboboxItemSelected = True

                        End If

                        lbNodes.Items.Add(item)

                    Catch ex As Exception

                    End Try

                End If

            Next

     

    This works in XP Pro having VS 2010 B2. I am able to see a node called “Tasks”.

     

    However, it doesn’t in Windows 7 having VS 2010 RC. Some nodes are missing.

     

    It looks like I have a x64 issue. Which DLLs am I supposed to copy, to where and from where?

    Friday, February 26, 2010 4:18 AM