Diff of /trunk/cforge/cforge/Helper.cs [000000] .. [r3]  Maximize  Restore

Switch to unified view

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
}