using System;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Xml;
using System.Xml.XPath;
namespace CSScript {
static class CSScript {
static void Fatal(string message) {
Console.WriteLine("FATAL: "+message);
Console.ReadKey();
Environment.Exit(1);
}
static private XPathNavigator config;
[STAThread]
static void Main(string[] args) {
try {
if(args.Length<1)
Fatal("Usage: CSScript <csscript_file> [<params>]");
if(!System.IO.File.Exists(args[0]))
Fatal("e1204141741 - File '"+args[0]+"' does not exist");
XmlDocument configXml=new XmlDocument();
configXml.Load(args[0]);
config=configXml.CreateNavigator();
if(config.Select("CSScript/EntryClass").Count!=1)
Fatal("'EntryClass' must be one and only one");
if(config.Select("CSScript/Title").Count!=1)
Fatal("'Title' must be one and only one");
Assembly compiledScript=CompileCode();
var title=config.SelectSingleNode("CSScript/Title");
Console.WriteLine("Starting application '{0}'",title);
Console.Title=title.ToString();
string[] parameters=new string[args.Length-1];
for(var i=1;i<args.Length;i++)
parameters[i-1]=args[i];
if(compiledScript==null)
Fatal("e1204141028 - Application not compiled properly.");
var entryClass=config.SelectSingleNode("CSScript/EntryClass").ToString();
Type mainType=getMainType(compiledScript,entryClass);
if(mainType==null)
Fatal("e1204141029 - Type "+entryClass+" could not be found");
var mainMethod=mainType.GetMethod("Main");
if(mainMethod==null)
Fatal("e1204141030 - Main Method 'Main' not found in class "+entryClass);
mainMethod.Invoke(null,new string[][] { parameters });
Console.Write("Press any key to exit...");
Console.ReadKey();
} catch(Exception e) {
Fatal("e1204141747 - "+e.ToString());
}
}
static Assembly CompileCode() {
Microsoft.CSharp.CSharpCodeProvider csProvider=new Microsoft.CSharp.CSharpCodeProvider();
CompilerParameters options=new CompilerParameters();
options.GenerateExecutable=false;
options.GenerateInMemory=true;
options.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
foreach(var assembly in config.Select("CSScript/ReferencedAssemblies/File"))
options.ReferencedAssemblies.Add(assembly.ToString());
var sources=config.Select("CSScript/CSSources/File");
string[]files=new string[sources.Count];
for(int i=0;i<files.Length;i++) {
sources.MoveNext();
files[i]=sources.Current.ToString();
}
CompilerResults results=csProvider.CompileAssemblyFromFile(options,files);
if(results.Errors.HasErrors||results.Errors.HasWarnings)
foreach(CompilerError error in results.Errors)
Console.WriteLine("COMPILATION "+(error.IsWarning?"WARNING":"ERROR")+": "+error.ToString()+": "+error.FileName+":"+error.Line+"@"+error.Column);
if(results.Errors.HasErrors)
Fatal("e1204141031 - Execution aborted, compilation generated errors!");
return results.CompiledAssembly;
}
static Type getMainType(Assembly script,string typeFullName) {
foreach(Type exportedType in script.GetExportedTypes())
if(exportedType.FullName==typeFullName)
return exportedType;
return null;
}
}
}