Solidworks插件在局域网中自动升级


插件开发完毕以dll文件的方式发布出去。但是bug避免不了,并且添加的新功能也需要更新插件。

Solidworks一旦启动插件,那么加载的dll就不能直接覆盖,因为是写保护状态。

把插件分为两部分,一部分用Solidworks自动加载,该部分实现插件的接口及完成另一部分的更新及加载。

    public class SwAddin : ISwAddin
    {
        #region 本地变量
        private object CommandInstance;
        private Type CommandManager;
        private ISldWorks iSwApp = null;
        private ICommandManager iCmdMgr = null;
        private int addinID = 0;

        #region Event 变量指针
        private Hashtable openDocs = new Hashtable();
        private SldWorks SwEventPtr = null;
        #endregion

        #region 公共属性
        public ISldWorks SwApp { get { return iSwApp; } }

        public ICommandManager CmdMgr { get { return iCmdMgr; } }

        public Hashtable OpenDocs { get { return openDocs; } }
        #endregion
        #endregion

        #region ISwAddin实现
        /// 
        /// 插件类构造函数
        /// 
        public SwAddin()
        {
            // 比较本地和服务器上dll文件日期,如果服务器上文件新则复制到本地
            return;
        }

        /// 
        /// 连接Solidworks
        /// 
        /// Solidworks对象
        /// 分配的Cookie
        /// 
        public bool ConnectToSW(object ThisSW, int cookie)
        {
            iSwApp = (ISldWorks)ThisSW;
            addinID = cookie;

            #region 设置回调
            iSwApp.SetAddinCallbackInfo(0, this, addinID);
            #endregion

            #region 命令管理器
            iCmdMgr = iSwApp.GetCommandManager(cookie);
            AddCommandMgr();
            #endregion

            #region 事件句柄
            SwEventPtr = (SldWorks)iSwApp;
            openDocs = new Hashtable();
            AttachEventHandlers();
            #endregion

            return true;
        }

        /// 
        /// 断开Solidworks连接
        /// 
        /// 
        public bool DisconnectFromSW()
        {
            RemoveCommandMgr();
            DetachEventHandlers();
            Marshal.ReleaseComObject(iCmdMgr);
            iCmdMgr = null;
            Marshal.ReleaseComObject(iSwApp);
            iSwApp = null;
            GC.Collect();
            GC.WaitForPendingFinalizers();
            return true;
        }
        #endregion

        #region UI方法
        /// 
        /// 添加命令组
        /// 
        public void AddCommandMgr()
        {
            Assembly assy = Assembly.LoadFrom("dll文件全名");  // 通过反射的方式调用dll文件
            Type CommandType = assy.GetType("NameSpace.ClassName");  // 创建类的实例对象
            CommandInstance = Activator.CreateInstance(CommandType, new object[] { iSwApp, iCmdMgr });
            CommandManager = CommandInstance.GetType();
            CommandManager.GetMethod("AddCommandMgr", BindingFlags.Instance | BindingFlags.Public).Invoke(CommandInstance, null);
            return;
        }

        /// 
        /// 删除命令组
        /// 
        public void RemoveCommandMgr()
        {
            CommandManager.GetMethod("RemoveCommandMgr", BindingFlags.Instance | BindingFlags.Public).Invoke(CommandInstance, null);
            return;
        }
        #endregion

        #region UI回调
        /// 
        /// 回调函数
        /// 
        /// 
        public void CallBackFunction(string cmd)
        {
            CommandManager.GetMethod("Do" + cmd, BindingFlags.Instance | BindingFlags.Public).Invoke(CommandInstance, null);
            return;
        }

        /// 
        /// 使能函数
        /// 
        /// 
        /// 
        public int EnableFunction(string cmd)
        {
            return (int)CommandManager.GetMethod(cmd, BindingFlags.Instance | BindingFlags.Public).Invoke(CommandInstance, null);
        }
        #endregion

        #region 事件方法
        public bool AttachEventHandlers()
        {
            AttachSwEvents();
            AttachEventsToAllDocuments();
            return true;
        }

        private bool AttachSwEvents()
        {
            try
            {
                SwEventPtr.ActiveDocChangeNotify += new DSldWorksEvents_ActiveDocChangeNotifyEventHandler(OnDocChange);
                SwEventPtr.DocumentLoadNotify2 += new DSldWorksEvents_DocumentLoadNotify2EventHandler(OnDocLoad);
                SwEventPtr.FileNewNotify2 += new DSldWorksEvents_FileNewNotify2EventHandler(OnFileNew);
                SwEventPtr.ActiveModelDocChangeNotify += new DSldWorksEvents_ActiveModelDocChangeNotifyEventHandler(OnModelChange);
                SwEventPtr.FileOpenPostNotify += new DSldWorksEvents_FileOpenPostNotifyEventHandler(FileOpenPostNotify);
                return true;
            }
            catch
            {
                return false;
            }
        }

        private bool DetachSwEvents()
        {
            try
            {
                SwEventPtr.ActiveDocChangeNotify -= new DSldWorksEvents_ActiveDocChangeNotifyEventHandler(OnDocChange);
                SwEventPtr.DocumentLoadNotify2 -= new DSldWorksEvents_DocumentLoadNotify2EventHandler(OnDocLoad);
                SwEventPtr.FileNewNotify2 -= new DSldWorksEvents_FileNewNotify2EventHandler(OnFileNew);
                SwEventPtr.ActiveModelDocChangeNotify -= new DSldWorksEvents_ActiveModelDocChangeNotifyEventHandler(OnModelChange);
                SwEventPtr.FileOpenPostNotify -= new DSldWorksEvents_FileOpenPostNotifyEventHandler(FileOpenPostNotify);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public void AttachEventsToAllDocuments()
        {
            ModelDoc2 modDoc = (ModelDoc2)iSwApp.GetFirstDocument();
            while (modDoc != null)
            {
                if (!openDocs.Contains(modDoc))
                {
                    AttachModelDocEventHandler(modDoc);
                }
                else if (openDocs.Contains(modDoc))
                {
                    bool connected = false;
                    DocumentEventHandler docHandler = (DocumentEventHandler)openDocs[modDoc];
                    if (docHandler != null)
                    {
                        connected = docHandler.ConnectModelViews();
                    }
                }

                modDoc = (ModelDoc2)modDoc.GetNext();
            }
        }

        public bool AttachModelDocEventHandler(ModelDoc2 modDoc)
        {
            if (modDoc == null) return false;

            DocumentEventHandler docHandler = null;

            if (!openDocs.Contains(modDoc))
            {
                switch (modDoc.GetType())
                {
                    case (int)swDocumentTypes_e.swDocPART:
                    {
                        docHandler = new PartEventHandler(modDoc, this);
                        break;
                    }
                    case (int)swDocumentTypes_e.swDocASSEMBLY:
                    {
                        docHandler = new AssemblyEventHandler(modDoc, this);
                        break;
                    }
                    case (int)swDocumentTypes_e.swDocDRAWING:
                    {
                        docHandler = new DrawingEventHandler(modDoc, this);
                        break;
                    }
                    default:
                    {
                        return false;
                    }
                }
                docHandler.AttachEventHandlers();
                openDocs.Add(modDoc, docHandler);
            }
            return true;
        }

        public bool DetachModelEventHandler(ModelDoc2 modDoc)
        {
            DocumentEventHandler docHandler;
            docHandler = (DocumentEventHandler)openDocs[modDoc];
            openDocs.Remove(modDoc);
            modDoc = null;
            docHandler = null;
            return true;
        }

        public bool DetachEventHandlers()
        {
            DetachSwEvents();

            DocumentEventHandler docHandler;
            int numKeys = openDocs.Count;
            object[] keys = new object[numKeys];

            openDocs.Keys.CopyTo(keys, 0);
            foreach (ModelDoc2 key in keys)
            {
                docHandler = (DocumentEventHandler)openDocs[key];
                docHandler.DetachEventHandlers();
                docHandler = null;
            }
            return true;
        }
        #endregion

        #region 事件句柄
        public int OnDocChange()
        {
            return 0;
        }

        public int OnDocLoad(string docTitle, string docPath)
        {
            return 0;
        }

        public int FileOpenPostNotify(string FileName)
        {
            AttachEventsToAllDocuments();
            return 0;
        }

        public int OnFileNew(object newDoc, int docType, string templateName)
        {
            AttachEventsToAllDocuments();
            return 0;
        }

        public int OnModelChange()
        {
            return 0;
        }
        #endregion    }
通过反射的方式调用NameSpace.ClassName

using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swconst;
using SolidWorksTools.File;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using SldView = SolidWorks.Interop.sldworks.View;

namespace NameSpace
{
    public class ClassName
    {
/// 
        /// 工具条
        /// 
        public readonly int mainCmdGroupID = 1;

        /// 
        /// 按钮
        /// 
        public const int mainItemID1 = 1;
        public const int mainItemID2 = 2;
        public const int mainItemID3 = 3;
private ISldWorks iSwApp = null;
        private ICommandManager iCmdMgr = null;
private BitmapHandler iBmp;
private ModelDoc2 swModel;
public WzCommand(ISldWorks swApp, ICommandManager cmdMgr)
        {
            iSwApp = swApp;
            iCmdMgr = cmdMgr;
        }

/// /// 获取图像 /// /// 命令组 /// 菜单按钮 private void GetIcons(out string[] mainIcons, out string[] icons) { if (iBmp == null) iBmp = new BitmapHandler(); Assembly thisAssembly = Assembly.GetAssembly(GetType()); mainIcons = new string[3]; icons = new string[3]; icons[0] = iBmp.CreateFileFromResourceBitmap("Namespace.Toolbar20.bmp", thisAssembly); icons[1] = iBmp.CreateFileFromResourceBitmap("Namespace.Toolbar32.bmp", thisAssembly); icons[2] = iBmp.CreateFileFromResourceBitmap("Namescape.Toolbar40.bmp", thisAssembly); mainIcons[0] = iBmp.CreateFileFromResourceBitmap("Namespace.MainIcon20.bmp", thisAssembly); mainIcons[1] = iBmp.CreateFileFromResourceBitmap("Namespace.MainIcon32.bmp", thisAssembly); mainIcons[2] = iBmp.CreateFileFromResourceBitmap("Namespace.MainIcon40.bmp", thisAssembly); thisAssembly = null; } /// /// 添加命令组 /// public void AddCommandMgr() { string[] mainIcons = new string[3]; string[] icons = new string[3]; GetIcons(out mainIcons, out icons); ICommandGroup cmdGroup = new ICommandGroup;int cmdIndex0, cmdIndex1, cmdIndex2; int[] docTypes = new int[] { (int)swDocumentTypes_e.swDocASSEMBLY, (int)swDocumentTypes_e.swDocDRAWING, (int)swDocumentTypes_e.swDocPART }; int cmdGroupErr = 0; int[] knownIDs = new int[3] { mainItemID1, mainItemID2, mainItemID3 };bool ignorePrevious = true; bool getDataResult; object registryIDs; getDataResult = iCmdMgr.GetGroupDataFromRegistry(mainCmdGroupID, out registryIDs); string cmdGroupDescription = "工具条名称"; if (getDataResult) ignorePrevious = !CompareIDs((int[])registryIDs, knownIDs); cmdGroup = iCmdMgr.CreateCommandGroup2(mainCmdGroupID, cmdGroupDescription, cmdGroupDescription, cmdGroupDescription[i], -1, ignorePrevious, ref cmdGroupErr); cmdGroup.MainIconList = mainIcons; cmdGroup.IconList = icons; #region 工具条显示在不同类型文档中 cmdGroup.ShowInDocumentType = (int)swDocTemplateTypes_e.swDocTemplateTypePART | (int)swDocTemplateTypes_e.swDocTemplateTypeASSEMBLY; #endregion int menuToolbarOption = (int)(swCommandItemType_e.swToolbarItem | swCommandItemType_e.swMenuItem); cmdIndex0 = cmdGroup.AddCommandItem2("功能1", -1, "功能1", "功能1", 0, "CallBackFunction(功能1)", "EnableFunction(Enable)", mainItemID1, menuToolbarOption); cmdIndex1 = cmdGroup.AddCommandItem2("功能2", -1, "功能2", "功能2", 1, "CallBackFunction(功能2)", "EnableFunction(Enable)", mainItemID2, menuToolbarOption); cmdIndex2 = cmdGroup.AddCommandItem2("功能3", -1, "功能3", "功能3", 2, "CallBackFunction(功能3)", "EnableFunction(Enable)", mainItemID3, menuToolbarOption); #region 启用命令foreach (CommandGroup cmdgroup in cmdGroups) { cmdgroup.HasMenu = true; cmdgroup.HasToolbar = true; cmdgroup.Activate(); } #endregion return; } /// /// 删除命令组 /// public void RemoveCommandMgr() { iBmp.Dispose(); foreach (int i in mainCmdGroupID) { iCmdMgr.RemoveCommandGroup(i); } } /// /// 比较已注册的命令组 /// /// 已注册 /// 现在 /// private bool CompareIDs(int[] storedIDs, int[] addinIDs) { List<int> storedList = new List<int>(storedIDs); List<int> addinList = new List<int>(addinIDs); addinList.Sort(); storedList.Sort(); if (addinList.Count != storedList.Count) return false; for (int i = 0; i < addinList.Count; i++) { if (addinList[i] != storedList[i]) return false; } return true; } #region 回调函数 public void Do功能1() {
// some code
return; } public void Do功能2() { // some codereturn; } public void Do功能3() { // some codereturn; } #endregion #region 命令可用 public int Enable() { return 1; } #endregion } }



Namespace