Esempio n. 1
0
        /// <summary> 将程序集文件加载到内存,并且提取出其中的 CAD 外部命令 </summary>
        /// <param name="assemblyPath"></param>
        /// <returns></returns>
        public static List <ICADExCommand> RetriveExternalCommandsFromAssembly(string assemblyPath)
        {
            var      assemLoader = new eZAssemblyLoader(assemblyPath);
            Assembly asm         = null;

            Type[] classes = null;
            try
            {
                assemLoader.HookAssemblyResolve();
                {
                    // 方法一:zengfy 设计,在测试中通过。其关键在于不能直接将源程序集加载到进程中,
                    // 因为如果这样的话,在Visual Studio中修改此程序集的代码后不能重新编译,或者即使可以重新编译,在AddinManager加载的过程中也不会将其刷新。
                    byte[] buff = File.ReadAllBytes(assemblyPath);
                    //先将插件拷贝到内存缓冲。一般情况下,当加载的文件大小大于2^32 byte (即4.2 GB),就会出现OutOfMemoryException,在实际测试中的极限值为630MB。
                    asm = Assembly.Load(buff); //不能直接通过LoadFrom或者LoadFile,而必须先将插件拷贝到内存,然后再从内存中Load

                    // 方法二:通过LoadFile加载,在测试中发现如果这样做,则在 eZcad_AddinManager 调试过程中,如果在Visual Studio中修改了代码,则不能重新进行编译。
                    // asm = Assembly.LoadFile(assemblyPath);  // LoadFile方法不会加载此程序集引用的其他程序集,也就是不会加载程序的依赖项。
                }

                // 加载程序集中的类型,以寻找对应的 Execute 方法。

                classes = asm.GetTypes();
            }
            catch (ReflectionTypeLoadException ex)
            {
                // 有可能会出现找不到文件或程序集 eZstd 或其依赖项的报错。
                classes = ex.Types;
            }
            catch (Exception ex)
            {
                // ignored
                // MessageBox.Show(ex.Message, "加载程序集时出错了", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            finally
            {
                assemLoader.UnhookAssemblyResolve();
            }
            DocumentModifier.LineFeedInCommandLine();
            return(GetExternalCommandClass(asm, classes));
        }
Esempio n. 2
0
        private static ExternalCommandResult Execute(object exCommandIns, SelectionSet impliedSelection, ref string errorMessage, ref IList<ObjectId> errorSet)
        {
            DocumentModifier.LineFeedInCommandLine();

            ExternalCommandResult res = ExternalCommandResult.Failed;
            try
            {
                var mtd = ExCommandFinder.FindExCommandMethod(exCommandIns.GetType());
                if (mtd != null)
                {
                    // 先将焦点交给 AutoCAD 主界面
                    Application.MainWindow.Focus();
                    // ---------------------------- 执行命令 ----------------------------------------
                    object[] paras = new object[] { impliedSelection, errorMessage, errorSet };
                    res = (ExternalCommandResult)mtd.Invoke(exCommandIns, paras);
                    // 将 ref 参数的值提取出来
                    errorMessage = paras[1] as string;
                    errorSet = paras[2] as IList<ObjectId>;
                }

                // 执行操作
                // 如果在执行 Execute()方法时发现某个程序集不存在,则通过AssemblyResolve 事件手动进行加载
                // 所以,所有引用的 zengfy 自定义程序集,都必须在  Execute() 方法中调用至少一次,以解决在Form.Show()时,出现不能找到或加载前面缺失的程序集B的问题。

                // 如果不想通过 AssemblyResolve 来加载缺失的程序集的话,可以在 AddinManager 中自行设计代码,手动在 Execute() 方法之前将要引用的程序集从临时文件夹中通过 Assembly.LoadFile() 进行加载即可。
                // var exCommand = exCommandIns as ICADExCommand;
                // res = exCommand.Execute(impliedSelection, errorMessage: ref errorMessage, elementSet: ref errorSet);
            }
            catch (Exception ex)
            {
                if (string.IsNullOrEmpty(errorMessage))
                {
                    errorMessage = GetDebugMessage(ex); // ex.Message;
                }
                else
                {
                    errorMessage = errorMessage + "\n\r--------------------------------------------\n\r"
                                   + GetDebugMessage(ex); // ex.Message;
                }
                res = ExternalCommandResult.Failed;
            }

            // 对命令的结果进行处理
            switch (res)
            {
                case ExternalCommandResult.Failed:
                    {
                        // 选择出错的单元格
                        if (errorSet != null)
                        {
                            StringBuilder errorIds = new StringBuilder();
                            foreach (var id in errorSet)
                            {
                                errorIds.AppendLine(id.ObjectClass.Name);
                            }
                            errorMessage += "\r\n出错对象:\r\n " + errorIds.ToString();
                        }
                        // MessageBox.Show(errorMessage, @"外部命令执行出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        break;
                    }
                case ExternalCommandResult.Cancelled:
                    {
                        // 由于没有在CAD中没有事务或者回滚,所以直接结束就可以了。
                        break;
                    }
                case ExternalCommandResult.Succeeded:
                    {
                        break;
                    }
            }
            return res;
        }