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