Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Creating COM DLL in VB.NET and using it in a VBScript 1

Status
Not open for further replies.

MicheleByte

Programmer
May 7, 2008
4
IT
Hi to all!
I created a VB.Net COM DLL which I can use in VBScript.
I followed the steps in the following article:
(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"
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


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.
 
Well, if it works on your machine, but not on a non-development machine, my first thought would be to verify that all of your dll's are getting copied over with the install. The Interop.VISUMLIB file would be the first one I would check.

The Interop.VISUMLIB file is a wrapper that was automatically created for you. Make sure that it's copied with your installation project, and put in the same directory as your dll.

If that doesn't work, go to Microsoft's website and find a program called "Process Monitor". This is an app that can look into processes and tell you what's happening. Load up Process Monitor, and run the script again. Look for failures in Process Monitor and it will tell you what file/process it tried to run and where it expected it to be. You might need to play around with Process Monitor in order to get the information you need...it's very intuitive so it should take more than 5-10 minutes to get up to speed on the basics of the app.

im in ur stakz, overflowin ur heapz!
 
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. I don't need now to register in the GAC and by the way I copied all files in the main directory where I execute script.

It give error!
Can you suggest me something?


With Visual Basic 6 there weren't problem. And a friend of mine tried the same code above in C#.NET and works
correctly.
 
Since you copied the Interop dll, it should allow you to create an instance of the VISUMLIB object.

To dig in to this a bit deeper, what Operating System are you running it on that gives you a problem? This may seem like a wierd question, but thereare a lot of support files that Vista does not include with a standard build. This is where Process Monitor comes in handy, it can point out the missing files.

Second, do you have the save .Net Framework installed on the other system that you built the project in? If you built the project in VS 2005, and the other machine only has .Net Framework 1.1, then it would cause wierd problems like this.

Also, another thing to check is the Event Log within the Administrative Tools in the Control Panel. Sometimes, information will get logged there by the Operating System. It may not provid a direct answer, but it may point out other issues.

If none of these ideas work, send me a copy of the dll's and script (if you can) you used on the other system and I can run them on a XP SP2 non-development virtual machine that I keep just for testing items like this :). My email address is lclay AT consultant DOT com

im in ur stakz, overflowin ur heapz!
 
Ok. Now it works with this modifications:

Public Sub Importa(ByRef o As Object)
MsgBox(obj.ToString())
MsgBox(Microsoft.VisualBasic.Information.TypeName(o))
'<deleted> Dim VisumCl As IVisum = o
'like cast-ing from ObjectCom to Object??
dim VisumCl as Object = o
'not the method clear() works correctly
VisumCl.Net.Marking.Clear()
'now the PROBLEM is with the next statement
VisumCl.Net.Marking.Add(VisumCl.Net.StopPoints.ItemByKey(numPF))

End Sub


----
With the last statement I want to add the element identified by numPF from the collection VisumCl.Net.StopPoints to the container Net.Marking

The error stack is:

System.Runtime.InteropServices.SHEException:External component has thrown an exception.
In Microsoft.VisualBasic.CompilerServices.LateBinding.InternalLateCall(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack, Boolean IgnoreReturn)
In Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateCall(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, Noolean IgnoreReturn)

Do you know what is this Exception?

By the way the dll worked in a second computer so I was able
to pass the COM object(or wrapper) to the dll. Now the problem is that I can't use like I would this object.

Thanks for your help. You made me improve so much!

regards
 
What type of object is numPF? The error you getting looks like you're going to have to marshal the object type to something that C++ can handle.

If you put [MarshalAs.???] as an attribute to the numPF that will fix it (if that's what it is). As far as the ??? you'll have to determine the type of object that the dll is expecting and then find that in the intellisense list.

im in ur stakz, overflowin ur heapz!
 
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!

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top