a | b/trunk/cforge/cforge/Helper.cs | ||
---|---|---|---|
1 | using Microsoft.Win32; |
||
2 | using System; |
||
3 | using System.Collections.Generic; |
||
4 | using System.Diagnostics; |
||
5 | using System.Dynamic; |
||
6 | using System.IO; |
||
7 | using System.Linq; |
||
8 | using System.Net; |
||
9 | using System.Reflection; |
||
10 | using System.Text; |
||
11 | using System.Threading.Tasks; |
||
12 | |||
13 | namespace cforge |
||
14 | { |
||
15 | /// <summary> |
||
16 | /// Misc helper classes for all kinds of stuff |
||
17 | /// </summary> |
||
18 | class Helper |
||
19 | { |
||
20 | |||
21 | const String strAssemblyNameIPY = "IronPython.dll"; |
||
22 | const String strAssemblyNameMSScripting = "Microsoft.Scripting.dll"; |
||
23 | |||
24 | |||
25 | #region Registry |
||
26 | |||
27 | |||
28 | /// <summary> |
||
29 | /// Function to check if URL Handler for cforge tool is installed |
||
30 | /// </summary> |
||
31 | /// <returns>true, if yes. false, if not</returns> |
||
32 | public static bool CheckRegistryProtocol() |
||
33 | { |
||
34 | RegistryKey cforge = Registry.ClassesRoot.OpenSubKey("cforge"); |
||
35 | if (cforge == null) |
||
36 | { |
||
37 | return false; |
||
38 | |||
39 | } |
||
40 | return true; |
||
41 | } |
||
42 | |||
43 | |||
44 | public static void RegisterProtocol() |
||
45 | { |
||
46 | try |
||
47 | { |
||
48 | String fullpath = GetCFORGEAssemblyPath(); |
||
49 | |||
50 | RegistryKey cforgekey = Registry.ClassesRoot.OpenSubKey("cforge"); |
||
51 | |||
52 | cforgekey = Registry.ClassesRoot.CreateSubKey("cforge", true); |
||
53 | cforgekey.SetValue("", "URL:cforge Protocol"); |
||
54 | cforgekey.SetValue("URL Protocol", ""); |
||
55 | |||
56 | RegistryKey cforgeshell = cforgekey.CreateSubKey("shell"); |
||
57 | RegistryKey shellopen = cforgeshell.CreateSubKey("open"); |
||
58 | RegistryKey opencommand = shellopen.CreateSubKey("command"); |
||
59 | opencommand.SetValue("", "\"" + fullpath + "\" \"%1\""); |
||
60 | |||
61 | Console.WriteLine("[INFO] Installed URL Handler for cforge tool. \r\n\tPath is: " + fullpath); |
||
62 | } |
||
63 | catch (Exception ex) |
||
64 | { |
||
65 | Console.WriteLine("Exception while adding the registry key. Perhaps you are not admin?"); |
||
66 | Console.WriteLine(ex.ToString()); |
||
67 | } |
||
68 | } |
||
69 | |||
70 | #endregion |
||
71 | |||
72 | |||
73 | |||
74 | |||
75 | /// <summary> |
||
76 | /// Function to retrieve the location of the currenty assembly (cforge.exe). |
||
77 | /// This should be located in the CODESYS installation subfolder "CFORGE" |
||
78 | /// </summary> |
||
79 | /// <returns>full path to cforge.exe</returns> |
||
80 | private static String GetCFORGEAssemblyPath() |
||
81 | { |
||
82 | String path = System.Reflection.Assembly.GetExecutingAssembly().Location; |
||
83 | return path; |
||
84 | } |
||
85 | |||
86 | private static bool IsCODESYSPathInstallation() |
||
87 | { |
||
88 | String path = GetCFORGEAssemblyPath(); |
||
89 | if (path.Contains("bin") && (path.Contains("Debug") || path.Contains("Release"))) |
||
90 | return false; |
||
91 | |||
92 | return true; |
||
93 | } |
||
94 | |||
95 | /// <summary> |
||
96 | /// Function to retrieve the CODESYS AP_ROOT (this is where "Common" etc. folders are) |
||
97 | /// </summary> |
||
98 | /// <returns>full path to AP ROOT</returns> |
||
99 | private static String GetCODESYSRoot() |
||
100 | { |
||
101 | if (IsCODESYSPathInstallation()) |
||
102 | { |
||
103 | // twice up from cforge.exe (if installed in CODESYS) |
||
104 | String path = GetCFORGEAssemblyPath(); |
||
105 | path = Directory.GetParent(path).FullName; |
||
106 | return Directory.GetParent(path).FullName; |
||
107 | } |
||
108 | // for now return a normal installation path for CODESYS |
||
109 | return @"C:\Program Files (x86)\3S CODESYS\CODESYS\"; |
||
110 | } |
||
111 | |||
112 | /// <summary> |
||
113 | /// Function to retrieve the CFORGE Script path (this is where the IronPython scripts should reside) |
||
114 | /// </summary> |
||
115 | /// <returns>full path to CFORGE Scripts</returns> |
||
116 | private static String GetCFORGEScriptPath() |
||
117 | { |
||
118 | if (IsCODESYSPathInstallation()) |
||
119 | { |
||
120 | // <AP_ROOT>\CFORGE\Scripts |
||
121 | String path = GetCODESYSRoot(); |
||
122 | return Path.Combine(path, "CFORGE", "Scripts"); |
||
123 | } |
||
124 | String localscriptpath = System.AppDomain.CurrentDomain.BaseDirectory; |
||
125 | localscriptpath = Directory.GetParent(localscriptpath).FullName; |
||
126 | localscriptpath = Directory.GetParent(localscriptpath).FullName; |
||
127 | localscriptpath = Directory.GetParent(localscriptpath).FullName; |
||
128 | return Path.Combine(localscriptpath,"Package", "CFORGE", "Scripts"); |
||
129 | } |
||
130 | |||
131 | private static String GetScriptPluginPath() |
||
132 | { |
||
133 | String path = ""; |
||
134 | bool bIPYFound = false; |
||
135 | bool bMSScrFound = false; |
||
136 | |||
137 | String dir = Path.Combine(GetCODESYSRoot(), "PlugIns", "dc937c18-e9f0-434d-85b7-1b8f499e378a"); |
||
138 | foreach (string item in Directory.EnumerateDirectories(dir)) |
||
139 | { |
||
140 | foreach (string file in Directory.EnumerateFiles(item)) |
||
141 | { |
||
142 | if(Path.GetFileName(file) == strAssemblyNameIPY) |
||
143 | { |
||
144 | bIPYFound = true; |
||
145 | path = item; |
||
146 | } |
||
147 | if (Path.GetFileName(file) == strAssemblyNameMSScripting) |
||
148 | { |
||
149 | bMSScrFound = true; |
||
150 | path = item; |
||
151 | } |
||
152 | } |
||
153 | } |
||
154 | |||
155 | if(!bIPYFound || !bMSScrFound || !Directory.Exists(path)) |
||
156 | { |
||
157 | Console.WriteLine("[ERROR] No scripting plugin in CODESYS found. Do you use original CODESYS at all?"); |
||
158 | return ""; |
||
159 | } |
||
160 | |||
161 | return path; |
||
162 | } |
||
163 | |||
164 | /// <summary> |
||
165 | /// Function to enumerate all IronPython scripts to exend cforge.exe inside Scripts folder |
||
166 | /// </summary> |
||
167 | /// <returns>List of IPY scripts</returns> |
||
168 | public static List<String> GetAllScripts() |
||
169 | { |
||
170 | List<string> liScripts = new List<string>(); |
||
171 | |||
172 | try |
||
173 | { |
||
174 | String path = GetCFORGEScriptPath(); |
||
175 | foreach (String file in Directory.EnumerateFiles(path)) |
||
176 | { |
||
177 | if (Path.GetExtension(file).ToLowerInvariant() == ".ipy") |
||
178 | { |
||
179 | String shortfilename = Path.GetFileNameWithoutExtension(file); |
||
180 | liScripts.Add(shortfilename); |
||
181 | } |
||
182 | } |
||
183 | } |
||
184 | catch(Exception e) |
||
185 | { |
||
186 | Console.WriteLine("[EXCEPTION] GetAllScripts: " + e.Message); |
||
187 | } |
||
188 | |||
189 | return liScripts; |
||
190 | } |
||
191 | |||
192 | #region Scripting |
||
193 | |||
194 | public static void ExecuteIPyScript(String command, String[] args) |
||
195 | { |
||
196 | String scriptfile = Path.Combine(GetCFORGEScriptPath(), command + ".ipy"); |
||
197 | if (!File.Exists(scriptfile)) |
||
198 | { |
||
199 | Console.WriteLine("[ERROR] Cannot execute script: no such file or directory: " + scriptfile); |
||
200 | return; |
||
201 | } |
||
202 | |||
203 | |||
204 | String strAssemblyDir = GetScriptPluginPath(); |
||
205 | if (String.IsNullOrEmpty(strAssemblyDir)) |
||
206 | return; |
||
207 | |||
208 | try |
||
209 | { |
||
210 | Assembly assemblyIronPython = Assembly.LoadFrom(Path.Combine(strAssemblyDir, strAssemblyNameIPY)); |
||
211 | Assembly assemblyMicrosoftScripting = Assembly.LoadFrom(Path.Combine(strAssemblyDir, strAssemblyNameMSScripting)); |
||
212 | |||
213 | Type tPython = assemblyIronPython.GetExportedTypes().Where(t => t.FullName == "IronPython.Hosting.Python").First(); |
||
214 | Type tScriptEngine = assemblyMicrosoftScripting.GetExportedTypes().Where(t => t.FullName == "Microsoft.Scripting.Hosting.ScriptEngine").First(); |
||
215 | Type tScriptScope = assemblyMicrosoftScripting.GetExportedTypes().Where(t => t.FullName == "Microsoft.Scripting.Hosting.ScriptScope").First(); |
||
216 | Type tScriptRuntime = assemblyMicrosoftScripting.GetExportedTypes().Where(t => t.FullName == "Microsoft.Scripting.Hosting.ScriptRuntime").First(); |
||
217 | |||
218 | MethodInfo miCreateRuntime = tPython.GetMethod("CreateRuntime", new Type[] { }); |
||
219 | |||
220 | MethodInfo miCreateEngine = tPython.GetMethod("CreateEngine", new Type[] { }); |
||
221 | MethodInfo miExecuteFile = tScriptEngine.GetMethod("ExecuteFile", new Type[] { typeof(String) }); |
||
222 | MethodInfo miGetSysModule = tPython.GetMethod("GetSysModule", new Type[] { tScriptRuntime}); |
||
223 | MethodInfo miSetVariable = tScriptScope.GetMethod("SetVariable", new Type[] { typeof(String), typeof(String[]) }); |
||
224 | |||
225 | var runtime = miCreateRuntime.Invoke(null, null); |
||
226 | var sysmodule = miGetSysModule.Invoke(runtime, null); |
||
227 | |||
228 | IDictionary<string, object> arguments = new Dictionary<string, object>(); |
||
229 | arguments["Arguments"] = new [] { args }; |
||
230 | //var IronPythonEngine = miCreateEngine.Invoke(null, new object[] { arguments }); |
||
231 | //var IronPythonEngine = miCreateEngine.Invoke(null, null); |
||
232 | |||
233 | //miExecuteFile.Invoke(IronPythonEngine, new object[] { scriptfile }); |
||
234 | |||
235 | //var ScriptScore = miGetSysModule.Invoke(IronPythonEngine, null); |
||
236 | |||
237 | //miSetVariable.Invoke(ScriptScore, new object[] {"argv", args }); |
||
238 | //miExecuteFile.Invoke(IronPythonEngine, new object[] { scriptfile }); |
||
239 | |||
240 | |||
241 | } |
||
242 | catch (Exception ex) |
||
243 | { |
||
244 | Console.WriteLine("[EXCEPTION] Execute IPY Script: " + command + ".ipy! " + ex.Message); |
||
245 | } |
||
246 | } |
||
247 | |||
248 | #endregion |
||
249 | } |
||
250 | } |