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?
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.
CS-Script: The C# Script Engine
http://www.csscript.net/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With