Just more details about scripting
Using the MS Scripting Object
The MS Scripting Object can be used in .NET applications. But it has several limitations.
The main limitation it has is that all scripted objects must be exposed thru pure COM. The scripting object is a COM component that know nothing about .NET
In general you could do something like the following to expose a component thru COM:
[System.Runtime.InteropServices.ComVisible(true)]
public partial class frmTestVBScript : Form
{
//Rest of code
}
NOTE: you can use that code to do a simple exposure of the form to COM Interop. However to provide a full exposure of a graphical component like a form or user control you should use the Interop Form ToolKit from Microsoft http://msdn.microsoft.com/en-us/vbasic/bb419144.aspx
To expose an object in COM. But most of the properties and methods in a System.Windows.Forms.Form class, use native types instead of COM types.
As you could see in the Backcolor property example:
public int MyBackColor
{
get { return System.Drawing.ColorTranslator.ToOle(this.BackColor); }
set { this.BackColor = System.Drawing.ColorTranslator.FromOle(value); }
}
Issues:
- The problem with properties such as those is that System.Drawing.Color is not COM exposable.
- Your script will expect an object exposing COM-compatible properties.
- Another problem with that is that there might be some name collision.
Using Forms
In general to use your scripts without a lot of modification to your scripts you should do something like this:
- Your forms must mimic the interfaces exposed by VB6 forms. To do that you can use a tool like OLE2View and take a look at the interfaces in VB6.OLB
- Using those interfaces create an interface in C#
- Make your forms implement that interface.
- If your customers have forms that they expose thru com then if those forms add new functionality do this:
- Create a new interface, that extends the basic one you have and
I’m attaching an application showing how to to this.
Performing a CreateObject and Connecting to the Database
The CreateObject command can still be used. To allow compatibility the .NET components must expose the same ProgIds that the used.
ADODB can still be used, and probably RDO and ADO (these last two I haven’t tried a lot)
So I tried a simple script like the following to illustrate this:
Sub ConnectToDB 'declare the variable that will hold new connection object Dim Connection 'create an ADO connection object Set Connection=CreateObject("ADODB.Connection") 'declare the variable that will hold the connection string Dim ConnectionString 'define connection string, specify database driver and location of the database ConnectionString = "Driver={SQL Server};Server=MROJAS\SQLEXPRESS;Database=database1;TrustedConnection=YES" 'open the connection to the database Connection.Open ConnectionString MsgBox "Success Connect. Now lets try to get data" 'declare the variable that will hold our new object Dim Recordset 'create an ADO recordset object Set Recordset=CreateObject("ADODB.Recordset") 'declare the variable that will hold the SQL statement Dim SQL SQL="SELECT * FROM Employees" 'Open the recordset object executing the SQL statement and return records Recordset.Open SQL, Connection 'first of all determine whether there are any records If Recordset.EOF Then MsgBox "No records returned." Else 'if there are records then loop through the fields Do While NOT Recordset.Eof MsgBox Recordset("EmployeeName") & " -- " & Recordset("Salary") Recordset.MoveNext Loop
End If MsgBox "This is the END!" End Sub |
I tested this code with the sample application I’m attaching. Just paste the code, press Add Code, then type ConnectToDB and executeStatement
I’m attaching an application showing how to do this. Look at extended form. Your users will have to make their forms extend the VBForm interface to expose their methods.
Using Events
Event handling has some issues.
All events have to be renamed (at least this is my current experience, I have to investigate further, but the .NET support for COM Events does a binding with the class names I think there’s a workaround for this but I still have not the time to test it).
In general you must create an interface with all events, rename then (in my sample I just renamed them to <Event>2) and then you can use this events.
You must also add handlers for .NET events to raise the COM events.
#region "Events"
public delegate void Click2EventHandler();
public delegate void DblClick2EventHandler();
public delegate void GotFocus2EventHandler();
public event Click2EventHandler Click2;
public event DblClick2EventHandler DblClick2;
public event GotFocus2EventHandler GotFocus2;
public void HookEvents()
{
this.Click += new EventHandler(SimpleForm_Click);
this.DoubleClick += new EventHandler(SimpleForm_DoubleClick);
this.GotFocus += new EventHandler(SimpleForm_GotFocus);
}
void SimpleForm_Click(object sender, EventArgs e)
{
if (this.Click2 != null)
{
try
{
Click2();
}
catch { }
}
}
void SimpleForm_DoubleClick(object sender, EventArgs e)
{
if (this.DblClick2 != null)
{
try
{
DblClick2();
}
catch { }
}
}
void SimpleForm_GotFocus(object sender, EventArgs e)
{
if (this.GotFocus2 != null)
{
try
{
GotFocus2();
}
catch { }
}
}
#endregion
Alternative solutions
Sadly there isn’t currently a nice solution for scripting in .NET. Some people have done some work to implement something like VBScript in .NET (including myself as a personal project but not mature enough I would like your feedback there to know if you will be interesting in a managed version of VBScript) but currently the most mature solution I have seen is Script.NET. This implementation is a true interpreter. http://www.codeplex.com/scriptdotnet Also microsoft is working in a DLR (Dynamic Languages Runtime, this is the runtime that I’m using for my pet project of VBScript)
The problem with some of the other solutions is that they allow you to use a .NET language like CSharp or VB.NET or Jscript.NET and compile it. But the problem with that is that this process generates a new assembly that is then loaded in the running application domain of the .NET Virtual machine. Once an assembly is loaded it cannot be unloaded. So if you compile and load a lot of script you will consume your memory. There are some solutions for this memory consumption issues but they require other changes to your code.
Using other alternatives (unless you used a .NET implementation of VBScript which currently there isn’t a mature one) will require updating all your user scripts. Most of the new scripts are variants of the Javascript language.
Migration tools for VBScript
No. There aren’t a lot of tools for this task. But you can use http://slingfive.com/pages/code/scriptConverter/
Download the code from: http://blogs.artinsoft.net/public_img/ScriptingIssues.zip