一.SolidWorks二次开发之 文档操作和设置

访问项目 Github仓库

查看在线文档

使用Nuget:

PM> Install-Package Du.SolidWorks -Version 0.1.1

本节源码

1.如何打开一个文档

SolidWorks Api 在SldWorks接口中为我们提供了很多OpenDoc方法来打开一个SolidWorks文件或者SolidWorks兼容的文件,如下


i文档打开方法

我使用的为2016版的帮助文档,文档中指示OpenDoc - OpenDoc4 已经是Obsolete状态,表示新版本中已经不在推荐使用,在Api演进过程中已经是过时Api.

使用 OpenDoc6打开文档

1.1打开文档

这里使用c#的扩展方法封装了一个静默打开文档的方法,这里隐藏了OpenDoc6的很多参数,只使用了一个路径字符串和一个用来控制文档是否可见的bool值.

        /// <summary>
        /// 静默模式打开隐藏文件
        /// </summary>
        /// <param name="app"><see cref="ISldWorks"/></param>
        /// <param name="filePath">文件路径</param>
        /// <param name="Hidden">是否隐藏 默认隐藏</param>
        /// <returns></returns>
        public static ModelDoc2 OpenInvisibleDocClient(this SldWorks app, string filePath, bool Hidden = true)
        {
            int Errors = -1, Warning = -1;
            var type = app.FileType(filePath);
            try
            {
                if (Hidden) app.DocumentVisible(false, (int)type);

                ModelDoc2 doc = app.OpenDoc6(filePath, type.SWToInt(), swOpenDocOptions_e.swOpenDocOptions_Silent.SWToInt(),
                    "", ref Errors, ref Warning) as ModelDoc2;

                if (doc == null)
                {
                    throw new Exception(string.Format("errors:{0},warings{1}",
                        Errors.CastObj<swFileLoadError_e>().ToString(),
                        Warning.CastObj<swFileLoadWarning_e>().ToString()));
                }

                return doc;
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                app.DocumentVisible(true, (int)type);
            }
        }

下面根据文件路径判断SolidWorks文档类型的方法

        /// <summary>
        /// 判断文件类型
        /// </summary>
        /// <param name="app"><see cref="ISldWorks"/></param>
        /// <param name="filePath">文件全路径</param>
        /// <returns></returns>
        public static swDocumentTypes_e FileType(this SldWorks app, string filePath)
        {
            string extension = Path.GetExtension(filePath).ToLower();
            swDocumentTypes_e type = swDocumentTypes_e.swDocPART;
            switch (extension)
            {
                case ".sldprt":
                    type = swDocumentTypes_e.swDocPART;
                    break;
                case ".sldasm":
                    type = swDocumentTypes_e.swDocASSEMBLY;
                    break;
                case ".slddrw":
                    type = swDocumentTypes_e.swDocDRAWING;
                    break;
                default:
                    throw new FileFormatException("不支持的文件类型:" + extension);
            }
            return type;
        }

1.2.只读打开

除了静默打开,我们有时候会在后台打开一个文件作为数据库使用,像草图轮廓库,特征数据库等.这时我们可以使用只读模式打开.下面的方法封装了OpenDoc7 来实现一个只读打开.

        /// <summary>
        /// 以不可见模式打开文档  Open a document invisibly. It will not be shown to the user but you will be
        /// able to interact with it through the API as if it is loaded.
        /// </summary>
        /// <param name="sldWorks"></param>
        /// <param name="toolFile"></param>
        /// <param name="visible">是否对用户可见</param>
        /// <param name="type"><see cref="swDocumentTypes_e"/> SolidWorks 文件类型 ,默认为零件</param>
        /// <returns></returns>
        public static ModelDoc2 OpenInvisibleReadOnly(this ISldWorks sldWorks, string toolFile, bool visible = false, swDocumentTypes_e type = swDocumentTypes_e.swDocPART)
        {
            try
            {
                if (!visible)
                    sldWorks.DocumentVisible(false, (int)type);
                var spec = (IDocumentSpecification)sldWorks.GetOpenDocSpec(toolFile);
                if (!visible)
                {
                    spec.Silent = true;
                    spec.ReadOnly = true;
                }
                var doc = sldWorks.OpenDoc7(spec);

                doc.Visible = visible;
                return doc;
            }
            finally
            {
                if (!visible)
                    sldWorks.DocumentVisible
                        (true,
                            (int)
                                type);

            }
        }

1.3.遍历打开的文档

SolidWorks提供了 GetDocuments 方法来获取所有打开的文档,其中包括在内存中打开并对用户不可见的文档,这立封装了一个方法,来遍历所有的文档并执行同一操作.

        /// <summary>
        /// 对内存中所有文档进行操作
        /// </summary>
        /// <param name="swApp"></param>
        /// <param name="action"></param>
        public static void UsingOpenDoc(this SldWorks swApp, Action<IModelDoc2> action)
        {
            var docs = (swApp.GetDocuments() as Object[]).Cast<IModelDoc2>();

            if (docs == null)
            {
                return;
            }

            foreach (var item in docs)
            {
                action?.Invoke(item);
            }
        }

1.4.判断文档是否已经打开

有时在打开前我们需要判断是否已经打开此文档,虽然对已经打开的文档再次打开SolidWorks也会返回到ModelDoc2对象,但有时判断一下还是很有必要.下面的方法便是对上面遍历所有文档的再次封装来实现判断此文档是否已经被打开.实现如下:

        /// <summary>
        /// 判断此文档是否打开
        /// </summary>
        /// <param name="app"></param>
        /// <param name="DocFilePathName"></param>
        /// <returns></returns>
        public static bool HasDocOpened(this SldWorks app, string DocFilePathName)
        {
            bool exist = false;
            app.UsingOpenDoc(d =>
            {
                if (d.GetPathName() == DocFilePathName)
                {
                    exist = true;
                }
            }
            );
            return exist;
        }

1.5.对当前打开的活动文档执行动作

对当前活动文档执行某些操作是相当普遍的做法,下面的方法使用了一个 Action类型的参数来对活动文档快速调用.适合一些对活动文档的快速操作.

        /// <summary>
        /// 对活动文档进行操作
        /// </summary>
        /// <param name="swApp"></param>
        /// <param name="action"></param>
        public static void UsingActiveDoc(this SldWorks swApp, Action<IModelDoc2> action)
        {
            if (swApp.ActiveDoc != null)
            {
                action?.Invoke((IModelDoc2)swApp.ActiveDoc);
            }
        }

2.新建SolidWorks零件或者装配体

2.1.调用默认模板创建零件或者装配体

在对SolidWorks开发中,新建一个零件或者装配体是再经常不过的高频操作,下面的方法封装了一个创建文档的操作,并针对中文环境下SolidWork默认模板文件命名变换的情况做了判断处理.

        /// <summary>
        /// 以默认设置的模板创建文档
        /// </summary>
        /// <param name="sldWorks"><see cref="ISldWorks"/></param>
        /// <param name="type"><see cref="swDocumentTypes_e"/></param>
        /// <returns></returns>
        public static IModelDoc2 CreateDocument(this ISldWorks sldWorks, swDocumentTypes_e type)
        {
            string templatePath = string.Empty;
            switch (type)
            {
                case swDocumentTypes_e.swDocPART:
                    templatePath = sldWorks.GetUserPreferenceStringValue((int)swUserPreferenceStringValue_e.swDefaultTemplatePart);
                    break;
                case swDocumentTypes_e.swDocASSEMBLY:
                    templatePath = sldWorks.GetUserPreferenceStringValue((int)swUserPreferenceStringValue_e.swDefaultTemplateAssembly);
                    break;
                case swDocumentTypes_e.swDocDRAWING:
                    templatePath = sldWorks.GetUserPreferenceStringValue((int)swUserPreferenceStringValue_e.swDefaultTemplateDrawing);
                    break;
                default:
                    break;
            }

            if (!File.Exists(templatePath))
            {
                templatePath =
                    Path.GetDirectoryName(templatePath) + "\\" +
                    Path.GetFileName(templatePath).
                    Replace("零件", "gb_part").
                    Replace("装配体", "gb_assembly").Replace("工程图", "gb_a1");
            }

            if (!File.Exists(templatePath))
            {
                throw new FileNotFoundException("无法找到SolidWorks文件--" + templatePath);
            }

            return sldWorks.CreateDocument(templatePath);
        }

2.2.通过模板新建文档

上面我们通过获取SolidWorks默认设置的模板来新建一个零件或者装配体,下面我们通过一个给定的模板路径来新建一个零件或者装配体。

        /// <summary>
        /// 通过模板创建新零件或者新项目
        /// </summary>
        /// <param name="app"></param>
        /// <param name="TemFilePath">*.asmdot 或者 *.prtdot</param>
        /// <returns></returns>
        public static ModelDoc2 NewPartOrAssembly(this SldWorks app, string TemFilePath)
        {
            return app.NewDocument(TemFilePath, (int)swDwgPaperSizes_e.swDwgPaperA4size, 100, 100) as ModelDoc2;
        }

3.修改SolidWorks设置

获取SolidWorks设置选项的基本方法在ISldWorks接口下,如下


获取SolidWorks设置选项

修改SolidWorks设置选项的方法也在ISldWorks接口下,大概与获取相对应,如下:
修改SolidWorks设置项

3.1 先获取设置项,执行完需要的代码后,将选项设置为默认状态

下面的代码演示了如何在某种状态下执行我们的业务代码,然后将设置选项还原到默认状态,以达到不随意改变用户设置的要求。

        /// <summary>
        /// 设置一个选项后执行动作,执行完后设置回系统默认值
        /// </summary>
        /// <param name="app">ISldwork interface</param>
        /// <param name="toggleSetting">需要设置的枚举值</param>
        /// <param name="value">值</param>
        /// <param name="action">执行的动作</param>
        public static void WithToggleState(this ISldWorks app, swUserPreferenceToggle_e toggleSetting, bool value, Action action)
        {
            try
            {
                bool fileLockState = app.GetUserPreferenceToggle(toggleSetting.SWToInt());
                app.SetUserPreferenceToggle(swUserPreferenceToggle_e.swLockRecentDocumentsList.SWToInt(), true);
                action?.Invoke();
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                app.SetUserPreferenceToggle(toggleSetting.SWToInt(), value);
            }
        }

下一篇:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容

  • SolidWorks开发之Linq初探 一.何为Linq 语言集成查询(英语:Language Integrate...
    dududuwei阅读 773评论 0 3
  • 前言前言 随着科学技术的飞速发展和科学技术的日新月异,产品更新换代的速度也越来越快,复杂零件的个数也越来越多,产...
    穆山阅读 1,755评论 0 10
  • 行动已经结束了,但生活仍在继续,在行动里面养成的微习惯将会延续到生活当中。
    絮言ZXR阅读 99评论 0 0
  • 中国历史上最多情的作家曹雪芹,在红楼中选美,在梦中选美,在美中选美,在女人中选女人,把天下的女人给写绝了,把女性美...
    徐徳怀阅读 965评论 0 3
  • 初中时代首次读到辛弃疾的“少年不识愁滋味,爱上层楼,爱上层楼,为赋新词强说愁”,实在是不以为然。不是少年,...
    迟朝生阅读 489评论 3 10