Sometimes you need the simplicity of the browser coupled with the power of a full fledged programming framework.
In a previous article about creating a simple .Net REPL, https://medium.com/@mikeptweet/making-a-net-repl-57ca5c465081#.w6xvh925y, I outlined a quick and easy way to access the .Net framework from an interactive REPL. In addition to being able to evaluate expressions and access .Net framework classes and libraries, this simple REPL provides an easy way to cross the bridge between .Net and standard COM Objects. Much of Window’s programming, especially LOB (Line of Business) applications involves COM automation. This is especially true for anyone doing any sophisticated Microsoft Office work. Prior to .Net, COM was the lingua franca of Windows and much of Window’s interoperability was based on COM.
Despite the popularity and growth of the .Net framework, a considerable number of existing Window’s applications are based on COM and in many cases, COM is the only practical way to achieve interop between applications from different vendors. While the .Net framework provides a number of ways to create and access COM objects, these approaches often require considerable knowledge and are not readily accessible to the average “script kiddie” ... for example, https://msdn.microsoft.com/en-us/library/system.runtime.interopservices(v=vs.110).aspx .
Ideally, we want to mix and match .Net and COM objects and leverage the power of both. This is achievable via our REPL, since it treats COM and .Net equally as first class citizens. If we refer back to our earlier article, you can see how easy it is to access .Net framework classes :
Just as easy, we can access COM Objects:
Much of the Window’s application ecosystem is readily accessible to COM and we can create some powerful integrations using the automation interfaces to such applications as Microsoft Office:
$.excel=new ActiveXObject("Excel.Application");$.word=new ActiveXObject("Word.Application");
or database access
$.conn = new ActiveXObject("ADODB.Connection");
Being able to script .Net Framework classes in conjunction with COM objects provides a tremendous toolbox that enables scenarios that would otherwise be out of reach for most business type programmers. By “business type programmers”, I am referring to the girl(or guy) in Account’s Payable who can do things with Excel macros that would make your head spin :-)
One scenario that I have found exceedingly useful on more than one occasion is being able to script the Internet Explorer application to automate web page tasks. This might be as simple as scrapping a web site for information such as Exchange rates, checking stock quotes or just getting the latest weather forecast. Doing this in our REPL is pretty simple. In this simple example, we script Internet Explorer to convert $20 USD to CAD (Canadian $):
Although this is a trivial example, it demonstrates just how powerful a few lines of script code can be in the hands of a creative person. Just to reiterate, we have the full power of COM plus the .Net Framework at our disposal. The beauty of this is it provides unlimited flexibility in terms of how you want to accomplish your task. In another scenario, maybe all you want to do is get the raw HTML from a web page and do some further processing locally. In this case, you could call up the .Net System.Net.WebClient class to get the raw data:
$.html=(new WebClient()).DownloadString("http://example.com");
While being able to script both .Net and COM is very useful, their are times when I want the capabilities of one environment “inside” the other. For example, being able to host a COM object inside .Net or vice versa, hosting a .Net Framework class/object/library inside a COM based application. Again, these capabilities do exist for the seasoned programmers, i.e. I can create an Excel Add-In in either .Net or COM, but they require extensive knowledge as well as a bunch of dependencies and restrictions. Since my mantra has always been “less is more”, I want to be able to do this on the fly, so to speak. Using our .Net REPL, we can do this in a few lines of code. Since objects that are created inside the REPL are “universal COM objects”, that means we can “attach” a .Net object to an existing COM object simply by calling a method or setting a property. For example, the following demonstrates how easy it is to create a new method(function) in Internet Explorer that calls a native .Net class to return a new GUID, which is something not possible via just JavaScript in the browser:
$.ie.document.parentWindow.CreateGuid=function(){return Guid.NewGuid().ToString()};
If you open the Internet Explorer Developer Tools (press F12), you can see that the new function now exists as a method on the DOM window object.
So in a few lines of code, we are able to provide the full functionality of the .Net Framework inside Internet Explorer, fully accessible by the browser’s JavaScript engine.
Indeed, we can take this to the extreme and make anything available in the context of our REPL accessible from within the context of the browser’s Javascript engine. All it takes is a single line of code:
$.ie.document.parentWindow.Repl=$;
This makes any global references (variables, functions, etc) we defined in our REPL available via window.Repl in the browser. Simple define functions on the REPL global $ and they are automatically accessible from the browser. For example, say we want to use the powerful String Formatting capability from .Net inside the browser … it’s a simple as:
$.ie.document.parentWindow.Repl=$;$.format=System.String.Format;
//and from the browser we can do
window.Repl.format("The date is {0}},Date());
Off course, we can simply this even further by assigning the Format method directly to the browser window object:
$.ie.document.parentWindow.format=String.Format;
// and from the browser
window.format("The date is {0}},Date());
//or simplyformat("The date is {0}}.Date());
//since all properties and methods on the window object are global by default.
Again, we can mix and match COM and .Net freely and create some very powerful solutions with very few lines of code. So this means we can equally do something like the following to insert Excel into the browser context:
$.window=$.ie.document.parentWindow;$.window.Excel= new ActiveXObject("Excel.Application");
That’s right, I can now fully script Excel from my browser context!
We’ll leave that for another article :-)