using System; using System.Collections.Generic; using System.Linq; using System.Text; using AyaNova.PlugIn; using GZTW.AyaNova.BLL; using System.ComponentModel; using System.Windows.Forms; using System.Reflection; using System.Data; using System.Text.RegularExpressions; using System.IO; using CSScriptLibrary; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; namespace AyaNova.PlugIn.AyaScript { public class AyaScript : IAyaNovaPlugin { //Holds the image resources from AyaNova //so we can display the correct icons in our plugin System.Resources.ResourceManager resman = null; //Holds the current logged in user's localized text //lookup object LocalizedTextTable LocaleText = null; #region IAyaNovaPlugin Members #region interface properties public string PluginName { get { return "AyaScript"; } } public string PluginVersion { get { return "7.6"; } } public string About { get { return "AyaNova AyaScript plugin"; } } public Guid PluginID { get { return new Guid("{C8FAE0E3-542E-4143-9708-1C3BDA2508B2}"); } } public System.Drawing.Image PluginSmallIcon { get { return Resource.Script16; } } public System.Drawing.Image PluginLargeIcon { get { return Resource.Script24; } } public System.Resources.ResourceManager AyaNovaResourceManager { set { resman = value; } get { return resman; } } #endregion interface properties #region Initialization and Close public bool Initialize(Version AyaNovaVersion, LocalizedTextTable localizedText) { LocaleText = localizedText; if (!Util.LoadScripts()) { MessageBox.Show("AyaScript plugin disabled due to error loading scripts!"); return false; } Util.AYS = this; return true; } public void Close() { Util.AYS=null; } #endregion Initialization and close #region ShowMenu? public bool SingleObjectMenuShow(RootObjectTypes objectType) { return true; } public bool MultipleObjectsMenuShow(RootObjectTypes objectType) { return true; } #endregion show menu? #region Menu options public List SingleObjectMenuOptions(RootObjectTypes objectType, object ayaNovaObject) { List list = new List(); list.Add(new AyaNovaPluginMenuItem("AyaScriptEditor", "AyaScript Editor", Resource.Script24, Resource.Script16)); foreach (Util.ScriptItem i in Util.ScriptList) { if(i.Show(true,objectType)) list.Add(new AyaNovaPluginMenuItem(i.ScriptID.ToString(), i.ScriptName, null, null)); } return list; } public List MultipleObjectsMenuOptions(RootObjectTypes objectType) { List list = new List(); list.Add(new AyaNovaPluginMenuItem("AyaScriptEditor", "AyaScript Editor", Resource.Script24, Resource.Script16)); foreach (Util.ScriptItem i in Util.ScriptList) { if (i.Show(false, objectType)) list.Add(new AyaNovaPluginMenuItem(i.ScriptID.ToString(), i.ScriptName, null, null)); } return list; } #endregion #region Menu Commands #region LIST OBJECT COMMAND /// /// LIST OBJECT /// /// /// /// /// /// public bool CommandSelectedForList(string commandKey, RootObjectTypes objectType, List objectIDList, object listObject) { if (commandKey == "AyaScriptEditor") { ScriptDesigner sd = new ScriptDesigner(); sd.ShowDialog(); sd.Dispose(); return true; } Util.ExecuteScript(new Guid(commandKey), true, objectType, listObject, objectIDList); return true; } #endregion list object command #region SINGLE OBJECT COMMAND /// /// SINGLE OBJECT /// /// /// /// public void CommandSelectedForSingleObject(string commandKey, RootObjectTypes objectType, object ayaNovaObject) { if (commandKey == "AyaScriptEditor") { ScriptDesigner sd = new ScriptDesigner(); sd.ShowDialog(); sd.Dispose(); return; } Util.ExecuteScript(new Guid(commandKey),false, objectType, ayaNovaObject, new List()); } #endregion single object command #endregion menu commands #endregion } public class Util { public static AyaScript AYS { get; set; } #region Regular expressions //Name: MyTestCode public static Regex rxName = new Regex( "//Name:\\s*([^\\r\\n]*)", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled ); //ShowInMenuFor: List / SingleObject / Everywhere / MainOnly public static Regex rxShowInMenuFor = new Regex( "//ShowInMenuFor:\\s*([^\\r\\n]*)", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled ); //HandlesAyaNovaTypes: Client, HeadOffice, Unit public static Regex rxHandlesAyaNovaTypes = new Regex( "//HandlesAyaNovaTypes:\\s*([^\\r\\n]*)", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled ); // //UniqueID: Guid // public static Regex rxUniqueID = new Regex( // "//UniqueID:\\s*([^\\r\\n]*)", //RegexOptions.IgnoreCase //| RegexOptions.Multiline //| RegexOptions.Compiled //); #endregion regex #region script store private static List mScriptList; public static List ScriptList { get { if (mScriptList == null) mScriptList = new List(); return mScriptList; } } private static string dbFile = ""; public static bool LoadScripts() { //check for db file in same folder this plugin loaded from and if not found create one dbFile = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\AyaScripts.xml"; DataTable dt = new DataTable("Scripts"); #region Load or create scripts file if (File.Exists(dbFile)) { try { dt.ReadXml(dbFile); } catch (Exception ex) { MessageBox.Show("AyaScript plugin failed to load scripts from " + dbFile + ", error: \r\n" + ex.Message); return false; } } else { //create it try { //setup the columns dt.Columns.Add("script", typeof(string)); dt.WriteXml(dbFile, XmlWriteMode.WriteSchema); } catch (Exception ex) { MessageBox.Show("AyaScript plugin failed to initialize and write new dataset to " + dbFile + ", error: \r\n" + ex.Message); return false; } } #endregion load or create scripts file #region parse scripts ScriptList.Clear(); foreach (DataRow dr in dt.Rows) ScriptList.Add(new ScriptItem(dr[0].ToString())); #endregion parse return true; } /// /// Persist scripts back to file /// public static void WriteScripts() { DataTable dt = new DataTable("Scripts"); dt.Columns.Add("script", typeof(string)); foreach (ScriptItem i in ScriptList) { DataRow dr = dt.NewRow(); dr[0] = i.ScriptText; dt.Rows.Add(dr); } dt.WriteXml(dbFile, XmlWriteMode.WriteSchema); } /// /// Save a script into the script cache, if a script with the same id exists previously, it's replaced /// /// public static void SaveScript(string sScript, Guid ID) { ScriptItem si = new ScriptItem(sScript); si.ScriptID = ID; //remove if present already since it's been updated DeleteScript(si.ScriptID); ScriptList.Add(si); } /// /// Remove script from cache if present /// /// Guid of script public static void DeleteScript(Guid scriptID) { for(int x=0;x /// Execute script /// /// public static void ExecuteScript(Guid ID, bool IsList, RootObjectTypes objectType, Object ayaNovaObject, List objectIDList) { string s = ""; foreach (ScriptItem si in ScriptList) { if (si.ScriptID == ID) { s=si.ScriptText; break; } } if (!s.Contains("AyaScriptMain")) { MessageBox.Show("Main method AyaScriptMain not found, nothing to execute!"); return; } //for some reason cs-script throws a null reference exception when a null //parameter is passed in if (ayaNovaObject == null) ayaNovaObject = DBNull.Value; try { var script = new AsmHelper(CSScript.LoadMethod(AddUsings(s))); script.Invoke("*.AyaScriptMain", IsList, objectType, ayaNovaObject, objectIDList); } catch (Exception ex) { MessageBox.Show("Error running script:\r\n----- Exception message -----\r\n" + ex.Message); } } /// /// Add the most common using statements /// if not already present /// /// /// private static string AddUsings(string sScript) { System.Text.StringBuilder sb = new StringBuilder(); //if (!sScript.Contains("using System;")) sb.Append("using System;\r\n"); if (!sScript.Contains("using System.Collections.Generic;")) sb.Append("using System.Collections.Generic;\r\n"); if (!sScript.Contains("using System.Data;")) sb.Append("using System.Data;\r\n"); if (!sScript.Contains("using System.Drawing;")) sb.Append("using System.Drawing;\r\n"); if (!sScript.Contains("using System.Text;")) sb.Append("using System.Text;\r\n"); if (!sScript.Contains("using System.Windows.Forms;")) sb.Append("using System.Windows.Forms;\r\n"); if (!sScript.Contains("using GZTW.AyaNova.BLL;")) sb.Append("using GZTW.AyaNova.BLL;\r\n"); if (!sScript.Contains("using AyaNova.PlugIn.AyaScript;")) sb.Append("using AyaNova.PlugIn.AyaScript;\r\n"); sb.Append(sScript); return sb.ToString(); } #endregion script execution #region parse [Serializable] public class ScriptItem { public ScriptItem(string Script) { //parse and set properties ScriptText = Script; //Name ScriptName = Util.rxName.Match(Script).Groups[1].Value; if (string.IsNullOrEmpty(ScriptName)) ScriptName = "Script " + System.DateTime.Now.ToString(); //Show in menu for ScriptShowInMenuFor = Util.rxShowInMenuFor.Match(Script).Groups[1].Value; if (string.IsNullOrEmpty(ScriptShowInMenuFor)) ScriptShowInMenuFor = "Everywhere"; //ID ScriptID = Guid.NewGuid(); //Object types ScriptHandlesTypes = new List(); List lsRootObjects = Util.rxHandlesAyaNovaTypes.Match(Script).Groups[1].Value.Replace(" ", "").Split(',').ToList(); if (lsRootObjects.Count == 0) lsRootObjects = new List(new string[] { "Client" }); foreach (string s in lsRootObjects) { try { ScriptHandlesTypes.Add((RootObjectTypes)Enum.Parse(typeof(RootObjectTypes), s, true)); } catch { } } } public bool Show(bool bFromSingle, RootObjectTypes oType) { if(ScriptShowInMenuFor.Equals("Everywhere", StringComparison.CurrentCultureIgnoreCase)) return true; if(ScriptShowInMenuFor.Equals("Main menu only", StringComparison.CurrentCultureIgnoreCase) && oType== RootObjectTypes.Nothing) return true; if(bFromSingle) { if(!ScriptShowInMenuFor.Equals("Single AyaNova object", StringComparison.CurrentCultureIgnoreCase)) return false; } else { if (!ScriptShowInMenuFor.Equals("List of AyaNova objects", StringComparison.CurrentCultureIgnoreCase)) return false; } if (ScriptHandlesTypes.Contains(oType)) return true; return false; } public string ScriptText { get; set; } public string ScriptName { get; set; } public Guid ScriptID { get; set; } public string ScriptShowInMenuFor { get; set; } public List ScriptHandlesTypes { get; set; } } #endregion parse }//bottom of util class }