Solved

Parsing VBScript against local objects in .NET using MSSCRIPT.OCX or Similar

Posted on 2003-11-25
15
1,765 Views
Last Modified: 2012-05-04
Hi,

I'm currently writing a spec for a large VB.Net application. We require users to be able to 'write vb script' in the application that is evaluated at run time against objects defined in the app and instatiated at runtime.

This functionality is handled perfectly in VB6 by MSSCRIPT.OCX, however I cannot get it to work in .net.

In VB6, I had no problems getting the following code to work.

' First I defined my class as such...
Option Explicit

Public sName As String

Property Get AttribA() As Integer
AttribA = 234
End Property

Property Get AttribB() As Integer
AttribB = 84
End Property


'then, I defined the follwing sub to test the scripting

Sub ScriptingTest()
Dim sScript As String
Dim sResult As String
Dim oScriptEngine As New MSScriptControl.ScriptControl
       
oScriptEngine.Language = "VBScript"
' Create an instance of my object
Dim oOb As New clsMyObject

' Set a property at run time
oOb.sName = "David"

' Add my instance of the object to the scriping control
oScriptEngine.AddObject "oStudent", oOb, False

' Test 1, show an evaluation
sResult = oScriptEngine.Eval("ostudent.sName")
MsgBox (sResult) ' this msgbox returns "David"
       
' test Two, do multiplication on a couple of properties from our class instance
sScript = "ostudent.AttribA * oStudent.AttribB"
sResult = oScriptEngine.Eval(sScript)
MsgBox sResult ' This returns 19656
End Sub


OK - now all of the above works great in VB6. It is exactly what I wish to achieve in .Net. Firstly, does anyone know of a way to do this in fully managed code? Does .Net have any way to parse script (defined by the user at runtime) against instantiated objects? This would obviously be my preference.

If that's not possible/available, can someone please help me to get msscript.OCX working in .net.

In VB.net, I tried the following code....

' First define our simple class

Class clsStudent

      Public sName As String

      Sub New(ByVal i_sName As String)
            sName = i_sName
      End Sub

End Class


' Now execute some script against it...

      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

            Dim sScript As String
            Dim sResult As String

            ' I added a reference to this COM control in the IDE, now instantiate it...
            Dim oScriptEngine As New MSScriptControl.ScriptControl

            oScriptEngine.Language = "VBScript"

            ' Instantiate our Object
            Dim oOb As clsStudent = New clsStudent("David")

            ' Try to pass it to MSSCRIPT.OCX - HERE IS WHERE I GET AN ERROR!
            oScriptEngine.AddObject("oStudent", oOb, True)

            ' Return the result from the script
            sResult = oScriptEngine.Eval("oStudent.sName")

      End Sub


The error that I get when I try to pass the .net object into the script control is


"An unhandled exception of type 'System.InvalidCastException' occurred in Scripting Research.exe Additional information: No such interface supported"

I'm guessing that it doesn't support 'iUnknown' or whatever it is that COM uses and that I need to add some sort of interface(s) to all of my objects so that they fit in.


I'm pretty desparate for an answer to this. Please give as much detail as appropriate, plus 'complete code' of solution. As mentioned before, if there is a way to achieve this functionality entirely in managed code, it is obvoiusly preferable.


Thanks in advance,



DS


0
Comment
Question by:damiensawyer
  • 7
  • 5
  • 3
15 Comments
 
LVL 12

Accepted Solution

by:
roverm earned 250 total points
ID: 9817397
Hi, I tried your code and works just fine (using framework 1.1).

The OCX version is 1.0 which I added to the references of my project.

D'Mzz!
RoverM
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 9817705
When does the error happen?
0
 
LVL 12

Expert Comment

by:roverm
ID: 9817754
Bob:' Try to pass it to MSSCRIPT.OCX - HERE IS WHERE I GET AN ERROR!
          oScriptEngine.AddObject("oStudent", oOb, True)

;-)
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 9817787
Actually, this seems like basic stuff, that I could do with the Script control to multiply a couple of numbers in a class.  Are my eyes deceiving me?  Is there something else that you are using the Script control for?  It just looks like a lot of overhead for nothing, but that's just my opinion.
0
 
LVL 1

Author Comment

by:damiensawyer
ID: 9819887
G'day All,

Thanks for your comments, however I'm still unable to get it to work. Do you mind if I 'restate' and possibly clarify? Roverm, if it works for you, then great! I'm using framework 1.1 and OCX ver 1... so Obviously I must have a setting wrong somewhere.

ok - for starters, I am right clicking on 'references' and adding a reference to c:\windows\system32\msscript.ocx.

I 'had' added it before from the form designer - when I did this, it added an extra library reference, to 'AxMSScriptControl'... However, regardless of where I add the reference, the result is the same. Maybe you could zip your project and email it to me? (dfs@deakin.edu.au).


G'day 'TheLearnedOne'. I'm also interested in your comment that this looks like basic stuff and overkill. If it is, then I'm very keen to see what you mean. In the example that I gave, the scripts are obviously very simple, however in the end application, 'users' will be able to write complex VBScripts - with variable declarations, loops, conditions etc, and have them parsed against the internal objects of the application. These scripts will return results (either boolean statements to test 'validity rules' on data or strings/numbers etc to work as formula results - just like XL). The results will be used at runtime by the application.

You make reference to 'the Script Control'. Which script control is this? Are you able to send me a sample? (either here, or post project to dfs@deakin.edu.au).

Thanks again to both of you, I hope to get to the bottom of this.


DS
0
 
LVL 1

Author Comment

by:damiensawyer
ID: 9820069
Another thing Roverm, What libraries do you have referenced?

I've got

MSScriptControl
System
System.data
System.drawing
System.Windows.Forms
System.XML

Cheers.. .

DS
0
 
LVL 96

Assisted Solution

by:Bob Learned
Bob Learned earned 250 total points
ID: 9820777
Aaah, now I understand.  Sometimes I read a question literally, not allowing for the possibility that it is sample code.  With your explanation, I understand the situation a little better.  

The MSScript control is what I was referring to.

When using the control in .NET, a COM wrapper is generated that may not allow the full functionality of the control.  I think what the problem is that the control expects COM objects, and not .NET objects.
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 12

Expert Comment

by:roverm
ID: 9821012
I reference Microsoft Script Control 1.0 *com object.
0
 
LVL 1

Author Comment

by:damiensawyer
ID: 9821844
" I think what the problem is that the control expects COM objects, and not .NET objects."

yep - that's what I'm thinking. I think that 'Com' objects expose special interfaces (eg iInknown) and that some of these are probably missing from my .Net Objects.

if that's the case, the question becomes "What do I need to add to my .Net objects to get them to work with MSSCRIPT.OCX"


RoverM - at the risk of being pedantic, by "Microsoft Script Control 1.0 *com object" do you mean that you right click on 'references' and then add a reference to c:\windows\system32\msscript.ocx ??

If the code runs on your machine, that is, the name "David" is placed into sResult (I probably should have put a msgbox in the example) then if we can figure out what you're doing that I'm not, we have a solution :-)


Cheers

DS
0
 
LVL 1

Author Comment

by:damiensawyer
ID: 9821905
Further information (but I still need help!)

The function works when I use a string object!

Dim sMyString As String = "Hello"
oScriptEngine.AddObject("oString", sMyString)

' the following line still fails though :-(
'oScriptEngine.AddObject("oStudent", oOb, True)

' Return the result from the script
sResult = oScriptEngine.Eval(sScript)
MsgBox(sResult)



This (strongly) suggests to me that there are some interfaces that I need to be including that I'm not. Help Help Help! :-)

Thanks in Advance,



DS

0
 
LVL 1

Author Comment

by:damiensawyer
ID: 9822453
I’ve found it. The problem was that I didn’t define a NEW constructor with no parameters!

As soon as I changed the class to the following it worked fine.

Public Class clsStudent

      Public sName As String
      Sub New(ByVal i_sName As String)
            sName = i_sName
      End Sub

' Just added a constructor with no parameters
      Sub New()

      End Sub

End Class


Thanks for your help guys - I'll split the points between you... I hope that's cool :-)
0
 
LVL 12

Expert Comment

by:roverm
ID: 9823047
I don't understand why this will work.
First of all: Your initial code works for me.
Second: Adding another Sub New is just an alternative constructor for when you try to instantiate the class without the name. It's the same as
     Sub New(Optional ByVal i_sName As String = "")
          sName = i_sName
     End Sub

What Framework version are you using?

And yes, I right-click the references and select the ms control.

D'Mzz!
RoverM
0
 
LVL 1

Author Comment

by:damiensawyer
ID: 9824511
Hmmm... I see the point you're making...

damn - it's late at night and now I'm confused.

What's even worse, I've just gone and copied/pasted the code from my original posting back into a project and now it works.

hmmmmm.... scratching my head at this point... what changed?? I wonder if it could be a .net/CLR bug??

0
 
LVL 12

Expert Comment

by:roverm
ID: 9824758
*lol* one of many.... ;-)
0
 
LVL 1

Author Comment

by:damiensawyer
ID: 9828671
OK - I think that I've got my head around it now.

It appears that the classes (as in my classes) need to be declared public. This makes sense I suppose. If they're not, the script control would not be able to reference them :-)


Thanks for all your help...


DS
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Summary Displaying images in RichTextBox is a common requirement with limited solutions available. Pasting through clipboard or embedding into RTF content only support static images.  This article describes how to insert Windows control objects int…
Welcome my friends to the second instalment and follow-up to our Minify and Concatenate Your Scripts and Stylesheets (http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/A_4334-Minify-and-Concatenate-Your-Scripts-and-Stylesheets.html)…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now