Beispiel #1
0
 private void SetupMainDirListener()
 {
     if (Directory.Exists(GH_ComponentServer.GHA_AppDataDirectory))
     {
         var watcher = GH_FileWatcher.CreateDirectoryWatcher(GH_ComponentServer.GHA_AppDataDirectory, "*.ghpy", GH_FileWatcherEvents.Created,
                                                             (sender, filePath, change) =>
         {
             try
             {
                 if (change == WatcherChangeTypes.Created)
                 {
                     if (LoadOneAddon(_gha_environment, filePath))
                     {
                         GH_ComponentServer.UpdateRibbonUI();
                     }
                 }
             }
             catch (Exception ex)
             {
                 Global_Proc.ASSERT(Guid.Empty, "GhPython last exception boundary", ex);
             }
         });
         watcher.Active = true;
     }
 }
Beispiel #2
0
 public override GH_LoadingInstruction PriorityLoad()
 {
     try
     {
         _gha_environment = CreateEnvironment();
         LoadExternalPythonAssemblies();
         SetupMainDirListener();
     }
     catch (Exception ex)
     {
         Global_Proc.ASSERT(Guid.Empty, "GhPython last exception boundary", ex);
     }
     return(GH_LoadingInstruction.Proceed);
 }
Beispiel #3
0
        private static bool LoadOneAddon(PythonEnvironment p, string path)
        {
            var engine  = p.Engine as dynamic;
            var runtime = engine.Runtime;
            var ops     = engine.Operations;

            if (ExternalUnsafe.HasZoneIdetifier(path))
            {
                if (MessageBox.Show("A FILE IS BLOCKED: \n\n" +
                                    path +
                                    "\n\nBefore being able to use it, this file should be unblocked.\n" +
                                    "Do you want attempt to unblock it now?", "GhPython Assembly is blocked",
                                    MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button2,
                                    MessageBoxOptions.DefaultDesktopOnly) == DialogResult.Yes)
                {
                    if (!ExternalUnsafe.Unblock(path))
                    {
                        Global_Proc.ASSERT(Guid.Empty, "You need to unblock \"" + path + "\" manually."); return(false);
                    }
                }
            }

            AssemblyName assName;

            try
            {
                assName = AssemblyName.GetAssemblyName(path);
            }
            catch (SecurityException ex)
            {
                Global_Proc.ASSERT(Guid.Empty, "You have not enough rights to load \"" + path + "\".", ex); return(false);
            }
            catch (BadImageFormatException ex)
            {
                Global_Proc.ASSERT(Guid.Empty, "The assembly \"" + path + "\" has a bad format.", ex); return(false);
            }
            catch (FileLoadException ex)
            {
                Global_Proc.ASSERT(Guid.Empty, "The assembly \"" + path + "\" is found but cannot be loaded.", ex); return(false);
            }

            var appDomain = AppDomain.CreateDomain("Temp");

            try
            {
                var farAssembly = appDomain.CreateInstanceFrom(path, "DLRCachedCode");
            }
            catch (FileLoadException ex)
            {
                int error = Marshal.GetHRForException(ex);
                if (error == -0x40131515)
                {
                    Global_Proc.ASSERT(Guid.Empty, "The file \"" + path + "\" is blocked.", ex); return(false);
                }
                Global_Proc.ASSERT(Guid.Empty, "The assembly at \"" + path + "\" cannot be loaded.", ex); return(false);
            }
            catch (BadImageFormatException ex)
            {
                Global_Proc.ASSERT(Guid.Empty, "This assembly \"" + path + "\" has a bad inner format.", ex); return(false);
            }
            catch (TypeLoadException ex)
            {
                Global_Proc.ASSERT(Guid.Empty, "\"" + path + "\" is not a valid Python assembly. Please remove it.", ex); return(false);
            }
            catch (MissingMethodException ex)
            {
                Global_Proc.ASSERT(Guid.Empty, "This assembly \"" + path + "\" is ruined.", ex); return(false);
            }
            finally
            {
                if (appDomain != null)
                {
                    AppDomain.Unload(appDomain);
                }
            }

            Assembly assembly   = Assembly.LoadFile(path);
            var      cachedCode = assembly.GetType("DLRCachedCode", false, false);

            if (cachedCode == null)
            {
                return(false);              //should be already ruled out
            }
            dynamic info = cachedCode.InvokeMember("GetScriptCodeInfo",
                                                   BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
                                                   null, null, new object[0]);

            string[] modules = info.GetValue(2)[0];

            runtime.LoadAssembly(assembly);

            bool toReturn = false;

            foreach (var module in modules)
            {
                var statement = "import " + module;
                p.Script.ExecuteScript(statement);

                dynamic ns = p.Script.GetVariable(module);

                var dict = ns.Get__dict__();
                var vars = dict.Keys;

                foreach (var v in vars)
                {
                    var text = v as string;

                    if (text == null)
                    {
                        continue;
                    }
                    object o = dict[text];

                    if (o == null)
                    {
                        continue;
                    }
                    Type type = o.GetType();

                    if (type.FullName != "IronPython.Runtime.Types.PythonType")
                    {
                        continue;
                    }

                    var basesEnum = (IEnumerable)type.InvokeMember(
                        "get_BaseTypes",
                        BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Instance, null, o, null);
                    if (basesEnum == null)
                    {
                        continue;
                    }

                    foreach (var baseObj in basesEnum)
                    {
                        Type finalSystemType = (Type)baseObj.GetType().InvokeMember(
                            "get_FinalSystemType",
                            BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Instance, null, baseObj, null);
                        if (finalSystemType == null)
                        {
                            continue;
                        }

                        if (typeof(IGH_Component).IsAssignableFrom(finalSystemType))
                        {
                            var instance = Instantiate(ops as object, o);
                            var proxy    = new PythonInstantiatorProxy(instance, o, ops as object, path);

                            toReturn |= Grasshopper.GH_InstanceServer.ComponentServer.AddProxy(proxy);
                        }
                    }
                }

                p.Script.ExecuteScript("del " + module);
            }
            return(toReturn);
        }