Search Forum
(57415 Postings)
Search Site/Articles

Archived Articles
712 Articles

C# Books
C# Consultants
What Is C#?
Download Compiler
Code Archive
Archived Articles
Advertise
Contribute
C# Jobs
Beginners Tutorial
C# Contractors
C# Consulting
Links
C# Manual
Contact Us
Legal

GoDiagram for .NET from Northwoods Software www.nwoods.com


              
Printable Version

C# and VSA
By Mat Dietrich

Microsoft released Visual Studio for Applications (VSA) SDK Beta 2. Download the SDK from http://www.msdn.microsoft.com/scripting.

"VSA provides a fully integrated way for customers to seamlessly customize and extend the functionality of Web-based applications using familiar tools." claims Microsoft. What is VSA? It's the .net version of VBA, Visual Basic for Applications, which is used to write Macros and Extensions for Outlook, Word and Excel etc.

You provide the application code, your customer can extend it using scripts.

The following code example shows how to run VB Script or JavaScript inside your .net application.

1) Instantiate the Script Engine.
2) Pass objects to be used by the script to the engine.
3) Add your script to the engine.
4) Compile the script.
5) Get a handle to the objects in the script
6) Get a handle to the method you like to call.
7) Invoke the method.

First compile the VsaArticleEngine.MyEngine into a .dll. Don't forget to change Line 38 to the path on your machine.

Create a ConsoleApplication for VsaArticle.TestVsa and run it.

There are two essential articles written by Microsoft's script guru Andrew Clinick which can be found at:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnclinic/html/scripting091399.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnclinic/html/scripting091399.asp

Enjoy and don't give up, when it doesn't run first time!

using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using Microsoft.Vsa.Hosting;
using Microsoft.Vsa;

namespace VsaArticleEngine 
{
	public class MyEngine : Microsoft.Vsa.IVsaSite
	{
		private IVsaEngine Engine;
		private string MyMoniker = "myapp://uk.co.mdo/MyEngine"; 
		private byte[] Code = new byte[1024];
		private IVsaItems Items;

		public String MyMember;
		public String GetMyMember(){
			return MyMember;
		}
		public void SetMyMember(String MyMember){
			this.MyMember = MyMember;
		}

		public void CreateEngine(){
			Engine = new Microsoft.VisualBasic.Vsa.VsaEngine();
			Engine.RootMoniker = MyMoniker;
			Engine.Name = "aisland";
			Engine.RootNamespace = "VsaArticleEngine";
			Engine.Site = this;
			Items = Engine.Items;
			IVsaReferenceItem  ReferenceItem = (IVsaReferenceItem)Items.CreateItem("VsaArticleEngine",Microsoft.Vsa.VsaItemType.Reference,Microsoft.Vsa.VsaItemFlag.None);
			// set the reference path of the compiled .dll on your machine !!
			ReferenceItem.AssemblyName = "C:\\Documents and Settings\\Administrator.MDO\\My Documents\\Visual Studio Projects\\mdo\\VsaArticleEngine\\bin\\Debug\\VsaArticleEngine.dll";
			IVsaGlobalItem Globalitem = (IVsaGlobalItem)(Items.CreateItem("HostObject", VsaItemType.AppGlobal,Microsoft.Vsa.VsaItemFlag.None));
			Globalitem.TypeString = "VsaArticleEngine.MyEngine";
		}

		public bool AddScript(String Script){
			IVsaCodeItem CodeItem = (IVsaCodeItem)Items.CreateItem("myCode",Microsoft.Vsa.VsaItemType.Code,Microsoft.Vsa.VsaItemFlag.Class);
			CodeItem.SourceText = Script;
			return Engine.Compile();
		}

		public void StartEngine(){
			Console.WriteLine("\n--starting the engine");
			Engine.Run();
		}

		public void ShowResult(){
			try{

				// get an Array of Types in the script
				Console.WriteLine("\n-- Types found in the script: \n");
				System.Type[] MyType = Engine.Assembly.GetTypes();		
				IEnumerator En = MyType.GetEnumerator();
				while (En.MoveNext()){
					Console.WriteLine(En.Current);
				}

				// get an Array of methods of Type myModule in the script
				System.Type Tp = Engine.Assembly.GetType("VsaArticleEngine.myModule",true,true);
				MethodInfo[] Mi = Tp.GetMethods();
				IEnumerator Enu = Mi.GetEnumerator();
				Console.WriteLine("\nMethods found in the script: \n");
				while(Enu.MoveNext()){
					Console.WriteLine(Enu.Current);
				}

				// get a handle to myMethod
				MethodInfo Method = Tp.GetMethod("myMethod");
				object Result;

				// call the Method
				Result = Method.Invoke(this,null);
				Console.WriteLine("\n--MyMethod\n" + Result.ToString());
				Console.WriteLine("\n--MyMember\n" + MyMember.ToString());

			}catch(Exception e){
				Console.WriteLine(e.Message);
			}
		}
		
		// the implementation of IVsaSite 
		public object GetEventSourceInstance(string itemName,string eventSourceName){
			Console.WriteLine("---GetEventSourceInstance" + itemName + eventSourceName);
			return this;
		}

		public void GetCompiledState(out byte[] pe, out byte[] debugInfo){
			Console.WriteLine("\n---GetCompiledState");
			pe = Code;
			debugInfo = null;
		}

		public object GetGlobalInstance(string name){
			Console.WriteLine("\n---GetGlobalInstance " + name);
			return this;
		}

		public void Notify(string notify,object info){
			Console.WriteLine("\n---Notify: " + notify + info.ToString());
		}

		public bool OnCompilerError(IVsaError error){
			Console.WriteLine("\n---OnCompilerError");
			Console.WriteLine(error.Description);
			return false;
		}
	}
}



using System;
using VsaArticleEngine;

namespace VsaArticle
{
	class TestVsa
	{
		static void Main(string[] args)
		{
            // create VB Script
			String script = "Module myModule \n";
			script += " Public function myMethod As String \n ";
			script += "        With HostObject \n";
			script += "			.MyMember = \"my VB Script sets this value.\" \n";
			script += "		End with \n";
			script += " return \"my VB Script function returns this value.\" \n";
			script += " End function \n ";
			script += "End Module \n";

			// Create a new instance of this
			MyEngine TestVsa = new MyEngine();
			
			// create the script engine
			TestVsa.CreateEngine();

			// add script
			TestVsa.AddScript(script);

			//start the engine
			TestVsa.StartEngine();

			//show the result
			TestVsa.ShowResult();

			//stop console window from closing
			Console.ReadLine();
		}
	}
}