Пример #1
0
 static Type GetRhinoDotNetType(string name)
 {
     System.Reflection.Assembly rhino_dot_net = HostUtils.GetRhinoDotNetAssembly();
     if (null == rhino_dot_net)
     {
         return(null);
     }
     return(rhino_dot_net.GetType(name));
 }
Пример #2
0
        /// <summary>
        /// For derived class implementers.
        /// <para>This method is called with argument true when class user calls Dispose(), while with argument false when
        /// the Garbage Collector invokes the finalizer, or Finalize() method.</para>
        /// <para>You must reclaim all used unmanaged resources in both cases, and can use this chance to call Dispose on disposable fields if the argument is true.</para>
        /// <para>Also, you must call the base virtual method within your overriding method.</para>
        /// </summary>
        /// <param name="disposing">true if the call comes from the Dispose() method; false if it comes from the Garbage Collector finalizer.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (IntPtr.Zero == m_ptr || m__parent is ConstCastHolder)
            {
                return;
            }

            Geometry.MeshHolder mh = m__parent as Geometry.MeshHolder;
            if (mh != null)
            {
                mh.ReleaseMesh();
            }

            if (m_bDestructOnDispose)
            {
                bool in_finalizer = !disposing;
                if (in_finalizer)
                {
                    // 11 Feb 2013 (S. Baer) RH-16157
                    // When running in the finalizer, the destructor is being called on the GC
                    // thread which results in nearly impossible to track down exceptions.
                    // Mask the exception in this case and post information to our logging system
                    // about the exception so we can better analyze and try to figure out what
                    // is going on
                    try
                    {
                        UnsafeNativeMethods.ON_Object_Delete(m_ptr);
                    }
                    catch (Exception ex)
                    {
                        HostUtils.ExceptionReport(ex);
                    }
                }
                else
                {
                    // See above. In this case we are running on the main thread of execution
                    // and throwing an exception is a good thing so we can analyze and quickly
                    // fix whatever is going wrong
                    UnsafeNativeMethods.ON_Object_Delete(m_ptr);
                }
                if (m_unmanaged_memory > 0)
                {
                    GC.RemoveMemoryPressure(m_unmanaged_memory);
                }
            }
            m_ptr      = IntPtr.Zero;
            m_disposed = true;
        }
Пример #3
0
        private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            // Handle the RhinoCommon case.
            if (args.Name.StartsWith("RhinoCommon", StringComparison.OrdinalIgnoreCase) &&
                !args.Name.StartsWith("RhinoCommon.resources", StringComparison.OrdinalIgnoreCase))
            {
                return(Assembly.GetExecutingAssembly());
            }

            // Get the significant name of the assembly we're looking for.
            string searchname = args.Name;
            // Do not attempt to handle resource searching.
            int index = searchname.IndexOf(".resources", StringComparison.Ordinal);

            if (index > 0)
            {
                return(null);
            }

            // The resolver is commonly called multiple times with the same search name.
            // Keep the results around so we don't keep doing the same job over and over
            if (m_match_dictionary != null && m_match_dictionary.ContainsKey(args.Name))
            {
                return(m_match_dictionary[args.Name]);
            }

            bool probably_python = false;

            index = searchname.IndexOf(',');
            if (index > 0)
            {
                searchname = searchname.Substring(0, index);
            }
            else
            {
                // Python scripts typically just look for very short names, like "MyFunctions.dll"
                if (searchname.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
                {
                    searchname = searchname.Substring(0, searchname.Length - ".dll".Length);
                }
                probably_python = true;
            }

            // See if the assembly is already loaded.
            var loaded_assemblies = AppDomain.CurrentDomain.GetAssemblies();

            foreach (var loaded_assembly in loaded_assemblies)
            {
                if (loaded_assembly.FullName.StartsWith(searchname + ",", StringComparison.OrdinalIgnoreCase))
                {
                    return(loaded_assembly);
                }
            }



            List <string> potential_files = new List <string>();

            // Collect all potential files in the plug-in directories.
#if RHINO_SDK
            string[] plugin_folders = HostUtils.GetAssemblySearchPaths();
            if (plugin_folders != null)
            {
                foreach (string plugin_folder in plugin_folders)
                {
                    string[] files = Directory.GetFiles(plugin_folder, @"*.dll", SearchOption.TopDirectoryOnly); //Why TopDirectoryOnly?
                    if (files != null)
                    {
                        potential_files.AddRange(files);
                    }

                    files = Directory.GetFiles(plugin_folder, @"*.rhp", SearchOption.TopDirectoryOnly); //Why TopDirectoryOnly?
                    if (files != null)
                    {
                        potential_files.AddRange(files);
                    }
                }
            }
#endif
            if (probably_python)
            {
                string current_dir = Directory.GetCurrentDirectory();
                if (!string.IsNullOrEmpty(current_dir))
                {
                    string[] files = Directory.GetFiles(current_dir, @"*.dll", SearchOption.TopDirectoryOnly); //Why TopDirectoryOnly?
                    if (files != null)
                    {
                        potential_files.AddRange(files);
                    }
                }
            }

            // Collect all potential files in the custom directories.
            if (m_custom_folders != null)
            {
                foreach (string custom_folder in m_custom_folders)
                {
                    string[] files = Directory.GetFiles(custom_folder, @"*.dll", SearchOption.TopDirectoryOnly); //Why TopDirectoryOnly?
                    if (files != null)
                    {
                        potential_files.AddRange(files);
                    }

                    files = Directory.GetFiles(custom_folder, @"*.rhp", SearchOption.TopDirectoryOnly); //Why TopDirectoryOnly?
                    if (files != null)
                    {
                        potential_files.AddRange(files);
                    }
                }
            }

            // Collect all potential files in the custom file list.
            if (m_custom_files != null)
            {
                potential_files.AddRange(m_custom_files);
            }

            // Remove the already loaded assemblies from the "potential" list. We've
            // already tested these.
            for (int i = 0; i < loaded_assemblies.Length; i++)
            {
                if (loaded_assemblies[i].GlobalAssemblyCache)
                {
                    continue;
                }
                if (loaded_assemblies[i].IsDynamic)
                {
                    continue; //dynamic assemblies won't have a Location anyways.
                }
                try
                {
                    // 6 Feb 2017 S. Baer (RH-35794)
                    // Remove loaded assemblies using filename as comparison. On systems
                    // where the same assembly is located in multiple search path locations
                    // we will start throwing exceptions when attempting to load those
                    // assemblies (even if they are not the ones we are looking for).
                    string filename = Path.GetFileName(loaded_assemblies[i].Location);
                    for (int j = potential_files.Count - 1; j >= 0; j--)
                    {
                        string potential_filename = Path.GetFileName(potential_files[j]);
                        if (string.Compare(filename, potential_filename, StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            potential_files.RemoveAt(j);
                        }
                    }
                }
                catch { }
            }

#if RHINO_SDK
            // 7 Feb 2017 S. Baer (RH-30818)
            // Remove native DLLs from the list of potentials
            for (int i = potential_files.Count - 1; i >= 0; i--)
            {
                if (!HostUtils.IsManagedDll(potential_files[i]))
                {
                    potential_files.RemoveAt(i);
                }
            }
#endif

            // Sort all potential files based on fuzzy name matches.
            FuzzyComparer fuzzy = new FuzzyComparer(searchname);
            potential_files.Sort(fuzzy);

            // 23 August 2012 S. Baer
            // Make sure that at least part of the searchname matches part of the filename
            // Just use the first 5 characters as a required pattern in the filename
            const int length_match        = 5;
            string    must_be_in_filename = searchname.Substring(0, searchname.Length > length_match ? length_match : searchname.Length);

            Assembly asm = null;
            foreach (string file in potential_files)
            {
                if (file.IndexOf(must_be_in_filename, StringComparison.InvariantCultureIgnoreCase) == -1)
                {
                    continue;
                }
                asm = TryLoadAssembly(file, searchname);
                if (asm != null)
                {
                    break;
                }
            }

            if (m_match_dictionary == null)
            {
                m_match_dictionary = new Dictionary <string, Assembly>();
            }
            if (!m_match_dictionary.ContainsKey(args.Name))
            {
                m_match_dictionary.Add(args.Name, asm);
            }

            return(asm);
        }
Пример #4
0
            public int Compare(string x, string y)
            {
                bool xExists = File.Exists(x);
                bool yExists = File.Exists(y);

                if (!xExists && !yExists)
                {
                    return(0);
                }

                if (!xExists)
                {
                    return(+1);
                }
                if (!yExists)
                {
                    return(-1);
                }

                // This can be made a lot smarter with substring searches.
                string xFileName = Path.GetFileName(x);
                string yFileName = Path.GetFileName(y);

                int xIndex = xFileName == null ? -1 : xFileName.IndexOf(m_search, StringComparison.OrdinalIgnoreCase);
                int yIndex = yFileName == null ? -1 : yFileName.IndexOf(m_search, StringComparison.OrdinalIgnoreCase);

                // 4 April 2012 - S. Baer
                // If the file names are the same, the highest version number or most
                // recent file date is sorted to the top.  Plug-ins like PanelingTools
                // have historically moved around on where they are installed on a user's
                // computer, so we may end up with duplicates
                if (xIndex >= 0 && yIndex >= 0 && string.Compare(xFileName, yFileName, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    try
                    {
                        // 25 August 2015 - David Rutten:
                        // Error reports:
                        // http://mcneel.myjetbrains.com/youtrack/issue/RH-30818
                        // https://app.raygun.io/dashboard/6bsfxg/errors/561473847
                        // seem to originate on one of the ReflectionOnlyLoadFrom calls below,
                        // but they're already in a try_catch block. I'm really not sure how to
                        // determine whether an assembly will load prior to loading it.

                        // 3 Oct 2017 - S. Baer (RH-35794)
                        // Reflection loading two assemblies into the same appdomain is asking for exceptions
                        // Luckily, there is another way... Use AssemblyName.GetAssemblyName

                        var     xAssemblyName = AssemblyName.GetAssemblyName(x);
                        var     yAssemblyName = AssemblyName.GetAssemblyName(y);
                        Version xVersion      = xAssemblyName.Version;
                        Version yVersion      = yAssemblyName.Version;
                        int     rc            = xVersion.CompareTo(yVersion);
                        if (rc != 0)
                        {
                            return(rc);
                        }

                        // Same version. Try using the file date
                        FileInfo xInfo = new FileInfo(x);
                        FileInfo yInfo = new FileInfo(y);
                        rc = xInfo.LastAccessTimeUtc.CompareTo(yInfo.LastAccessTimeUtc);
                        if (rc != 0)
                        {
                            return(rc);
                        }
                    }
                    catch (Exception ex)
                    {
                        HostUtils.ExceptionReport("duplicate assembly resolve", ex);
                    }
                }

                if (xIndex < 0)
                {
                    xIndex = int.MaxValue;
                }
                if (yIndex < 0)
                {
                    yIndex = int.MaxValue;
                }
                return(xIndex.CompareTo(yIndex));
            }
Пример #5
0
        public static int LoadPlugIn(string path)
        {
            HostUtils.SendDebugToCommandLine = true;
            HostUtils.DebugString("[MonoHost::LoadPlugIn] Start");
            if (!m_bUsingMono)
            {
                m_bUsingMono = true;
                // Don't turn visual styles on yet, they seem pretty flakey as of
                // Mono 2.4.2
                //System.Windows.Forms.Application.EnableVisualStyles();

                InitializeExceptionHandling();
                HostUtils.InitializeRhinoCommon();

                HostUtils.DebugString("Attempt to initialize MonoMac");
                Type t = typeof(System.Windows.Forms.Application);
                if (t != null)
                {
                    System.Reflection.MethodInfo mi = t.GetMethod("MonoMacInit", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
                    if (mi != null)
                    {
                        HostUtils.DebugString("Got methodinfo for MonoMacInit");
                        mi.Invoke(null, null);
                    }
                }
            }

            // 7 Apr 2013, S. Baer
            // Mac plug-ins can now be located inside of OSX plug-in bundles.
            // The native plug-in manager may just pass us the bundle path
            // See if the path refers to a bundle. If that is the case,
            // look inside the bundle to find the actual assembly
            var temp_path = System.IO.Path.Combine(path, "Contents");

            temp_path = System.IO.Path.Combine(temp_path, "Mono");
            if (System.IO.Directory.Exists(temp_path))
            {
                var files = System.IO.Directory.GetFiles(temp_path, "*.rhp");
                if (files != null && files.Length > 0)
                {
                    path = files[0];
                }
            }

            HostUtils.DebugString("path = " + path);

            // Reflection Load assembly first in order to check versioning
            // and make sure the plug-in hasn't already been loaded
            System.Reflection.Assembly plugin_assembly;
            try
            {
                plugin_assembly = System.Reflection.Assembly.ReflectionOnlyLoadFrom(path);
            }
            catch (Exception) { plugin_assembly = null; }
            HostUtils.DebugString("ReflectionOnlyLoadFrom succeeded");

            if (null == plugin_assembly)
            {
                return((int)MonoLoadResult.error_not_dotnet);
            }

            //make sure this assembly has not alread been loaded
            for (int i = 0; i < PlugIn.m_plugins.Count; i++)
            {
                System.Reflection.Assembly loadedAssembly = PlugIn.m_plugins[i].Assembly;
                if (string.Compare(loadedAssembly.FullName, plugin_assembly.FullName, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    return((int)MonoLoadResult.error_already_loaded);
                }
            }

            // Check version of RhinoCommon that this plug-in uses
            // Don't allow plug-ins built against earlier versions of RhinoCommon to load
            bool passesVersionCheck = false;

            try
            {
                System.Reflection.AssemblyName[] referenced_assemblies = plugin_assembly.GetReferencedAssemblies();
                for (int i = 0; i < referenced_assemblies.Length; i++)
                {
                    if (referenced_assemblies[i].Name.Equals("RhinoCommon", StringComparison.OrdinalIgnoreCase))
                    {
                        Version referenced_version = referenced_assemblies[i].Version;
                        Version this_version       = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
                        HostUtils.DebugString("Installed RhinoCommon version = {0}", this_version);
                        HostUtils.DebugString("Plug-In built against = {0}", referenced_version);
                        // major and minor MUST match
                        if (referenced_version.Major == this_version.Major && referenced_version.Minor == this_version.Minor)
                        {
                            // At this point the SDK is changing too rapidly to allow for "safe" updates
                            // build of this_version must be == build of referenced version
                            // revision of this_version must be >= build of referenced version
                            if (this_version.Build == referenced_version.Build)
                            {
                                if (this_version.Revision >= referenced_version.Revision)
                                {
                                    passesVersionCheck = true;
                                }
                            }
                        }
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                HostUtils.DebugString("Exception while checking versions");
                HostUtils.DebugString(ex.Message);
            }
            if (!passesVersionCheck)
            {
                return((int)MonoLoadResult.error_incompatible_version);
            }


            // TODO: Check version of RhinoCommon that this plug-in uses for versioning

            // At this point, we have determined that this is a RhinoCommon plug-in
            // We've done all the checking that we can do without actually loading
            // the DLL ( and resolving links)
            try
            {
                plugin_assembly = System.Reflection.Assembly.LoadFrom(path);
            }
            catch (Exception)
            {
                plugin_assembly = null;
            }
            if (null == plugin_assembly)
            {
                return((int)MonoLoadResult.error_unable_to_load);
            }
            HostUtils.DebugString("Assembly loaded for real... GetExportedTypes");

            Type[] internal_types = null;
            try
            {
                internal_types = plugin_assembly.GetExportedTypes();
            }
            catch (System.Reflection.ReflectionTypeLoadException ex)
            {
                HostUtils.DebugString("Caught reflection exception");
                Type[] loaded_types = ex.Types;
                if (loaded_types != null)
                {
                    HostUtils.DebugString("Got {0} loaded types", loaded_types.Length);
                    for (int i = 0; i < loaded_types.Length; i++)
                    {
                        Type t = loaded_types[i];
                        if (t != null)
                        {
                            HostUtils.DebugString("{0} - {1}", i, t);
                        }
                    }
                    HostUtils.DebugString(loaded_types.ToString());
                }
                Exception[] e = ex.LoaderExceptions;
                if (e != null)
                {
                    HostUtils.DebugString("Got some loader exceptions");
                    for (int i = 0; i < e.Length; i++)
                    {
                        HostUtils.DebugString(ex.ToString());
                        internal_types = null;
                    }
                }
            }
            catch (Exception ex)
            {
                HostUtils.DebugString("Caught generic exception");
                HostUtils.DebugString(ex.ToString());
                internal_types = null;
                //        HostUtils.ExceptionReport(ex);
            }

            if (null == internal_types)
            {
                return((int)MonoLoadResult.error_unable_to_load);
            }

            HostUtils.DebugString("{0} Exported Types", internal_types.Length);

            // walk through list of exported types and find a single class
            // that derives from PlugIn
            Type plugin_type = typeof(PlugIn);
            int  type_index  = -1;

            try
            {
                for (int i = 0; i < internal_types.Length; i++)
                {
                    if (plugin_type.IsAssignableFrom(internal_types[i]))
                    {
                        if (type_index >= 0)
                        {
                            return((int)MonoLoadResult.error_create_plugin);
                        }
                        type_index = i;
                    }
                }
            }
            catch (Exception ex)
            {
                HostUtils.DebugString("Exception occured while trying to find type that is derived from PlugIn");
                HostUtils.ExceptionReport(ex);
                type_index = -1;
            }
            if (type_index < 0)
            {
                return((int)MonoLoadResult.error_create_plugin);
            }
            plugin_type = internal_types[type_index];
            HostUtils.DebugString("Found type derived from PlugIn  (" + plugin_type.ToString() + ")");

            object[] name = plugin_assembly.GetCustomAttributes(typeof(System.Reflection.AssemblyTitleAttribute), false);
            string   plugin_name;

            if (name != null && name.Length > 0)
            {
                plugin_name = ((System.Reflection.AssemblyTitleAttribute)name[0]).Title;
            }
            else
            {
                plugin_name = plugin_assembly.GetName().Name;
            }

            string plugin_version = plugin_assembly.GetName().Version.ToString();

            HostUtils.DebugString("  name = {0}; version = {1}", plugin_name, plugin_version);

            object[] descriptionAtts = plugin_assembly.GetCustomAttributes(typeof(PlugInDescriptionAttribute), false);
            if (descriptionAtts != null)
            {
                const int idxAddress      = 0;
                const int idxCountry      = 1;
                const int idxEmail        = 2;
                const int idxFax          = 3;
                const int idxOrganization = 4;
                const int idxPhone        = 5;
                const int idxUpdateUrl    = 6;
                const int idxWebsite      = 7;

                for (int i = 0; i < descriptionAtts.Length; i++)
                {
                    PlugInDescriptionAttribute description = (PlugInDescriptionAttribute)descriptionAtts[i];
                    switch (description.DescriptionType)
                    {
                    case DescriptionType.Address:
                        UnsafeNativeMethods.RhMono_SetPlugInLoadString(idxAddress, description.Value);
                        break;

                    case DescriptionType.Country:
                        UnsafeNativeMethods.RhMono_SetPlugInLoadString(idxCountry, description.Value);
                        break;

                    case DescriptionType.Email:
                        UnsafeNativeMethods.RhMono_SetPlugInLoadString(idxEmail, description.Value);
                        break;

                    case DescriptionType.Fax:
                        UnsafeNativeMethods.RhMono_SetPlugInLoadString(idxFax, description.Value);
                        break;

                    case DescriptionType.Organization:
                        UnsafeNativeMethods.RhMono_SetPlugInLoadString(idxOrganization, description.Value);
                        break;

                    case DescriptionType.Phone:
                        UnsafeNativeMethods.RhMono_SetPlugInLoadString(idxPhone, description.Value);
                        break;

                    case DescriptionType.UpdateUrl:
                        UnsafeNativeMethods.RhMono_SetPlugInLoadString(idxUpdateUrl, description.Value);
                        break;

                    case DescriptionType.WebSite:
                        UnsafeNativeMethods.RhMono_SetPlugInLoadString(idxWebsite, description.Value);
                        break;
                    }
                    HostUtils.DebugString("  {0} - {1}", description.DescriptionType, description.Value);
                }
            }

            PlugIn plugin = PlugIn.Create(plugin_type, plugin_name, plugin_version);

            if (plugin == null)
            {
                return((int)MonoLoadResult.error_create_plugin);
            }

            // We've created a plug-in so we're pretty committed at this point
            PlugIn.m_plugins.Add(plugin);

            // create all commands in the plug-in
            HostUtils.CreateCommands(plugin);
            HostUtils.DebugString("Created {0} commands", plugin.GetCommands().Length);
            HostUtils.DebugString("[MonoHost::LoadPlugIn] - DONE");

            return((int)MonoLoadResult.success);
        }