Click here to Skip to main content
15,867,330 members
Articles / Programming Languages / C#
Article

C# Script for .NET 2.0

Rate me:
Please Sign up or sign in to vote.
4.83/5 (10 votes)
29 Jan 20065 min read 109.5K   1.1K   49   28
A simple yet amazingly powerful script engine for C# and .NET 2.0.

Introduction

I receive every month or so, a free magazine from VSJ. The articles in the magazine focus on "visual" languages such as Java, VB.NET, etc. Along with the articles, there is an "Outlook" section that discusses some recent developments or something similar, and also book reviews as well as the usual advertising.

In the Feb 5th edition, there was an article entitled "Script it with C#" (you can read the original here). This article is a .NET 2.0 version inspired by the original VSJ article but duly rewritten from the ground up.

Background

I contemplated changing the existing article to support the .NET 2.0 Framework back when it was still in Beta1, however when I tried this, it ran into a plethora of errors, and due to the time constraints, I dropped it. This evening, I decided that it would be nice if it did work under .NET 2.0 (just because of creating support for generics :) ) and so I did it.

Using the code

Included inside the zip file are the source files (or should I say file) along with a VC# Express project to compile it with. However, because it's just a single file, you should be able to compile it quite easily using csc.exe.

There are two routines inside the class, Main and RunScript.

Main

Main, as usual, takes care of loading the program. In this case, all it does is check that a file was passed as the first argument, and then runs it passing the remaining arguments to the script. I decided to leave the first argument in the array so that the script has an easy way of determining where on the hard drive it is located. I.e. arg[0]=scripfile.csx, arg[1...]=....

C#
private static void Main(string[] args)
{
    // If no arguments then display error
    if ((args.Length == 0) || (!File.Exists(args[0])))
    {
        MessageBox.Show("A script file must be provided" + 
          " on the command-line.", "No Script File", 
          MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    else
    {
        // Run the script (we'll leave the first argument so 
        // that the script knows where it is :)
        CSScriptCompiler.RunScript(args[0], args);
    }
}

RunScript

RunScript takes care of all the hard work. Basically, the following steps occur:

  1. The script file is read in, if the line includes a #using, #import, or #target directive, then it is skipped, and these are explained below.
  2. The "Compiler" will insert using statements at the beginning of the source file and reference the necessary assemblies.
  3. The "Compiler" will then create a namespace, a class, and possibly a Main routine to encapsulate the script.
  4. It will then decide whether Main was declared with or without the command-line arguments option and invoke the appropriate method.

#using <namespace>

This is analogous to the C# using statement, it simply imports a namespace so that you can use shorthand versions of the class names. I decided to prefix the statement with a # because it is a bit simpler to avoid clashes with the actual C# statement.

A possibility that crossed my mind was to use regular expressions to increase the robustness of parsing, however, I decided to opt out because it was easier and quicker to accomplish.

#import <filename>

I never got on well with Dino's system of using a separate file to reference the DLLs, the task is made much easier if all the code is contained within one source file and that's why I introduced the #import directive. This basically references an assembly so that you can use it in the script; the filename can be relative, absolute, or if it's on the paths searched by csc, then it can just be a filename.

#include "filename"

This is like the C #include statement. All that really happens is this line is replaced with the contents of filename. You can of course have includes within includes within includes (insert recursion loop here :) ).

Note: Remember to take this into account when debugging errors. I have not thought of an elegant solution which will keep track of the source files or line numbers.

Points of interest

Along with the source / demo project is an installer created with NSIS which will register the .csx extension for the compiler so that when you run a script file, it automatically executes css.exe, the C# script compiler. It also associates an icon with the extension to identify the file-type.

This installer will be compiled when you build the solution (if you have NSIS on your machine and installed in the default path).

Here is a list of the main features of the application:

  • You can simply write code without having to bother about function declarations (see the helloworld.csx file in the samples directory).
  • You can write code which incorporates functions; at the moment, you have to then write the main body of the script file in a valid Main routine.
  • You can use any aspect of .NET you wish; for a simple Windows Forms example, look at the about_css.csx file in the samples directory.

If anybody comes up with any cool or useful scripts that could be included with the source, then send me an email through the CP website and if they're good enough I'll include them in the zip.

History

  • 31st December, 2005
    • First version.
  • 11th January, 2006
    • Changed VS solution to compile as a console app so that the console is displayed for debugging.
    • Added corrections to line numbers in the exception handling code.
  • 20th January, 2006
    • Improved code logic to remove the error message: "Error in source, probably forgot a ; blah blah blah (this was introduced because I couldn't be bothered to code around it previously, but I've done it now :) ).
    • Removed the WinEXE / EXE target option because the console is displayed as the output window for the program so there was no point to it.
  • 25th January, 2006
    • Added #include statement.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Engineer PooreDesign
United Kingdom United Kingdom
Ed is a student who due to a form of cancer (now clear) took a year out before going to Imperial College, London to study Electronic Engineering.

His interests include shooting (clay-pigeon (shotgun), air-rifle and rifle), playing with his three labradors (Sandy, Rosie and Tundra), programming (most experienced in C# and C, although those are not the only ones), walking (has completed Gold Duke of Edinburgh's Award), playing games and reading.

He lives in two places on a 57 acre farm in West Waleswith the rest of the family during the holidays; and Greater London during term time.

Languages and Technologies: C#, C, VB6, VB.NET, XAML, (X)HTML, CSS, XSLT, Assembler (PIC), ASP.NET, WPF, Windows.Forms, ASP, VBScript, JavaScript, Pascal / Delphi, XML

Current Stuff:
1st Year MEng Electronics Engineering (Imperial College, London)

Comments and Discussions

 
PraiseThis is absolutely amazing Pin
cnodnarb12-Jan-16 18:37
cnodnarb12-Jan-16 18:37 
QuestionScript Pin
yardly21-Apr-08 19:08
yardly21-Apr-08 19:08 
AnswerRe: Script Pin
Ed.Poore21-Apr-08 22:21
Ed.Poore21-Apr-08 22:21 
Generaljust like VSTL Pin
c_c55515-Jan-08 18:22
c_c55515-Jan-08 18:22 
Questionmulti threaded ? Pin
Kendavis16-Oct-07 11:14
Kendavis16-Oct-07 11:14 
AnswerRe: multi threaded ? Pin
Ed.Poore16-Oct-07 13:06
Ed.Poore16-Oct-07 13:06 
QuestionAlintex Script Replacement? Pin
aryehof28-Jan-06 16:25
aryehof28-Jan-06 16:25 
AnswerRe: Alintex Script Replacement? Pin
Ed.Poore28-Jan-06 22:21
Ed.Poore28-Jan-06 22:21 
GeneralRe: Alintex Script Replacement? Pin
aryehof29-Jan-06 1:48
aryehof29-Jan-06 1:48 
GeneralRe: Alintex Script Replacement? Pin
Ed.Poore29-Jan-06 4:22
Ed.Poore29-Jan-06 4:22 
GeneralRe: Alintex Script Replacement? Pin
aryehof29-Jan-06 10:33
aryehof29-Jan-06 10:33 
GeneralRe: Alintex Script Replacement? Pin
Ed.Poore29-Jan-06 12:18
Ed.Poore29-Jan-06 12:18 
GeneralSuggestion Pin
leppie25-Jan-06 3:52
leppie25-Jan-06 3:52 
QuestionRe: Suggestion Pin
Ed.Poore25-Jan-06 5:51
Ed.Poore25-Jan-06 5:51 
AnswerRe: Suggestion Pin
leppie25-Jan-06 6:04
leppie25-Jan-06 6:04 
AnswerRe: Suggestion Pin
Ed.Poore25-Jan-06 6:30
Ed.Poore25-Jan-06 6:30 
GeneralRe: Suggestion Pin
leppie25-Jan-06 6:43
leppie25-Jan-06 6:43 
GeneralRe: Suggestion Pin
Ed.Poore25-Jan-06 7:05
Ed.Poore25-Jan-06 7:05 
GeneralRe: Suggestion Pin
leppie25-Jan-06 7:15
leppie25-Jan-06 7:15 
GeneralRe: Suggestion Pin
Ed.Poore25-Jan-06 7:30
Ed.Poore25-Jan-06 7:30 
GeneralSimilarities to Oleg's cscript Pin
tomstrummer20-Jan-06 7:47
tomstrummer20-Jan-06 7:47 
AnswerRe: Similarities to Oleg's cscript Pin
Ed.Poore20-Jan-06 8:14
Ed.Poore20-Jan-06 8:14 
GeneralRe: Similarities to Oleg's cscript Pin
Tras_b11-Sep-06 13:24
Tras_b11-Sep-06 13:24 
GeneralRe: Similarities to Oleg's cscript Pin
Ed.Poore11-Sep-06 21:25
Ed.Poore11-Sep-06 21:25 
General"Error in source code" Pin
dalager19-Jan-06 21:46
dalager19-Jan-06 21:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.