For those who've been following my antics with string reversals in JavaScript, you may recall me talking about Lychen, my wrapping of V8 JavaScript in a command-line tool accessing C# objects via ClearScript. It's a Claytons Node.js -- the Node you have when you're not having Node.
I heartily recommend ClearScript as a way of adding JavaScript (or VBScript for that matter) to your application. We also use it where I work, though we're still using the other JavaScript engine, Microsoft's JScript.
Question 22 of the ClearScript FAQtorial asks, "Can I expose many host types in one step?" and I've been using the technique discussed there to expose a variety of assemblies into Lychen as a large PropertyBag hanging off the "CS" symbol. This makes possible calls such as,
var mail = CS.System.Net.Mail;
var message = new mail.MailMessage();
message.From = new mail.MailAddress(
CSScriptINI.IniReadValue("Settings", "ReplyToEmail", ""),
CSScriptINI.IniReadValue("Settings", "ReplyToName", ""));
and
var data = CS.System.IO.File.ReadAllText(logfile).split(/\r\n/g);
Just of late I've been trying to work out how to add more.
The FAQtorial's example gives
using Microsoft.ClearScript;
…
var typeCollection = new HostTypeCollection("mscorlib", "System", "System.Core");
engine.AddHostObject("clr", typeCollection);
and up until recently I was doing the same, adding a few more assemblies like RestSharp. For a while I believed that I needed to add these assemblies to my project. I thought this largely because the only way I could have the DLLs appear in my \bin\Debug folder was to have their project in mine.
It took me a while too to figure out that the project name wasn't what needed to be in the list of assembly names. Rather it was the name of the DLL (minus the ".dll" extension).
Just last week I figured out how to add any .NET DLL to a Lychen run. The code is below.
AddHostSymbols
starts with creating symbols CSExtendedHost
and CSHost
to hook to the matching ClearScript objects, ExtendedHostFunctions
and HostFunctions
.
private static void AddHostSymbols(ref V8ScriptEngine v8)
{
v8.AddHostObject("CSExtendedHost", new ExtendedHostFunctions());
v8.AddHostObject("CSHost", new HostFunctions());
Next it instantiates a HostTypeCollection object and adds a pile of assembly names to it. It's assumed that these are readily available either from the GAC or from local to the EXE.
var htc = new HostTypeCollection();
foreach (var assembly in new string[] { "mscorlib", "System", "System.Core", "System.Data", "RestSharp", "WebDriver", "WebDriver.Support" })
{
htc.AddAssembly(assembly);
}
Next comes the reason for my joy.
I have a Settings dictionary (a Dictionary) which contains the command line parameters. I check for the presence of /ASSEMBLIES
. If the symbol is there, I assume that its argument is a comma-separated list of paths to assemblies. I pass each path to System.Reflection.Assembly.LoadFrom()
and then pass the resulting Assembly to the htc object. (.AddAssembly()
will accept a string or an Assembly object.) There's a bit of error checking to catch FileNotFound errors.
if (Settings.ContainsKey("/ASSEMBLIES"))
{
var assemblies = Settings["/ASSEMBLIES"].ToString().Split(',');
foreach (var assembly in assemblies)
{
System.Reflection.Assembly assem;
try
{
assem = System.Reflection.Assembly.LoadFrom(assembly);
htc.AddAssembly(assem);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
finally we hand the htc symbol off to the ClearScript engine.
v8.AddHostObject("CS", htc);
}
What this means is
Lychen /REPL /ASSEMBLIES:"path to dll"
Which could look like this:
>LYCHEN /REPL /ASSEMBLIES:"c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.VisualBasic.dll"
Lychen>CS.Microsoft.VisualBasic
Microsoft.ClearScript.PropertyBag
Lychen>CS.Microsoft.VisualBasic.DateAndTime
HostType:DateAndTime
Lychen>CS.Microsoft.VisualBasic.DateAndTime.DateString
07-27-2019
All sorts of interesting DevOps scripting possibilities there, ہے نہ ؟
Top comments (0)