public static bool ShouldRun(string name, string code) { if (string.IsNullOrEmpty(code)) { return(false); } try { code = GetCode(code); var script = new AsmHelper(CSScript.LoadMethod(code)); return((bool)script.Invoke("*.ShouldRun")); } catch (ThreadAbortException) { } catch (Exception e) { Logging.Write(LogType.Error, "Error running script (ShouldRun): {0}:{1} ", name, e.Message); } return(false); }
static void CallStaticMethodOfFreeStandingClasslessCode() { //There is no script. //The code consist of the only method definition. //Autoclass is injected by CS-Script engine and user has no control //on class name, which is always Scripting.DynamicClass var assembly = CSScript.LoadMethod( @"public static void SayHello(string greeting) { Console.WriteLine(greeting); }"); AsmHelper script = new AsmHelper(assembly); script.Invoke("*.SayHello", "Hello World!"); //or var SayHello = script.GetStaticMethod(); SayHello("Hello World!"); }
public static void RunCode(string code) { try { CSScript.GlobalSettings.TargetFramework = "v3.5"; //try //{ // var helper = // new AsmHelper(CSScript.LoadMethod(File.ReadAllText(ysfile), GetReferences())); // helper.Invoke("*.Run", ynote); var assembly = CSScript.LoadMethod(code, GetReferences()); using (var execManager = new AsmHelper(assembly)) { execManager.Invoke("*.Main", Globals.Ynote); } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } }
/// <summary> /// Gets a interface/class/value from a script's main method /// </summary> /// <typeparam name="T"></typeparam> /// <param name="reference"></param> /// <param name="ysfile"></param> /// <param name="method"></param> /// <returns></returns> public static T Get <T>(object reference, string ysfile, string method) { T val; var assemblyFileName = ysfile + "c"; CSScript.GlobalSettings.TargetFramework = "v3.5"; //try //{ // var helper = // new AsmHelper(CSScript.LoadMethod(File.ReadAllText(ysfile), GetReferences())); // helper.Invoke("*.Run", ynote); var assembly = !File.Exists(assemblyFileName) ? CSScript.LoadMethod(File.ReadAllText(ysfile), assemblyFileName, true, GetReferences()) : Assembly.LoadFrom(assemblyFileName); using (var execManager = new AsmHelper(assembly)) { val = (T)(execManager.Invoke(method, reference)); } return(val); }
/// <summary> /// 体型&物理スクリプトを読み込みます。 /// </summary> public bool Load() { ProportionList.Instance.Load(); // 物理オブジェクトスクリプトを読み込みます。 string phys_path = Path.Combine(Application.StartupPath, @"PhysObTemplate"); if (!Directory.Exists(phys_path)) { MessageBox.Show("Tso2Pmdを正常に起動できませんでした。\n" + "PhysObTemplateフォルダが見つかりません。"); return(false); } string[] phys_script_files = Directory.GetFiles(phys_path, "*.cs"); foreach (string script_file in phys_script_files) { try { StreamReader sr = new StreamReader(script_file, Encoding.GetEncoding("Shift_JIS")); string text = sr.ReadToEnd(); sr.Close(); string class_name = "TDCG.PhysObTemplate." + Path.GetFileNameWithoutExtension(script_file); //var script = CSScript.Load(script_file, Path.GetTempFileName(), true).CreateInstance(class_name).AlignToInterface<IPhysObTemplate>(); var script = CSScript.LoadCode(text).CreateInstance(class_name).AlignToInterface <IPhysObTemplate>(); phys_items.Add(script); phys_flag.Add(script, false); } catch { MessageBox.Show("Tso2Pmdを正常に起動できませんでした。\n" + "スクリプトファイル(PhysObTemplate/" + Path.GetFileName(script_file) + ")を\n" + "読込中にエラーが発生しました。"); return(false); } } return(true); }
//_________________________________________________________________________________________________________ #region Macro End Execution (with Interface Alignment) //_________________________________________________________________________________________________________ public void ExecMacroEnd(string sMacroFile, string sParam = "") { LogHelper.Msg(); try { currentMacro = ""; currentMacroParam = ""; if (!File.Exists(sMacroFile)) { return; } using (var helper = new AsmHelper(CSScript.CompileFile(sMacroFile), null, false)) { IFIMSyncMacro script = helper.CreateAndAlignToInterface <IFIMSyncMacro>("Script"); script.EndScript(this, sParam); // If an Async method is called, again a new call to EndScript is pending if (MacroHelper.Running) { currentMacro = sMacroFile; currentMacroParam = sParam; } } } catch (Exception ex) { string sMsg = string.Format("[{0}]\n[{1}]\n{2}", sMacroFile, sParam, ex.Message); LogHelper.Msg("ERROR:\n" + sMsg); LogError(sMsg.Replace('\n', '\\')); MessageBox.Show("ERROR:\n" + sMsg, "ExecMacroEnd", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } // If there is not pending activities, call to EndScript while (!MacroHelper.Running && currentMacro != "") { ExecMacroEnd(currentMacro, currentMacroParam); } // Enable timer to call next pending macro or enable menu if (!MacroHelper.Running && pendingMacros.Count > 0) { f.cTimerNextMacro.Enabled = true; } else { f.mExecMacro.Enabled = true; } }
private void loadMessageParsers() { skillParser.Items.Clear(); skillParser.Items.Add(new CBWrapper(new MiningMessageParser())); skillParser.SelectedIndex = 0; String path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); String dirname = path + "\\" + "WurmSkillRatio"; if (!Directory.Exists(dirname)) { return; } String[] files = Directory.GetFiles(dirname, "*.cs"); foreach (String file in files) { try { CSScript.GlobalSettings.AddSearchDir(dirname); AsmHelper asmHelper = new AsmHelper(CSScript.Load(file)); asmHelper.ProbingDirs = CSScript.GlobalSettings.SearchDirs.Split(';'); IMessageParser handler = asmHelper.CreateObject("*").AlignToInterface <IMessageParser>(true); int index = skillParser.Items.IndexOf(handler.getName()); if (index != -1) { skillParser.Items[index] = new CBWrapper(handler); } else { skillParser.Items.Add(new CBWrapper(handler)); } } catch (Exception e) { AddLog(e.Message + "\n"); } } }
/// <summary> /// Builds the dynamic POCO and aligns it to INetworkPackage /// </summary> /// <param name="className">The POCO class name</param> /// <param name="propertyFields">The field's types and names</param> /// <returns>A type that's aligned to INetworkPackage</returns> public Type Build(string className, List <RuntimePropertyInfo> propertyFields) { var str = String.Format(@"using Microsoft.CSharp; using Lidgren.Network; namespace Gem.Network.Builders {{ public class {0} : Gem.Network.Events.INetworkPackage {{ public {0}() {{}} public {0}(NetIncomingMessage msg) {{{4}}} public {0}({1}) {{ {2} }} {3} private byte _Id; public byte Id {{ get {{ return _Id; }} set {{ _Id = value; }} }} }} }}", className, GetConstructorDeclaration(propertyFields), GetConstructorBody(propertyFields), GetGetterSetters(propertyFields), GetDecodeConstructorBody(propertyFields)); return(CSScript.LoadCode(str) .CreateObject("*") .AlignToInterface <INetworkPackage>() .GetType()); }
private void buttonGenerate_Click(object sender, EventArgs e) { this.Cursor = Cursors.WaitCursor; try { GenerateScript(); //todo: background! File.WriteAllText(_scriptFile.Path, textBoxGeneratedScript.Text); AsmHelper scriptAsm = new AsmHelper(CSScript.Load(_scriptFile.Path)); string result = (string)scriptAsm.Invoke("StatisticsTemplate.Run", new object[] { this.OwnerPlugin, Core }); textBoxHtml.Text = result; DisplayHtml(string.Format("<html><head></head><body>{0}</body></html>", result)); tabControl1.SelectedIndex = 3; } catch (Exception ex) { System.Windows.Forms.MessageBox.Show(ex.Message, "Error"); } this.Cursor = Cursors.Default; }
static void TestLifeExtension() { using (var helper = new AsmHelper(CSScript.CompileCode(code), null, false)) { IScript script = helper.CreateAndAlignToInterface <IScript>("*"); int minutes = 1; helper.RemoteObject.ExtendLifeFromMinutes(minutes); (script as MarshalByRefObject).ExtendLifeFromMinutes(minutes); try { Thread.Sleep(1000 * 60 * 2); //call before 7 minutes expire script.Hello("Hi TestLifeExtension1..."); } catch (Exception e) { Console.WriteLine("Error in TestLifeExtension1: " + e.Message); } } }
static void TreatWarningAsError1() { string code = @"//css_co /warnaserror+; using System; public class Calc { static public int Sum(int a, int b) { #warning test warning return a + b; } }"; try { CSScript.LoadCode(code); } catch (CompilerException e) { ReportCompilerError(e); } }
static void TestWithAsmHelperAndUnloadingAssembly() { //we cannot use HelloScript.cs as class Script must //be serializable or derived from MarshalByRefObject var code = @"using System; public class Script : MarshalByRefObject { public void Hello(string greeting) { Console.WriteLine(greeting); } }"; //Note usage of helper.CreateAndAlignToInterface<IScript>("Script") is also acceptable using (var helper = new AsmHelper(CSScript.CompileCode(code), null, false)) { IScript script = helper.CreateAndAlignToInterface <IScript>("*"); script.Hello("Hi there..."); } }
public object LoadScript(string scriptPath) { if (!scriptPath.Contains(":")) { string folder = AppDomain.CurrentDomain.GetData("DataDirectory") + scriptsSubFolder; scriptPath = String.Format(@"{0}\{1}", folder, scriptPath); } var curTime = File.GetLastWriteTime(scriptPath).ToString(); if (loadedScripts.Any(script => script.Path.Equals(scriptPath, StringComparison.InvariantCultureIgnoreCase) && curTime == script.Id)) { return(null); } Log.WriteInfo("Loading script {0}...", scriptPath); DisposeScriptAssembly(scriptPath); var assemblyPath = Path.Combine(Path.GetDirectoryName(scriptPath), Path.GetFileNameWithoutExtension(scriptPath) + ".dll"); AsmHelper asmHelper = new AsmHelper(CSScript.LoadCodeFrom(scriptPath, null, false, null)); var obj = asmHelper.CreateObject("*"); IScriptConfig configObj = obj as IScriptConfig; if (configObj != null) { configObj.Config = GetScriptConfig(scriptPath, obj); } loadedScripts.Add(new ScriptItem( scriptPath, File.GetLastWriteTime(scriptPath).ToString(), asmHelper, obj )); return(obj); }
static void TreatWarningAsError2() { string code = @"using System; public class Calc { static public int Sum(int a, int b) { #warning test warning return a + b; } }"; try { string script = CSSEnvironment.SaveAsTempScript(code); string assembly = CSScript.CompileWithConfig(script, null, false, CSScript.GlobalSettings, "/warnaserror"); } catch (CompilerException e) { ReportCompilerError(e); } }
/// <summary> /// 体型スクリプトを読み込みます。 /// 2回目は読み込みません。 /// </summary> public void Load() { if (items.Count != 0) { return; } string proportion_path = GetProportionPath(); if (!Directory.Exists(proportion_path)) { return; } string[] script_files = Directory.GetFiles(proportion_path, "*.cs"); foreach (string script_file in script_files) { string class_name = "TDCG.Proportion." + Path.GetFileNameWithoutExtension(script_file); var script = CSScript.Load(script_file).CreateInstance(class_name).AlignToInterface <IProportion>(); items.Add(script); } }
private void debugToolStripMenuItem_Click(object sender, EventArgs e) { textBox1.Text += Environment.NewLine; Cursor.Current = Cursors.WaitCursor; try { if (IsScriptChanged()) { using (StreamWriter sw = new StreamWriter(this.dbgSourceFileName)) sw.Write(ConvertToCode(GetLastScript(), true)); scriptAsm = new AsmHelper(CSScript.Load(this.dbgSourceFileName, null, true)); } scriptAsm.Invoke("Script.Main"); scriptAsm = null; } catch (Exception ex) { MessageBox.Show(ex.Message.Trim()); } Cursor.Current = Cursors.Default; }
static public void Main(string[] args) { //indicate that the CS-Script engine should use custom (VB.NET) compiler CSScript.GlobalSettings.UseAlternativeCompiler = Assembly.GetExecutingAssembly().Location; string[] refAssemblies = new[] { typeof(Form).Assembly.Location }; string code = @"Imports System Imports System.Windows.Forms Public Class Script Public Sub Main() Console.WriteLine(""Hello World!"") MessageBox.Show(""Hello World!"") End Sub End Class"; dynamic script = CSScript.LoadCode(code, refAssemblies) .CreateObject("Script"); script.Main(); }
// interfaces to app public void loadScript(String filename) { try { logger.Info("Loading script {0}", filename); Assembly script = CSScript.Load(filename, null, true); foreach (var t in script.GetTypes()) { Type tp = t.GetInterface("IScript"); if (tp != null) { IScript sc = Activator.CreateInstance(t) as IScript; String scname = sc.init(this); scripts.Add(scname, sc); } } } catch (Exception ex) { logger.Error("Error loading script {0}: {1}", filename, ex.ToString()); } }
public void LoadCodeAndAlignToInterface() { lock (As.BlockingTest) { //This use-case uses Interface Alignment and this requires all assemblies involved to have non-empty Assembly.Location CSScript.GlobalSettings.InMemoryAssembly = false; var script = CSScript.LoadCode(@"public class Script { public int Sum(int a, int b) { return a+b; } }") .CreateObject("*") .AlignToInterface <ICalc>(); int result = script.Sum(1, 2); Assert.Equal(3, result); } }
public bool Compile(string SourcetoCompile) { if (UseExplictIncludeofReferences) { evaluator = evaluator.ReferenceAssemblyOf(this); //evaluator.ReferenceAssemblyOf<string>(); evaluator = evaluator.ReferenceAssembliesFromCode(SourcetoCompile); evaluator = evaluator.ReferenceDomainAssemblies(); } GetAssemblies(); // CompiledAssembly = CSScript.Evaluator.CompileCode(SourcetoCompile); try { _CompiledAssembly = evaluator.CompileCode(SourcetoCompile); string result; if (CreateDll) { if (FileName == string.Empty) { FileName = $"{Path.GetTempFileName()}.dll"; } result = CSScript.CompileFile(SourcetoCompile, FileName, false, GetAssemblyNames(evaluator.GetReferencedAssemblies())); } } catch (CompilerException e) { Errors = (List <string>)e.Data["Errors"]; Errors.Add(SourcetoCompile); } catch (Exception e) { Errors.Add(e.Message); } //CSScript.CompilingHistory.Last().Value.Result.Errors.Count; // Results = CSScriptLibrary.CSScript.CompilingHistory.Last().Value.Result;// CSScript.LastCompilingResult.Result; return(Success); }
private bool CompileCSharpCode() { if (ScriptGenerationComplete == false) { return(false); } var progressId = this.ReportStart("Script Compilation", ScriptCode); try { CSScript.ShareHostRefAssemblies = true; CSScript.AssemblyResolvingEnabled = true; //var helper = new AsmHelper(CSScript.LoadCode(code, null, true)); var helper = new AsmHelper(CSScript.LoadCode(ScriptCode)); //the only reflection based call _gmacScriptInstance = (IGMacScript)helper.CreateObject("InteractiveScript"); _gmacScriptInstance.Ipr = Ipr; this.ReportFinish(progressId, "", ProgressEventArgsResult.Success); return(true); } catch (Exception e) { CompilationError = e; this.ReportError(e); this.ReportFinish(progressId, "", ProgressEventArgsResult.Failure); return(false); } }
public static void LoadCode_WithInterface(HostApp host) { // 1 - LoadCode compiles code and returns instance of a first class in the compiled assembly. // 2 - The script class implements host app interface so the returned object can be type casted into it. // 3 - In this sample host object is passed into script routine. var calc = (ICalc)CSScript.LoadCode(@"using CSScriptNativeApi; public class Script : ICalc { public int Sum(int a, int b) { if(Host != null) Host.Log(""Sum is invoked""); return a + b; } public HostApp Host { get; set; } }") .CreateObject("*"); calc.Host = host; int result = calc.Sum(1, 2); }
public static void Main() { var entryAsm = Assembly.GetEntryAssembly(); var thisAsm = Assembly.GetExecutingAssembly(); var hostAsm = Assembly.GetCallingAssembly(); if (thisAsm == entryAsm) { Console.WriteLine("It is not a script assembly but a fully compiled stand alone application."); } if (hostAsm == null) { Console.WriteLine("It is an assembly hosted by " + hostAsm.GetName().Name); } PrintScriptName("reflection #1 ", () => CSScript.GetScriptName(Assembly.GetExecutingAssembly())); PrintScriptName("reflection #2 ", () => Assembly.GetExecutingAssembly().GetScriptName()); PrintScriptName("reflection #3 ", () => GetScriptName(thisAsm)); PrintScriptName("CSSEnvironment #1", () => CSSEnvironment.PrimaryScriptFile); //script that was executed from command line or double-clicked PrintScriptName("CSSEnvironment #2", () => CSSEnvironment.ScriptFile); //script that is currently executed; it may not be a PrimaryScriptFile if it is a pre-execution scripting scenario PrintScriptName("Environment Var ", () => Environment.GetEnvironmentVariable("EntryScript")); }
public static void ExecuteAndUnload() { // The script will be loaded into a temporary AppDomain and unloaded after the execution. // Note: remote execution is a subject of some restrictions associated with the nature of the // CLR cross-AppDomain interaction model: // * the script class must be serializable or derived from MarshalByRefObject. // // * any object (call arguments, return objects) that crosses ApPDomain boundaries // must be serializable or derived from MarshalByRefObject. // // * long living script class instances may get disposed in remote domain even if they are // being referenced in the current AppDomain. You need to use the usual .NET techniques // to prevent that. See LifetimeManagement.cs sample for details. //This use-case uses Interface Alignment and this requires all assemblies involved to have //non-empty Assembly.Location CSScript.GlobalSettings.InMemoryAssembly = false; var code = @"using System; public class Script : MarshalByRefObject { public void Hello(string greeting) { Console.WriteLine(greeting); } }"; //Note: usage of helper.CreateAndAlignToInterface<IScript>("Script") is also acceptable using (var helper = new AsmHelper(CSScript.CompileCode(code), null, deleteOnExit: true)) { IScript script = helper.CreateAndAlignToInterface <IScript>("*"); script.Hello("Hi there..."); } //from this point AsmHelper is disposed and the temp AppDomain is unloaded }
//_________________________________________________________________________________________________________ //_________________________________________________________________________________________________________ public static void Init() { Present = false; string sExtensionFile = GetFirstExtension(); if (sExtensionFile == "") { return; } try { if (!File.Exists(sExtensionFile)) { return; } var helper = new AsmHelper(CSScript.CompileFile(sExtensionFile), null, false); oExtension = helper.CreateAndAlignToInterface <IFIMSyncExtension>("FIMSyncExtension"); Present = true; } catch (Exception ex) { string sMsg = string.Format("[{0}]\n[{1}]", sExtensionFile, ex.Message); LogHelper.Msg("ERROR:\n" + sMsg); MessageBox.Show("ERROR:\n" + sMsg, "FIMSync Extension", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } }
public void LoadPlugins(string dir) { Plugins.Clear(); DeskApp._send = Publish; DeskApp._trace = LogPlugin; foreach (string script in Directory.GetFiles(dir, "*.cs")) { using (StreamReader sr = new StreamReader(script)) { try { string scriptCode = sr.ReadToEnd(); string name = Path.GetFileNameWithoutExtension(script); AsmHelper helper = new AsmHelper(CSScript.LoadCode(scriptCode, null, false)); IPlugin plugin = helper.CreateObject(name) as IPlugin; Plugins.Add(name, plugin); } catch (Exception ex) { //MessageBox.Show(ex.ToString(), "Load Plugin " + script, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); Log(ex.ToString()); } sr.Close(); } } }
public IBuildScript FindAndCreateBuildScriptInstance(string fileName) { CSScript.AssemblyResolvingEnabled = true; Assembly assembly = CSScript.LoadFile(fileName); Type myType = typeof(IBuildScript); List <Type> classes = assembly.GetTypes().Where(i => myType.IsAssignableFrom(i)).ToList(); if (classes.Count <= 0) { string message = string.Format( CultureInfo.InvariantCulture, "Used build script file '{0}' but it does not contain any IBuildScript implementation.", fileName); throw new BuildScriptLocatorException(message); } // ReSharper disable once AssignNullToNotNullAttribute object scriptInstance = assembly.CreateInstance(classes[0].FullName); return(scriptInstance.AlignToInterface <IBuildScript>()); }
/// <summary> /// Initializes a new instance of the <see cref="Script" /> class.<br /> /// Loads and compiles the specified script file. /// </summary> /// <param name="ScriptFile">The FileInfo object for the script file.</param> /// <param name="ThrowExceptions">If set to <c>true</c> a exception will be thrown, if a error occurs when loading and compiling the script file.</param> /// <exception cref="System.Exception">A error occured while loading or loading the script file {0}.</exception> public Script(FileInfo ScriptFile, bool ThrowExceptions = false) { this.File = ScriptFile; Assembly A = null; try { A = CSScript.Load(ScriptFile.FullName, null, true); Assembly = A; Log.Write("Script file loaded and compiled: {0}".Build(ScriptFile.FullName)); } catch (Exception e) { CompilationException = e; Log.Exception("Could not load and compile script file: {0}".Build(ScriptFile.FullName), e); if (ThrowExceptions) { throw new Exception("A error occured while loading or loading the script file {0}.".Build(ScriptFile.FullName), e); } } }
public void CreateDummyTest() { var testCode = GetTestCode(); var assemblyFile = WorkingDirectory + Path.DirectorySeparatorChar + "bin" + Path.DirectorySeparatorChar + "Release" + Path.DirectorySeparatorChar + "CustomTestFixture" + ".dll"; if (!Directory.Exists(Path.GetDirectoryName(assemblyFile))) { Directory.CreateDirectory(Path.GetDirectoryName(assemblyFile)); } var refAssemblies = new string[] { "/lib/NUnit.2.6.0.12051/lib/nunit.framework.dll" }; CSScript.CompileCode(testCode, assemblyFile, true, refAssemblies); }
public IEnumerable <IModObject> Load(Mod mod) { string empsFolder; if (ModPath == null) { //empsFolder = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Pictures", "Races"); empsFolder = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Scripts", "AI"); } else { empsFolder = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), ModPath, "Scripts", "AI"); } //empsFolder = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), ModPath, "Pictures", "Races"); if (Directory.Exists(empsFolder)) { foreach (var empFolder in Directory.GetDirectories(empsFolder)) { if (File.Exists(Path.Combine(empFolder, "AI.py"))) { var script = PythonScript.Load(Path.Combine(empFolder, "AI")); if (script == null) { continue; // script does not exist for this shipset } var ministers = new SafeDictionary <string, ICollection <string> >(); string curCategory = "Uncategorized"; var ministersFile = Path.Combine(empFolder, "AI.ministers"); if (File.Exists(ministersFile)) { foreach (var line in File.ReadAllLines(ministersFile)) { if (line.StartsWith("\t")) { // found a minister name var ministerName = line.Substring(1); if (ministers[curCategory] == null) { ministers[curCategory] = new List <string>(); } ministers[curCategory].Add(ministerName); } else { // found a minister category curCategory = line; } } } var ai = new PythonAI <Empire, Galaxy>(Path.GetFileName(empFolder), script, ministers); mod.EmpireAIs.Add(ai); yield return(ai); } //C# AI. else if (File.Exists(Path.Combine(empFolder, "AI.csx"))) { var script = CSScript.Load(Path.Combine(empFolder, "AI")); if (script == null) { continue; // script does not exist for this shipset } var ministers = new SafeDictionary <string, ICollection <string> >(); string curCategory = "Uncategorized"; var ministersFile = Path.Combine(empFolder, "AI.ministers"); if (File.Exists(ministersFile)) { foreach (var line in File.ReadAllLines(ministersFile)) { if (line.StartsWith("\t")) { // found a minister name var ministerName = line.Substring(1); if (ministers[curCategory] == null) { ministers[curCategory] = new List <string>(); } ministers[curCategory].Add(ministerName); } else { // found a minister category curCategory = line; } } } var ai = new CSAI <Empire, Galaxy>(Path.GetFileName(empFolder), script, ministers); mod.EmpireAIs.Add(ai); yield return(ai); } } } }