5

I have used Python extensively for doing various adhoc data munging and ancillary tasks. Since I am learning C#, I figure it would be fun to see if I can rewrite some of these scripts in C#.

Is there an executable available that takes a .cs file and runs it ala python?

tmthydvnprt
  • 10,398
  • 8
  • 52
  • 72
voidstar
  • 161
  • 1
  • 4
  • 1
    check it here - http://stackoverflow.com/questions/1660452/c-interpreter-without-compilation – cnd May 18 '11 at 07:39
  • Visual Studio has an [immediate window](http://msdn.microsoft.com/en-us/library/f177hahy(v=VS.100).aspx) you can play with – bitxwise May 18 '11 at 07:41
  • 1
    While not quite the same thing, [LINQPad](http://www.linqpad.net/) can work similar to the Python REPL. –  May 18 '11 at 07:41
  • 2
    You might do better looking at PowerShell: designed as a shell and uses .NET as its object model. – Richard May 18 '11 at 07:48

3 Answers3

4

You can do something like this (Create a Console app with code similar to this one)

...
using System.Reflection;
using System.CodeDom.Compiler;
...

namespace YourNameSpace
{
  public interface IRunner
  {
    void Run();
  }

  public class Program
  {
    static Main(string[] args)
    {
      if(args.Length == 1)
      {
        Assembly compiledScript = CompileCode(args[0]);
        if(compiledScript != null)
          RunScript(compiledScript);
      }
    }

    private Assembly CompileCode(string code)
    {
      Microsoft.CSharp.CSharpCodeProvider csProvider = new 
Microsoft.CSharp.CSharpCodeProvider();

      CompilerParameters options = new CompilerParameters();
      options.GenerateExecutable = false;
      options.GenerateInMemory = true;

      // Add the namespaces needed for your code
      options.ReferencedAssemblies.Add("System");
      options.ReferencedAssemblies.Add("System.IO");
      options.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);

      // Compile the code
      CompilerResults result;
      result = csProvider.CompileAssemblyFromSource(options, code);

      if (result.Errors.HasErrors)
      {
        // TODO: Output the errors
        return null;
      }

      if (result.Errors.HasWarnings)
      {
        // TODO: output warnings
      }

      return result.CompiledAssembly;
    }

    private void RunScript(Assembly script)
    {
      foreach (Type type in script.GetExportedTypes())
      {
        foreach (Type iface in type.GetInterfaces())
        {
          if (iface == typeof(YourNameSpace.Runner))
          {
            ConstructorInfo constructor = type.GetConstructor(System.Type.EmptyTypes);
              if (constructor != null && constructor.IsPublic)
              {
                YourNameSpace.IRunner scriptObject = constructor.Invoke(null) as 
YourNameSpace.IRunner;

                if (scriptObject != null)
                {
                  scriptObject.Run();
                }
                else
                {
                  // TODO: Unable to create the object
                }
              }
              else
              {
                // TODO: Not implementing IRunner
              }
            }
          }
        }
      }
  }
}

After creating this console app you can start this like this at a command prompt:

YourPath:\> YourAppName.exe "public class Test : IRunnder { public void Run() { 
Console.WriteLine("woot"); } }"

You can easily change the Main method to accept file instead of inline code, so your console app would have a simillar behaviour as the python or ruby interpreter. Simply pass a filename to your application and read it with a StreamReader in the main function and pass the content to the CompileCode method. Something like this:

static void Main(string[] args)
{
  if(args.Length == 1 && File.Exists(args[0]))
  {
    var assambly = CompileCode(File.ReadAllText(args[0]));
    ...
  }  
}

And on the command line:

YourPath:\> YourApp.exe c:\script.cs

You have to implement the IRunner interface, you could as well simply call a hard-coded Start method without inheriting the interface, that was just to show the concept of compiling class on the fly and executing it.

Hope it help.

Dominic St-Pierre
  • 2,429
  • 3
  • 27
  • 35
1

CS-Script: The C# Script Engine

http://www.csscript.net/

Jonathan Allen
  • 68,373
  • 70
  • 259
  • 447
0

The latest and best way to run C# as a script is to leverage Roslyn. Which is C# compiler written in C#.

Glenn Block, Justin Rusbatch and Filip Wojcieszyn have packaged up Roslyn into a program, called scriptcs, that does exactly what you want.

You can find the project here. http://scriptcs.net/

You can run a C# script file called server.csx by calling

scriptcs server.csx
Aron
  • 15,464
  • 3
  • 31
  • 64