/// <summary> /// Executes the script. /// </summary> /// <param name="p_scpScript">The Mod Script to execute.</param> /// <param name="p_strDataPath">path where script data is stored.</param> /// <param name="p_dynPreset">preset for the installer</param> /// <returns><c>true</c> if the script completes successfully; /// <c>false</c> otherwise.</returns> /// <exception cref="ArgumentException">Thrown if <paramref name="p_scpScript"/> is not a /// <see cref="ModScript"/>.</exception> public override Task <IList <Instruction> > DoExecute(IScript p_scpScript, string p_strDataPath, dynamic p_dynPreset) { if (!(p_scpScript is ModScript)) { throw new ArgumentException("The given script must be of type ModScript.", "p_scpScript"); } ModScript mscScript = (ModScript)p_scpScript; if (string.IsNullOrEmpty(mscScript.Code)) { return(null); } AppDomain admScript = CreateSandbox(p_scpScript, p_strDataPath); object[] args = { m_msfFunctions }; AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); IList <Instruction> instructions = new List <Instruction>(); m_msfFunctions.SetInstructionContainer(instructions); ScriptRunner srnRunner = null; try { srnRunner = (ScriptRunner)admScript.CreateInstanceFromAndUnwrap(typeof(ScriptRunner).Assembly.ManifestModule.FullyQualifiedName, typeof(ScriptRunner).FullName, false, BindingFlags.Default, null, args, null, null); } catch (Exception e) { // TODO rethrow because the transition layer to js seems to have trouble serializing the original exception // of course we want to maintain more of the error message and this shouldn't be here but closer to the // "edge". return(Task.Run(new Func <IList <Instruction> >(() => { throw new Exception("failed to create runner: " + e.GetType().ToString() + "\n" + e.Message + "\n" + e.StackTrace + "\n" + e.Data.ToString()); }))); } finally { // AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve; } return(Task.Run(() => { bool res = srnRunner.Execute(mscScript.Code.Substring(3)); AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve; AppDomain.Unload(admScript); if (!res) { return null; } else { return instructions; } })); }
/// <summary> /// Executes the script. /// </summary> /// <param name="p_scpScript">The Mod Script to execute.</param> /// <param name="p_strDataPath">path where script data is stored.</param> /// <returns><c>true</c> if the script completes successfully; /// <c>false</c> otherwise.</returns> /// <exception cref="ArgumentException">Thrown if <paramref name="p_scpScript"/> is not a /// <see cref="ModScript"/>.</exception> public override Task <IList <Instruction> > DoExecute(IScript p_scpScript, string p_strDataPath) { if (!(p_scpScript is ModScript)) { throw new ArgumentException("The given script must be of type ModScript.", "p_scpScript"); } ModScript mscScript = (ModScript)p_scpScript; if (string.IsNullOrEmpty(mscScript.Code)) { return(null); } AppDomain admScript = CreateSandbox(p_scpScript, p_strDataPath); try { object[] args = { m_msfFunctions }; AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); ScriptRunner srnRunner = null; try { srnRunner = (ScriptRunner)admScript.CreateInstanceFromAndUnwrap(typeof(ScriptRunner).Assembly.ManifestModule.FullyQualifiedName, typeof(ScriptRunner).FullName, false, BindingFlags.Default, null, args, null, null); } finally { AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve; } return(null); // ??? This requires tweaking: Task.Run(() => srnRunner.Execute(mscScript.Code)); } finally { AppDomain.Unload(admScript); } }