VB.NET COM DLL form a VBScript

M

MicheleG

Hi to all!
I created a VB.Net COM DLL which I can use in VBScript.
I followed the steps in the following article:
http://msdn2.microsoft.com/en-us/library/x66s8zcd(VS.71).aspx
(I used the method "with COM class template")

My DLL got created fine - no errors in build process.
The "Make Assembly COM-Visible" checkbox is checked.


the ComClass1 class is below (dll / assembly name is ClassLibrary1):


--------------begin of code

<ComClass(ComClass1.ClassId, ComClass1.InterfaceId,
ComClass1.EventsId)> _
Public Class ComClass1


Public Sub Importa(ByRef o As VISUMLIB.Visum)
MsgBox(Marshal.IsComObject(o))
o.Net.Marking.Clear()
End Sub

#Region "GUID COM"
' Questi GUID forniscono l'identità COM per la classe
' e le sue interfacce COM. Se vengono modificati, i client
' esistenti non saranno più in grado di accedere alla classe.
Public Const ClassId As String = "381f7f94-e48b-431d-
bdaa-2068442c90e6"
Public Const InterfaceId As String = "2dded33c-22ac-4816-a2f2-
ec8d228686b3"
Public Const EventsId As String = "2d8d4753-4d5e-4b58-
b75c-6e3fab5dad8a"
#End Region

' È possibile creare classi COM solo se dispongono di una Public
Sub New()
' senza parametri. In caso contrario, infatti, la classe non può
essere
' registrata nel registro COM e non può essere creata
' con CreateObject.
Public Sub New()
MyBase.New()
End Sub

End Class

-----------------end of code

As you can see I created a public method called Importa that accept as
input a COM object from a library referenced in .NET ("VISUMLIB")


Then I wrote a vbscript which creates an instance of the object:

Set dllobject = CreateObject("ClassLinrary1.ComClass1")

It works correctly!

Then I put in the vbs script then statement:

dllobject.Importa comobjectname

The output is a msgbox with "True" (result of
MsgBox(Marshal.IsComObject(o)).
So the object I'm sending to the dll method is a true COM object.
The problem is in the statement inside the sub:
"o.Net.Marking.Clear()"
I'm trying to execute the method Clear() of the container
"o.Net.Marking".

In my development machine everything works corretly.
But I tried to install the dll (I created a setup) and when It comes
to execute the statement
"o.Net.Marking.Clear()"

The vbscript breaks with the following error:

----------
"Unable to cast COM object of type "VISUMLIB.VisumClass" to interface
type
'VISUMLIB.IVisum'. This operation failed
because the QueryInterface call on the COM component for the interface
with
IID '{33B2B132-69BE-4ADE-A90E-939972B93FD5}' failed due to the
following
error: No such interface supported (Exception from HRESULT:
0x80004002
(E_NOINTERFACE)).
Source:Interop.VISUMLIB
----------

Can you help me sith any suggestions?
Thank you very much

M.G.
 
M

MicheleG

Hi to all!
I created a VB.Net COM DLL which I can use in VBScript.
I followed the steps in the following article:http://msdn2.microsoft.com/en-us/library/x66s8zcd(VS.71).aspx
(I used the method "with COM class template")

My DLL got created fine  - no errors in build process.
The "Make Assembly COM-Visible" checkbox is checked.

the ComClass1 class is below (dll / assembly name is ClassLibrary1):

--------------begin of code

<ComClass(ComClass1.ClassId, ComClass1.InterfaceId,
ComClass1.EventsId)> _
Public Class ComClass1

    Public Sub Importa(ByRef o As VISUMLIB.Visum)
        MsgBox(Marshal.IsComObject(o))
        o.Net.Marking.Clear()
    End Sub

#Region "GUID COM"
    ' Questi GUID forniscono l'identità COM per la classe
    ' e le sue interfacce COM. Se vengono modificati, i client
    ' esistenti non saranno più in grado di accedere alla classe.
    Public Const ClassId As String = "381f7f94-e48b-431d-
bdaa-2068442c90e6"
    Public Const InterfaceId As String = "2dded33c-22ac-4816-a2f2-
ec8d228686b3"
    Public Const EventsId As String = "2d8d4753-4d5e-4b58-
b75c-6e3fab5dad8a"
#End Region

    ' È possibile creare classi COM solo se dispongono di una Public
Sub New()
    ' senza parametri. In caso contrario, infatti, la classe non può
essere
    ' registrata nel registro COM e non può essere creata
    ' con CreateObject.
    Public Sub New()
        MyBase.New()
    End Sub

End Class

-----------------end of code

As you can see I created a public method called Importa that accept as
input a COM object from a library referenced in .NET ("VISUMLIB")

Then I wrote a vbscript which creates an instance of the object:

Set dllobject = CreateObject("ClassLinrary1.ComClass1")

It works correctly!

Then I put in the vbs script then statement:

dllobject.Importa comobjectname

The output is a msgbox with "True" (result of
MsgBox(Marshal.IsComObject(o)).
So the object I'm sending to the dll method is a true COM object.
The problem is in the statement inside the sub:
"o.Net.Marking.Clear()"
I'm trying to execute the method Clear() of the container
"o.Net.Marking".

In my development machine everything works corretly.
But I tried to install the dll (I created a setup) and when It comes
to execute the statement
"o.Net.Marking.Clear()"

The vbscript breaks with the following error:

----------
"Unable to cast COM object of type "VISUMLIB.VisumClass" to interface
type
'VISUMLIB.IVisum'. This operation failed
because the QueryInterface call on the COM component for the interface
with
IID '{33B2B132-69BE-4ADE-A90E-939972B93FD5}' failed due to the
following
error: No such interface supported (Exception from HRESULT:
0x80004002
(E_NOINTERFACE)).
Source:Interop.VISUMLIB
----------

Can you help me sith any suggestions?
Thank you very much

M.G.

Sorry the correct title is "VB.NET COM DLL from a VBScript "
kind regards

M.G.
 
M

Michel Posseth [MCP]

Strange ,,,,,,

However please note the following
Then I put in the vbs script then statement:

dllobject.Importa comobjectname

would be

dllobject.Importa(comobjectname) ' i asume comobjectname is an initialized
com object of type VISUMLIB.Visum
wich must also registred on the target system in the system32 directory or
in the GAC ( note that the assembly path wil not work as the Windows
scripting host is the actuall caller in this situation )

Are you sure the VISUMLIB.Visum is initialized in the VBS file ? cause it
looks to me like the VB program is receiving an unitialized Object type wich
is valid for COM as VBS works with variants wich are equal to .Net Object
types


HTH

Michel Posseth [MCP]












"MicheleG" <[email protected]> schreef in bericht
Hi to all!
I created a VB.Net COM DLL which I can use in VBScript.
I followed the steps in the following
article:http://msdn2.microsoft.com/en-us/library/x66s8zcd(VS.71).aspx
(I used the method "with COM class template")

My DLL got created fine - no errors in build process.
The "Make Assembly COM-Visible" checkbox is checked.

the ComClass1 class is below (dll / assembly name is ClassLibrary1):

--------------begin of code

<ComClass(ComClass1.ClassId, ComClass1.InterfaceId,
ComClass1.EventsId)> _
Public Class ComClass1

Public Sub Importa(ByRef o As VISUMLIB.Visum)
MsgBox(Marshal.IsComObject(o))
o.Net.Marking.Clear()
End Sub

#Region "GUID COM"
' Questi GUID forniscono l'identità COM per la classe
' e le sue interfacce COM. Se vengono modificati, i client
' esistenti non saranno più in grado di accedere alla classe.
Public Const ClassId As String = "381f7f94-e48b-431d-
bdaa-2068442c90e6"
Public Const InterfaceId As String = "2dded33c-22ac-4816-a2f2-
ec8d228686b3"
Public Const EventsId As String = "2d8d4753-4d5e-4b58-
b75c-6e3fab5dad8a"
#End Region

' È possibile creare classi COM solo se dispongono di una Public
Sub New()
' senza parametri. In caso contrario, infatti, la classe non può
essere
' registrata nel registro COM e non può essere creata
' con CreateObject.
Public Sub New()
MyBase.New()
End Sub

End Class

-----------------end of code

As you can see I created a public method called Importa that accept as
input a COM object from a library referenced in .NET ("VISUMLIB")

Then I wrote a vbscript which creates an instance of the object:

Set dllobject = CreateObject("ClassLinrary1.ComClass1")

It works correctly!

Then I put in the vbs script then statement:

dllobject.Importa comobjectname

The output is a msgbox with "True" (result of
MsgBox(Marshal.IsComObject(o)).
So the object I'm sending to the dll method is a true COM object.
The problem is in the statement inside the sub:
"o.Net.Marking.Clear()"
I'm trying to execute the method Clear() of the container
"o.Net.Marking".

In my development machine everything works corretly.
But I tried to install the dll (I created a setup) and when It comes
to execute the statement
"o.Net.Marking.Clear()"

The vbscript breaks with the following error:

----------
"Unable to cast COM object of type "VISUMLIB.VisumClass" to interface
type
'VISUMLIB.IVisum'. This operation failed
because the QueryInterface call on the COM component for the interface
with
IID '{33B2B132-69BE-4ADE-A90E-939972B93FD5}' failed due to the
following
error: No such interface supported (Exception from HRESULT:
0x80004002
(E_NOINTERFACE)).
Source:Interop.VISUMLIB
----------

Can you help me sith any suggestions?
Thank you very much

M.G.

Sorry the correct title is "VB.NET COM DLL from a VBScript "
kind regards

M.G.
 
M

MicheleG

Thank you for your answer!

I tried to modify the public sub:

Public Sub Importa(ByRef o As Object)
MsgBox(obj.ToString())
MsgBox(Microsoft.VisualBasic.Information.TypeName(o))
Dim VisumCl As IVisum = o
End Sub

The reselts are:

MsgBox(obj.ToString()) ---> "System.__ComObject"
MsgBox(Microsoft.VisualBasic.Information.TypeName(o)) ----->
"IVisum"
Dim VisumCl As IVisum = o ---> same exception: cannot cast from
COM object of type "System.__ComObject" to interface type
"VISUMLIB.IVisum".

This is very strange since from all above it seems that:
"System.__ComObject" is the type of COM wrapper and
"VISUMLIB.IVisum" is the actual type behind the COM wrapper.
So a cast with "Dim VisumCl As IVisum = o" should be possible since
the System.__ComObject class is specifically designed to work with COM
object,
and it is always able to performe a QueryInterface to any COM
interfaces that are implemented by an object. So casting the specific
interface (as long as they
are implemented on the object) should be succesful.

Since in my development machine all works correctly I think it could
be a different problem behind the code.
To tell you everything I built the dll from a COM-class template.
VB.NET produced 6 files. Among this I copied the files:
ClassLibrary1.dll, ClassLibrary1.tlb, Interop.VISUMLIB.dll
in a new computer (together with vbs file I need for executing all),
and registered the assembly with:
"regasm.exe ClassLibrary1.dll /codebase /tlb:ClassLibrary1.tlb"
I used /codebase because I created a Strong Name for my
ClassLibrary1.dll with a AssemblyKeyFile
(now I don't need to register all in the GAC)

It give error!
Can you suggest me something?

About your question "Are you sure the VISUMLIB.Visum is initialized in
the VBS file"
the answer is that I don't need to declare nor initialize such object
because the vbs file is execute
inside a software (imagine like a script inside autocad or Arcgis or
like in Access VBA..) so when
I write Visum in vbs it is an already known object that I can use or
pass to a method of an external com-dll.

With Visual Basic 6 there weren't problem. And a friend of mine tried
the same code above in C#.NET and works
correctly.
 
M

Michel Posseth [MCP]

MicheleG said:
Thank you for your answer!

I tried to modify the public sub:

Public Sub Importa(ByRef o As Object)
MsgBox(obj.ToString())
MsgBox(Microsoft.VisualBasic.Information.TypeName(o))
Dim VisumCl As IVisum = o
End Sub

The reselts are:

MsgBox(obj.ToString()) ---> "System.__ComObject"
MsgBox(Microsoft.VisualBasic.Information.TypeName(o)) ----->
"IVisum"
Dim VisumCl As IVisum = o ---> same exception: cannot cast from
COM object of type "System.__ComObject" to interface type
"VISUMLIB.IVisum".

This is very strange since from all above it seems that:
"System.__ComObject" is the type of COM wrapper and
"VISUMLIB.IVisum" is the actual type behind the COM wrapper.
So a cast with "Dim VisumCl As IVisum = o" should be possible since
the System.__ComObject class is specifically designed to work with COM
object,
and it is always able to performe a QueryInterface to any COM
interfaces that are implemented by an object. So casting the specific
interface (as long as they
are implemented on the object) should be succesful.

Since in my development machine all works correctly I think it could
be a different problem behind the code.
To tell you everything I built the dll from a COM-class template.
VB.NET produced 6 files. Among this I copied the files:
ClassLibrary1.dll, ClassLibrary1.tlb, Interop.VISUMLIB.dll
in a new computer (together with vbs file I need for executing all),
and registered the assembly with:
"regasm.exe ClassLibrary1.dll /codebase /tlb:ClassLibrary1.tlb"
I used /codebase because I created a Strong Name for my
ClassLibrary1.dll with a AssemblyKeyFile
(now I don't need to register all in the GAC)

It give error!
Can you suggest me something?

About your question "Are you sure the VISUMLIB.Visum is initialized in
the VBS file"
the answer is that I don't need to declare nor initialize such object
because the vbs file is execute
inside a software (imagine like a script inside autocad or Arcgis or
like in Access VBA..) so when
I write Visum in vbs it is an already known object that I can use or
pass to a method of an external com-dll.

With Visual Basic 6 there weren't problem. And a friend of mine tried
the same code above in C#.NET and works
correctly.

The new regasm doesn`t register the assembly location

with a execytable this is not a problem as a executable will resolve the
assembly path and alternatively the system32 directory

to be more clear

if you want to run an .Net COM Object on a PHP page you must copy the .Net
COM dll to the Apache bin directory ( as PHP is run in this context ) or
isntall the assembly to the GAC

VBS files are run by the WSH wich is located in system32 so i guess copying
the LIBS to the system32 will solve your prpoblem

with C# you should have the same problem ( unless he is using this from a C#
prog and not from a VBS file )

HTH

Michel
 
M

MicheleG

OK I solved the problem.
Thanks to everyone who wrote me.
This is the solution:

----BEGIN OF CODE-------
Public Class Class1

Public Sub Importa(ByRef visum As Object, ByVal numPF as Integer)
Dim VisumCl as Object = visum
VisumCl.Net.Marking.Clear()
Dim spp as Object = VisumCl.Net.Marking
spp.Add(Ctype(VisumCl.Net.StopPoints.ItemByKey(numPF), Object))
End Sub

Public Sub New()
MyBase.New()
End Sub

End Class
--------------------END OF CODE------

As you can see, before adding an element
VisumCl.Net.StopPoints.ItemByKey(numPF) to the container
VisumCl.Net.Marking, I have to convert it to generic type Object. Now
all works correctly!

Obviously from the VBScript I execute the statements:

Set dllobject = CreateObject("ClassLibrary1.Class1")
dllobject.Importa comobjectname numPF

Moreover, I added the dll: ClassLibrary1.dll and Interop.VISUMLIB.dll
in the
main directory where I execute the VBScript and where is located the
VISUM.EXE (dependence of Interop.VISUMLIB.dll)

Thank to everyone who answered me!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top