--- a +++ b/trunk/cforge/cforge/Helper.cs @@ -0,0 +1,250 @@ +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Dynamic; +using System.IO; +using System.Linq; +using System.Net; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace cforge +{ + /// <summary> + /// Misc helper classes for all kinds of stuff + /// </summary> + class Helper + { + + const String strAssemblyNameIPY = "IronPython.dll"; + const String strAssemblyNameMSScripting = "Microsoft.Scripting.dll"; + + + #region Registry + + + /// <summary> + /// Function to check if URL Handler for cforge tool is installed + /// </summary> + /// <returns>true, if yes. false, if not</returns> + public static bool CheckRegistryProtocol() + { + RegistryKey cforge = Registry.ClassesRoot.OpenSubKey("cforge"); + if (cforge == null) + { + return false; + + } + return true; + } + + + public static void RegisterProtocol() + { + try + { + String fullpath = GetCFORGEAssemblyPath(); + + RegistryKey cforgekey = Registry.ClassesRoot.OpenSubKey("cforge"); + + cforgekey = Registry.ClassesRoot.CreateSubKey("cforge", true); + cforgekey.SetValue("", "URL:cforge Protocol"); + cforgekey.SetValue("URL Protocol", ""); + + RegistryKey cforgeshell = cforgekey.CreateSubKey("shell"); + RegistryKey shellopen = cforgeshell.CreateSubKey("open"); + RegistryKey opencommand = shellopen.CreateSubKey("command"); + opencommand.SetValue("", "\"" + fullpath + "\" \"%1\""); + + Console.WriteLine("[INFO] Installed URL Handler for cforge tool. \r\n\tPath is: " + fullpath); + } + catch (Exception ex) + { + Console.WriteLine("Exception while adding the registry key. Perhaps you are not admin?"); + Console.WriteLine(ex.ToString()); + } + } + + #endregion + + + + + /// <summary> + /// Function to retrieve the location of the currenty assembly (cforge.exe). + /// This should be located in the CODESYS installation subfolder "CFORGE" + /// </summary> + /// <returns>full path to cforge.exe</returns> + private static String GetCFORGEAssemblyPath() + { + String path = System.Reflection.Assembly.GetExecutingAssembly().Location; + return path; + } + + private static bool IsCODESYSPathInstallation() + { + String path = GetCFORGEAssemblyPath(); + if (path.Contains("bin") && (path.Contains("Debug") || path.Contains("Release"))) + return false; + + return true; + } + + /// <summary> + /// Function to retrieve the CODESYS AP_ROOT (this is where "Common" etc. folders are) + /// </summary> + /// <returns>full path to AP ROOT</returns> + private static String GetCODESYSRoot() + { + if (IsCODESYSPathInstallation()) + { + // twice up from cforge.exe (if installed in CODESYS) + String path = GetCFORGEAssemblyPath(); + path = Directory.GetParent(path).FullName; + return Directory.GetParent(path).FullName; + } + // for now return a normal installation path for CODESYS + return @"C:\Program Files (x86)\3S CODESYS\CODESYS\"; + } + + /// <summary> + /// Function to retrieve the CFORGE Script path (this is where the IronPython scripts should reside) + /// </summary> + /// <returns>full path to CFORGE Scripts</returns> + private static String GetCFORGEScriptPath() + { + if (IsCODESYSPathInstallation()) + { + // <AP_ROOT>\CFORGE\Scripts + String path = GetCODESYSRoot(); + return Path.Combine(path, "CFORGE", "Scripts"); + } + String localscriptpath = System.AppDomain.CurrentDomain.BaseDirectory; + localscriptpath = Directory.GetParent(localscriptpath).FullName; + localscriptpath = Directory.GetParent(localscriptpath).FullName; + localscriptpath = Directory.GetParent(localscriptpath).FullName; + return Path.Combine(localscriptpath,"Package", "CFORGE", "Scripts"); + } + + private static String GetScriptPluginPath() + { + String path = ""; + bool bIPYFound = false; + bool bMSScrFound = false; + + String dir = Path.Combine(GetCODESYSRoot(), "PlugIns", "dc937c18-e9f0-434d-85b7-1b8f499e378a"); + foreach (string item in Directory.EnumerateDirectories(dir)) + { + foreach (string file in Directory.EnumerateFiles(item)) + { + if(Path.GetFileName(file) == strAssemblyNameIPY) + { + bIPYFound = true; + path = item; + } + if (Path.GetFileName(file) == strAssemblyNameMSScripting) + { + bMSScrFound = true; + path = item; + } + } + } + + if(!bIPYFound || !bMSScrFound || !Directory.Exists(path)) + { + Console.WriteLine("[ERROR] No scripting plugin in CODESYS found. Do you use original CODESYS at all?"); + return ""; + } + + return path; + } + + /// <summary> + /// Function to enumerate all IronPython scripts to exend cforge.exe inside Scripts folder + /// </summary> + /// <returns>List of IPY scripts</returns> + public static List<String> GetAllScripts() + { + List<string> liScripts = new List<string>(); + + try + { + String path = GetCFORGEScriptPath(); + foreach (String file in Directory.EnumerateFiles(path)) + { + if (Path.GetExtension(file).ToLowerInvariant() == ".ipy") + { + String shortfilename = Path.GetFileNameWithoutExtension(file); + liScripts.Add(shortfilename); + } + } + } + catch(Exception e) + { + Console.WriteLine("[EXCEPTION] GetAllScripts: " + e.Message); + } + + return liScripts; + } + + #region Scripting + + public static void ExecuteIPyScript(String command, String[] args) + { + String scriptfile = Path.Combine(GetCFORGEScriptPath(), command + ".ipy"); + if (!File.Exists(scriptfile)) + { + Console.WriteLine("[ERROR] Cannot execute script: no such file or directory: " + scriptfile); + return; + } + + + String strAssemblyDir = GetScriptPluginPath(); + if (String.IsNullOrEmpty(strAssemblyDir)) + return; + + try + { + Assembly assemblyIronPython = Assembly.LoadFrom(Path.Combine(strAssemblyDir, strAssemblyNameIPY)); + Assembly assemblyMicrosoftScripting = Assembly.LoadFrom(Path.Combine(strAssemblyDir, strAssemblyNameMSScripting)); + + Type tPython = assemblyIronPython.GetExportedTypes().Where(t => t.FullName == "IronPython.Hosting.Python").First(); + Type tScriptEngine = assemblyMicrosoftScripting.GetExportedTypes().Where(t => t.FullName == "Microsoft.Scripting.Hosting.ScriptEngine").First(); + Type tScriptScope = assemblyMicrosoftScripting.GetExportedTypes().Where(t => t.FullName == "Microsoft.Scripting.Hosting.ScriptScope").First(); + Type tScriptRuntime = assemblyMicrosoftScripting.GetExportedTypes().Where(t => t.FullName == "Microsoft.Scripting.Hosting.ScriptRuntime").First(); + + MethodInfo miCreateRuntime = tPython.GetMethod("CreateRuntime", new Type[] { }); + + MethodInfo miCreateEngine = tPython.GetMethod("CreateEngine", new Type[] { }); + MethodInfo miExecuteFile = tScriptEngine.GetMethod("ExecuteFile", new Type[] { typeof(String) }); + MethodInfo miGetSysModule = tPython.GetMethod("GetSysModule", new Type[] { tScriptRuntime}); + MethodInfo miSetVariable = tScriptScope.GetMethod("SetVariable", new Type[] { typeof(String), typeof(String[]) }); + + var runtime = miCreateRuntime.Invoke(null, null); + var sysmodule = miGetSysModule.Invoke(runtime, null); + + IDictionary<string, object> arguments = new Dictionary<string, object>(); + arguments["Arguments"] = new [] { args }; + //var IronPythonEngine = miCreateEngine.Invoke(null, new object[] { arguments }); + //var IronPythonEngine = miCreateEngine.Invoke(null, null); + + //miExecuteFile.Invoke(IronPythonEngine, new object[] { scriptfile }); + + //var ScriptScore = miGetSysModule.Invoke(IronPythonEngine, null); + + //miSetVariable.Invoke(ScriptScore, new object[] {"argv", args }); + //miExecuteFile.Invoke(IronPythonEngine, new object[] { scriptfile }); + + + } + catch (Exception ex) + { + Console.WriteLine("[EXCEPTION] Execute IPY Script: " + command + ".ipy! " + ex.Message); + } + } + + #endregion + } +}