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 | } |