--- a/trunk/cforge/cforge/Helper.cs +++ b/trunk/cforge/cforge/Helper.cs @@ -1,4 +1,8 @@ -using Microsoft.Win32; +using IronPython.Hosting; +using Microsoft.CSharp.RuntimeBinder; +using Microsoft.Scripting.Hosting; +using Microsoft.Scripting.Runtime; +using Microsoft.Win32; using System; using System.Collections.Generic; using System.Diagnostics; @@ -7,6 +11,7 @@ using System.Linq; using System.Net; using System.Reflection; +using System.Security.Principal; using System.Text; using System.Threading.Tasks; @@ -17,11 +22,7 @@ /// </summary> class Helper { - - const String strAssemblyNameIPY = "IronPython.dll"; - const String strAssemblyNameMSScripting = "Microsoft.Scripting.dll"; - #region Registry @@ -41,7 +42,7 @@ } - public static void RegisterProtocol() + public static void RegisterProtocol(bool bVerbose) { try { @@ -67,16 +68,21 @@ } } + internal static void ShowLicenseInfo() + { + Console.WriteLine("License information "); + Console.WriteLine(""); + Console.Write(Resources.license); + Console.WriteLine(""); + } + #endregion #region SystemPath - public static void AddToSystemPath() - { - // either do it here - //HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\Path - // for now we try it like this: - + public static void AddToSystemPath(bool bVerbose) + { + string strPath = System.Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine); string[] split = strPath.Split(new Char[] { ';' }); @@ -129,6 +135,7 @@ // 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) @@ -149,38 +156,7 @@ 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 @@ -195,7 +171,7 @@ String path = GetCFORGEScriptPath(); foreach (String file in Directory.EnumerateFiles(path)) { - if (Path.GetExtension(file).ToLowerInvariant() == ".ipy") + if (Path.GetExtension(file).ToLowerInvariant() == ".py") { String shortfilename = Path.GetFileNameWithoutExtension(file); liScripts.Add(shortfilename); @@ -210,59 +186,120 @@ return liScripts; } + public static bool IsUserElevated() + { + using (var curIdent = WindowsIdentity.GetCurrent()) + { + var principal = new WindowsPrincipal(curIdent); + return principal.IsInRole(WindowsBuiltInRole.Administrator); + } + } + + public static void RunElevated(String args) + { + String strAssemblyPath = GetCFORGEAssemblyPath(); + + try + { + Process p = new Process(); + p.StartInfo.FileName = strAssemblyPath; + p.StartInfo.Arguments = args; + p.StartInfo.Verb = "runas"; + + p.Start(); + + p.WaitForExit(); + } + catch(Exception ex) + { + Console.WriteLine("[EXCEPTION] RunElevated: " + ex.Message); + } + } + #region Scripting - public static void ExecuteIPyScript(String command, String[] args) - { - String scriptfile = Path.Combine(GetCFORGEScriptPath(), command + ".ipy"); + + public static void ExecuteIPyScript(String command, String[] args, bool bVerbose) + { + String scriptfile = Path.Combine(GetCFORGEScriptPath(), command + ".py"); + Console.WriteLine(); + Console.WriteLine("[INFO] Executing: " + scriptfile); + Console.WriteLine(); + if (!File.Exists(scriptfile)) { - Console.WriteLine("[ERROR] Cannot execute script: no such file or directory: " + scriptfile); + Console.WriteLine(); + Console.WriteLine("[ERROR] Cannot execute command: no such file or directory: " + scriptfile); + Console.WriteLine(); + return; } - - String strAssemblyDir = GetScriptPluginPath(); - if (String.IsNullOrEmpty(strAssemblyDir)) + //ScriptEngine engine = Python.CreateEngine(); + ScriptEngine engine = IronPython.Hosting.Python.CreateEngine(new Dictionary<string, object> { { "Debug", ScriptingRuntimeHelpers.True } }); + Debug.Assert(engine.Runtime.Setup.DebugMode); + + try + { + dynamic sys = Python.GetSysModule(engine); + sys.argv = args; + + var source = engine.CreateScriptSourceFromFile(scriptfile); + dynamic result = source.Execute(); + + //Console.WriteLine("Script finished"); + } + catch (Exception ex) + { + Console.WriteLine(); + + Console.WriteLine("[Exception] command " + command + ".py caused an exception: " + ex.Message); + + ExceptionOperations eo = engine.GetService<ExceptionOperations>(); + string error = eo.FormatException(ex); + Console.WriteLine(error); + + } + } + + + public static void ShowUsageIPyScript(string command, bool v) + { + String scriptfile = Path.Combine(GetCFORGEScriptPath(), command + ".py"); + if (!File.Exists(scriptfile)) + { + Console.WriteLine("[ERROR] Cannot execute command: no such file or directory: " + scriptfile); 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); + } + + ScriptRuntime runtime; + ScriptEngine engine; + runtime = Python.CreateRuntime(); + engine = Python.GetEngine(runtime); + + + + try + { + + dynamic script = runtime.UseFile(scriptfile); + + var help = script.cforge_usage(); + + foreach (var item in help) + { + String cmd = "--" + command + " " + item[0].ToString(); + cmd = cmd.PadRight(32) + item[1]; + Console.WriteLine(cmd); + } + + } + catch + { + + // we silently ignore errors in this script, as we only want to show the usage! + Console.WriteLine(("--" + command).PadRight(32) + ""); + } }