Diff of /trunk/cforge/cforge/Helper.cs [r6] .. [r7]  Maximize  Restore

Switch to unified view

a/trunk/cforge/cforge/Helper.cs b/trunk/cforge/cforge/Helper.cs
1
using Microsoft.Win32;
1
using IronPython.Hosting;
2
using System;
2
using Microsoft.CSharp.RuntimeBinder;
3
using System.Collections.Generic;
3
using Microsoft.Scripting.Hosting;
4
using System.Diagnostics;
4
using Microsoft.Scripting.Runtime;
5
using System.Dynamic;
5
using Microsoft.Win32;
6
using System.IO;
6
using System;
7
using System.Linq;
7
using System.Collections.Generic;
8
using System.Net;
8
using System.Diagnostics;
9
using System.Reflection;
9
using System.Dynamic;
10
using System.Text;
10
using System.IO;
11
using System.Threading.Tasks;
11
using System.Linq;
12
12
using System.Net;
13
namespace cforge
13
using System.Reflection;
14
{
14
using System.Security.Principal;
15
    /// <summary>
15
using System.Text;
16
    /// Misc helper classes for all kinds of stuff
16
using System.Threading.Tasks;
17
    /// </summary>
17
18
    class Helper
18
namespace cforge
19
    {
19
{
20
20
    /// <summary>
21
        const String strAssemblyNameIPY = "IronPython.dll";
21
    /// Misc helper classes for all kinds of stuff
22
        const String strAssemblyNameMSScripting = "Microsoft.Scripting.dll";
22
    /// </summary>
23
        
23
    class Helper
24
24
    {
25
        #region Registry
25
        
26
26
        #region Registry
27
27
28
        /// <summary>
28
29
        /// Function to check if URL Handler for cforge tool is installed
29
        /// <summary>
30
        /// </summary>
30
        /// Function to check if URL Handler for cforge tool is installed
31
        /// <returns>true, if yes. false, if not</returns>
31
        /// </summary>
32
        public static bool CheckRegistryProtocol()
32
        /// <returns>true, if yes. false, if not</returns>
33
        {
33
        public static bool CheckRegistryProtocol()
34
            RegistryKey cforge = Registry.ClassesRoot.OpenSubKey("cforge");
34
        {
35
            if (cforge == null)
35
            RegistryKey cforge = Registry.ClassesRoot.OpenSubKey("cforge");
36
            {
36
            if (cforge == null)
37
                return false;
37
            {
38
38
                return false;
39
            }
39
40
            return true;
40
            }
41
        }
41
            return true;
42
42
        }
43
43
44
        public static void RegisterProtocol()
44
45
        {
45
        public static void RegisterProtocol(bool bVerbose)
46
            try
46
        {
47
            {
47
            try
48
                String fullpath = GetCFORGEAssemblyPath();
48
            {
49
49
                String fullpath = GetCFORGEAssemblyPath();
50
                RegistryKey cforgekey = Registry.ClassesRoot.OpenSubKey("cforge");
50
51
51
                RegistryKey cforgekey = Registry.ClassesRoot.OpenSubKey("cforge");
52
                cforgekey = Registry.ClassesRoot.CreateSubKey("cforge", true);
52
53
                cforgekey.SetValue("", "URL:cforge Protocol");
53
                cforgekey = Registry.ClassesRoot.CreateSubKey("cforge", true);
54
                cforgekey.SetValue("URL Protocol", "");
54
                cforgekey.SetValue("", "URL:cforge Protocol");
55
55
                cforgekey.SetValue("URL Protocol", "");
56
                RegistryKey cforgeshell = cforgekey.CreateSubKey("shell");
56
57
                RegistryKey shellopen = cforgeshell.CreateSubKey("open");
57
                RegistryKey cforgeshell = cforgekey.CreateSubKey("shell");
58
                RegistryKey opencommand = shellopen.CreateSubKey("command");
58
                RegistryKey shellopen = cforgeshell.CreateSubKey("open");
59
                opencommand.SetValue("", "\"" + fullpath + "\" \"%1\"");
59
                RegistryKey opencommand = shellopen.CreateSubKey("command");
60
60
                opencommand.SetValue("", "\"" + fullpath + "\" \"%1\"");
61
                Console.WriteLine("[INFO] Installed URL Handler for cforge tool. \r\n\tPath is: " + fullpath);
61
62
            }
62
                Console.WriteLine("[INFO] Installed URL Handler for cforge tool. \r\n\tPath is: " + fullpath);
63
            catch (Exception ex)
63
            }
64
            {
64
            catch (Exception ex)
65
                Console.WriteLine("Exception while adding the registry key. Perhaps you are not admin?");
65
            {
66
                Console.WriteLine(ex.ToString());
66
                Console.WriteLine("Exception while adding the registry key. Perhaps you are not admin?");
67
            }
67
                Console.WriteLine(ex.ToString());
68
        }
68
            }
69
69
        }
70
        #endregion
70
71
71
        internal static void ShowLicenseInfo()
72
        #region SystemPath
72
        {
73
73
            Console.WriteLine("License information ");
74
        public static void AddToSystemPath()
74
            Console.WriteLine("");
75
        {
75
            Console.Write(Resources.license);
76
            // either do it here
76
            Console.WriteLine("");
77
            //HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\Path
77
        }
78
            // for now we try it like this:
78
79
79
        #endregion
80
            string strPath = System.Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine);
80
81
            string[] split = strPath.Split(new Char[] { ';' });
81
        #region SystemPath
82
82
83
            String path = Path.GetDirectoryName(GetCFORGEAssemblyPath());
83
        public static void AddToSystemPath(bool bVerbose)
84
            String strNewSystemPath = strPath + ";" + path;
84
        {
85
85
            
86
            if (!split.Contains(path))
86
            string strPath = System.Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine);
87
            {
87
            string[] split = strPath.Split(new Char[] { ';' });
88
                System.Environment.SetEnvironmentVariable("Path", strNewSystemPath, EnvironmentVariableTarget.Machine);
88
89
            }
89
            String path = Path.GetDirectoryName(GetCFORGEAssemblyPath());
90
90
            String strNewSystemPath = strPath + ";" + path;
91
        }
91
92
92
            if (!split.Contains(path))
93
        #endregion
93
            {
94
94
                System.Environment.SetEnvironmentVariable("Path", strNewSystemPath, EnvironmentVariableTarget.Machine);
95
95
            }
96
        /// <summary>
96
97
        /// Function to retrieve the location of the currenty assembly (cforge.exe).
97
        }
98
        /// This should be located in the CODESYS installation subfolder "CFORGE"
98
99
        /// </summary>
99
        #endregion
100
        /// <returns>full path to cforge.exe</returns>
100
101
        private static String GetCFORGEAssemblyPath()
101
102
        {
102
        /// <summary>
103
            String path = System.Reflection.Assembly.GetExecutingAssembly().Location;
103
        /// Function to retrieve the location of the currenty assembly (cforge.exe).
104
            return path;
104
        /// This should be located in the CODESYS installation subfolder "CFORGE"
105
        }
105
        /// </summary>
106
106
        /// <returns>full path to cforge.exe</returns>
107
        private static bool IsCODESYSPathInstallation()
107
        private static String GetCFORGEAssemblyPath()
108
        {
108
        {
109
            String path = GetCFORGEAssemblyPath();
109
            String path = System.Reflection.Assembly.GetExecutingAssembly().Location;
110
            if (path.Contains("bin") && (path.Contains("Debug") || path.Contains("Release")))
110
            return path;
111
                return false;
111
        }
112
112
113
            return true;
113
        private static bool IsCODESYSPathInstallation()
114
        }
114
        {
115
115
            String path = GetCFORGEAssemblyPath();
116
        /// <summary>
116
            if (path.Contains("bin") && (path.Contains("Debug") || path.Contains("Release")))
117
        /// Function to retrieve the CODESYS AP_ROOT (this is where "Common" etc. folders are)
117
                return false;
118
        /// </summary>
118
119
        /// <returns>full path to AP ROOT</returns>
119
            return true;
120
        private static String GetCODESYSRoot()
120
        }
121
        {
121
122
            if (IsCODESYSPathInstallation())
122
        /// <summary>
123
            {
123
        /// Function to retrieve the CODESYS AP_ROOT (this is where "Common" etc. folders are)
124
                // twice up from cforge.exe (if installed in CODESYS)
124
        /// </summary>
125
                String path = GetCFORGEAssemblyPath();
125
        /// <returns>full path to AP ROOT</returns>
126
                path = Directory.GetParent(path).FullName;
126
        private static String GetCODESYSRoot()
127
                return Directory.GetParent(path).FullName;
127
        {
128
            }
128
            if (IsCODESYSPathInstallation())
129
            // for now return a normal installation path for CODESYS
129
            {
130
            return @"C:\Program Files (x86)\3S CODESYS\CODESYS\";
130
                // twice up from cforge.exe (if installed in CODESYS)
131
        }
131
                String path = GetCFORGEAssemblyPath();
132
132
                path = Directory.GetParent(path).FullName;
133
        /// <summary>
133
                return Directory.GetParent(path).FullName;
134
        /// Function to retrieve the CFORGE Script path (this is where the IronPython scripts should reside)
134
            }
135
        /// </summary>
135
            // for now return a normal installation path for CODESYS
136
        /// <returns>full path to CFORGE Scripts</returns>
136
            return @"C:\Program Files (x86)\3S CODESYS\CODESYS\";
137
        private static String GetCFORGEScriptPath()
137
        }
138
        {
138
139
            if (IsCODESYSPathInstallation())
139
140
            {
140
        /// <summary>
141
                // <AP_ROOT>\CFORGE\Scripts
141
        /// Function to retrieve the CFORGE Script path (this is where the IronPython scripts should reside)
142
                String path = GetCODESYSRoot();
142
        /// </summary>
143
                return Path.Combine(path, "CFORGE", "Scripts");
143
        /// <returns>full path to CFORGE Scripts</returns>
144
            }
144
        private static String GetCFORGEScriptPath()
145
            String localscriptpath = System.AppDomain.CurrentDomain.BaseDirectory;
145
        {
146
            localscriptpath = Directory.GetParent(localscriptpath).FullName;
146
            if (IsCODESYSPathInstallation())
147
            localscriptpath = Directory.GetParent(localscriptpath).FullName;
147
            {
148
            localscriptpath = Directory.GetParent(localscriptpath).FullName;
148
                // <AP_ROOT>\CFORGE\Scripts
149
            return Path.Combine(localscriptpath,"Package", "CFORGE", "Scripts");
149
                String path = GetCODESYSRoot();
150
        }
150
                return Path.Combine(path, "CFORGE", "Scripts");
151
151
            }
152
        private static String GetScriptPluginPath()
152
            String localscriptpath = System.AppDomain.CurrentDomain.BaseDirectory;
153
        {
153
            localscriptpath = Directory.GetParent(localscriptpath).FullName;
154
            String path = "";
154
            localscriptpath = Directory.GetParent(localscriptpath).FullName;
155
            bool bIPYFound = false;
155
            localscriptpath = Directory.GetParent(localscriptpath).FullName;
156
            bool bMSScrFound = false;
156
            return Path.Combine(localscriptpath,"Package", "CFORGE", "Scripts");
157
            
157
        }
158
            String dir = Path.Combine(GetCODESYSRoot(), "PlugIns", "dc937c18-e9f0-434d-85b7-1b8f499e378a");
158
159
            foreach (string item in Directory.EnumerateDirectories(dir))
159
       
160
            {
160
161
                foreach (string file in Directory.EnumerateFiles(item))
161
        /// <summary>
162
                {
162
        /// Function to enumerate all IronPython scripts to exend cforge.exe inside Scripts folder
163
                    if(Path.GetFileName(file) == strAssemblyNameIPY)
163
        /// </summary>
164
                    {
164
        /// <returns>List of IPY scripts</returns>
165
                        bIPYFound = true;
165
        public static List<String> GetAllScripts()
166
                        path = item;
166
        {
167
                    }
167
            List<string> liScripts = new List<string>();
168
                    if (Path.GetFileName(file) == strAssemblyNameMSScripting)
168
169
                    {
169
            try
170
                        bMSScrFound = true;
170
            {
171
                        path = item;
171
                String path = GetCFORGEScriptPath();
172
                    }
172
                foreach (String file in Directory.EnumerateFiles(path))
173
                }
173
                {
174
            }
174
                    if (Path.GetExtension(file).ToLowerInvariant() == ".py")
175
175
                    {
176
            if(!bIPYFound || !bMSScrFound || !Directory.Exists(path))
176
                        String shortfilename = Path.GetFileNameWithoutExtension(file);
177
            {
177
                        liScripts.Add(shortfilename);
178
                Console.WriteLine("[ERROR] No scripting plugin in CODESYS found. Do you use original CODESYS at all?");
178
                    }
179
                return "";
179
                }
180
            }
180
            }
181
181
            catch(Exception e)
182
            return path;
182
            {
183
        }
183
                Console.WriteLine("[EXCEPTION] GetAllScripts: " + e.Message);
184
184
            }
185
        /// <summary>
185
186
        /// Function to enumerate all IronPython scripts to exend cforge.exe inside Scripts folder
186
            return liScripts;
187
        /// </summary>
187
        }
188
        /// <returns>List of IPY scripts</returns>
188
189
        public static List<String> GetAllScripts()
189
        public static bool IsUserElevated()
190
        {
190
        {
191
            List<string> liScripts = new List<string>();
191
            using (var curIdent = WindowsIdentity.GetCurrent())
192
192
            {
193
            try
193
                var principal = new WindowsPrincipal(curIdent);
194
            {
194
                return principal.IsInRole(WindowsBuiltInRole.Administrator);
195
                String path = GetCFORGEScriptPath();
195
            }
196
                foreach (String file in Directory.EnumerateFiles(path))
196
        }
197
                {
197
198
                    if (Path.GetExtension(file).ToLowerInvariant() == ".ipy")
198
        public static void RunElevated(String args)
199
                    {
199
        {
200
                        String shortfilename = Path.GetFileNameWithoutExtension(file);
200
            String strAssemblyPath = GetCFORGEAssemblyPath();
201
                        liScripts.Add(shortfilename);
201
202
                    }
202
            try
203
                }
203
            {
204
            }
204
                Process p = new Process();
205
            catch(Exception e)
205
                p.StartInfo.FileName = strAssemblyPath;
206
            {
206
                p.StartInfo.Arguments = args;
207
                Console.WriteLine("[EXCEPTION] GetAllScripts: " + e.Message);
207
                p.StartInfo.Verb = "runas";
208
            }
208
209
209
                p.Start();
210
            return liScripts;
210
211
        }
211
                p.WaitForExit();
212
212
            }
213
        #region Scripting
213
            catch(Exception ex)
214
214
            {
215
        public static void ExecuteIPyScript(String command, String[] args)
215
                Console.WriteLine("[EXCEPTION] RunElevated: " + ex.Message);
216
        {
216
            }
217
            String scriptfile = Path.Combine(GetCFORGEScriptPath(), command + ".ipy");
217
        }
218
            if (!File.Exists(scriptfile))
218
219
            {
219
        #region Scripting
220
                Console.WriteLine("[ERROR] Cannot execute script: no such file or directory: " + scriptfile);
220
221
                return;
221
222
            }
222
        public static void ExecuteIPyScript(String command, String[] args, bool bVerbose)
223
223
        {
224
224
            String scriptfile = Path.Combine(GetCFORGEScriptPath(), command + ".py");
225
            String strAssemblyDir = GetScriptPluginPath();
225
            Console.WriteLine();
226
            if (String.IsNullOrEmpty(strAssemblyDir))
226
            Console.WriteLine("[INFO] Executing: " + scriptfile);
227
                return;
227
            Console.WriteLine();
228
228
229
            try
229
            if (!File.Exists(scriptfile))
230
            {
230
            {
231
                Assembly assemblyIronPython = Assembly.LoadFrom(Path.Combine(strAssemblyDir, strAssemblyNameIPY));
231
                Console.WriteLine();
232
                Assembly assemblyMicrosoftScripting = Assembly.LoadFrom(Path.Combine(strAssemblyDir, strAssemblyNameMSScripting));
232
                Console.WriteLine("[ERROR] Cannot execute command: no such file or directory: " + scriptfile);
233
233
                Console.WriteLine();
234
                Type tPython = assemblyIronPython.GetExportedTypes().Where(t => t.FullName == "IronPython.Hosting.Python").First();
234
235
                Type tScriptEngine = assemblyMicrosoftScripting.GetExportedTypes().Where(t => t.FullName == "Microsoft.Scripting.Hosting.ScriptEngine").First();
235
                return;
236
                Type tScriptScope = assemblyMicrosoftScripting.GetExportedTypes().Where(t => t.FullName == "Microsoft.Scripting.Hosting.ScriptScope").First();
236
            }
237
                Type tScriptRuntime = assemblyMicrosoftScripting.GetExportedTypes().Where(t => t.FullName == "Microsoft.Scripting.Hosting.ScriptRuntime").First();
237
238
238
            //ScriptEngine engine = Python.CreateEngine();
239
                MethodInfo miCreateRuntime = tPython.GetMethod("CreateRuntime", new Type[] {  });
239
            ScriptEngine engine = IronPython.Hosting.Python.CreateEngine(new Dictionary<string, object> { { "Debug", ScriptingRuntimeHelpers.True } });
240
240
            Debug.Assert(engine.Runtime.Setup.DebugMode);
241
                MethodInfo miCreateEngine = tPython.GetMethod("CreateEngine", new Type[] { });
241
242
                MethodInfo miExecuteFile = tScriptEngine.GetMethod("ExecuteFile", new Type[] { typeof(String) });
242
            try
243
                MethodInfo miGetSysModule = tPython.GetMethod("GetSysModule", new Type[] { tScriptRuntime});
243
            {
244
                MethodInfo miSetVariable = tScriptScope.GetMethod("SetVariable", new Type[] { typeof(String), typeof(String[]) });
244
                dynamic sys  = Python.GetSysModule(engine);
245
245
                sys.argv = args;
246
                var runtime = miCreateRuntime.Invoke(null, null);
246
                
247
                var sysmodule = miGetSysModule.Invoke(runtime, null);
247
                var source = engine.CreateScriptSourceFromFile(scriptfile);
248
248
                dynamic result = source.Execute();
249
                IDictionary<string, object> arguments = new Dictionary<string, object>();
249
250
                arguments["Arguments"] = new [] { args };
250
                //Console.WriteLine("Script finished");
251
                //var IronPythonEngine = miCreateEngine.Invoke(null, new object[] { arguments });
251
            }
252
                //var IronPythonEngine = miCreateEngine.Invoke(null, null);
252
            catch (Exception ex)
253
253
            {
254
                //miExecuteFile.Invoke(IronPythonEngine, new object[] { scriptfile });
254
                Console.WriteLine();
255
 
255
256
                //var ScriptScore = miGetSysModule.Invoke(IronPythonEngine, null);
256
                Console.WriteLine("[Exception] command " + command + ".py caused an exception: " + ex.Message);
257
257
258
                //miSetVariable.Invoke(ScriptScore, new object[] {"argv", args });
258
                ExceptionOperations eo = engine.GetService<ExceptionOperations>();
259
                //miExecuteFile.Invoke(IronPythonEngine, new object[] { scriptfile });
259
                string error = eo.FormatException(ex);
260
                
260
                Console.WriteLine(error);
261
261
262
            }
262
            }
263
            catch (Exception ex)
263
        }
264
            {
264
265
                Console.WriteLine("[EXCEPTION] Execute IPY Script: " + command + ".ipy! " + ex.Message);
265
266
        public static void ShowUsageIPyScript(string command, bool v)
267
        {
268
            String scriptfile = Path.Combine(GetCFORGEScriptPath(), command + ".py");
269
            if (!File.Exists(scriptfile))
270
            {
271
                Console.WriteLine("[ERROR] Cannot execute command: no such file or directory: " + scriptfile);
272
                return;
273
            }
274
275
            ScriptRuntime runtime;
276
            ScriptEngine engine;
277
            runtime = Python.CreateRuntime();
278
            engine = Python.GetEngine(runtime);
279
280
            
281
282
            try
283
            {
284
                
285
                dynamic script = runtime.UseFile(scriptfile);
286
287
                var help = script.cforge_usage();
288
289
                foreach (var item in help)
290
                {
291
                    String cmd = "--" + command + " " + item[0].ToString();
292
                    cmd = cmd.PadRight(32) + item[1];
293
                    Console.WriteLine(cmd);
294
                }
295
                
296
            }
297
            catch
298
            {
299
                
300
                // we silently ignore errors in this script, as we only want to show the usage!
301
                Console.WriteLine(("--" + command).PadRight(32) + "");
302
                
266
            }
303
            }
267
        }
304
        }
268
305
269
        #endregion
306
        #endregion
270
    }
307
    }
271
}
308
}