Hello SolidWorks community,
I'm experiencing an issue with a custom Add-In I've developed for SolidWorks.
The Add-In loads and functions correctly when SolidWorks is first started. However, after a period of inactivity, it seems to stop executing—possibly being unloaded or disabled. Once I manually reload the Add-In or restart SolidWorks, it works again without any issues.
The Add-In is designed to:
Automatically switch the model view to ISO before saving.
Exit "Edit Sheet" mode in drawings before saving.
Has anyone encountered a similar issue or have any insights into what might be causing this behavior? Any suggestions on how to prevent the Add-In from becoming inactive would be greatly appreciated.
Thank you in advance!
using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swcommands;
using SolidWorks.Interop.swconst;
using SolidWorks.Interop.swpublished;
using System;
using System.Runtime.InteropServices;
using System.Timers;
using Timer = System.Timers.Timer;
namespace SWXAddIn
{
    [Guid("572956E4-6151-49A6-BAD2-ECB11A379B60")]
    [ComVisible(true)]
    public class SolidWorksAddIn : ISwAddin
    {
        private SldWorks? _swxApp;
        private int _cookie;
        private Timer? _reconnectTimer;
        private DPartDocEvents_FileSaveNotifyEventHandler? _partSaved;
        private DAssemblyDocEvents_FileSaveNotifyEventHandler? _assemblySaved;
        private DDrawingDocEvents_FileSaveNotifyEventHandler? _drawingSaved;
        public bool ConnectToSW(object thisSw, int cookie)
        {
            _swxApp = thisSw as SldWorks;
            _cookie = cookie;
            if (_swxApp == null) return false;
            _swxApp.SetAddinCallbackInfo(0, this, _cookie);
            _swxApp.SendMsgToUser("Rosenxt SolidWorks AddIn loaded");
            _swxApp.TaskPaneIsPinned = true;
            if (_swxApp.ActiveDoc is ModelDoc2 modelDoc)
            {
                ConfigureComponentIdentifiers(modelDoc.FeatureManager);
                SubscribeToSaveEvents(modelDoc);
            }
            //_swxApp.CommandCloseNotify += OnCommandCloseNotify;
            new OptionSetter(_swxApp).DeactivateToolboxDefaultSearchFolder();
            StartReconnectMonitor();
            return true;
        }
        private void StartReconnectMonitor()
        {
            _reconnectTimer = new Timer(60000);
            _reconnectTimer.Elapsed += CheckConnection;
            _reconnectTimer.Start();
        }
        private void CheckConnection(object? sender, ElapsedEventArgs e)
        {
            try
            {
                if (_swxApp == null || _swxApp.GetProcessID() <= 0)
                {
                    ReconnectToSw();
                }
            }
            catch
            {
                ReconnectToSw();
            }
        }
        private void ReconnectToSw()
        {
            try
            {
                var swApp = SolidWorksConnector.GetActiveSolidWorksInstance("SldWorks.Application");
                if (swApp is not SldWorks swxApp) return;
                _swxApp = swxApp;
                _swxApp.SetAddinCallbackInfo(0, this, _cookie);
                _swxApp.SendMsgToUser("Rosenxt AddIn reconnected");
                if (_swxApp.ActiveDoc is ModelDoc2 modelDoc)
                {
                    ConfigureComponentIdentifiers(modelDoc.FeatureManager);
                    SubscribeToSaveEvents(modelDoc);
                }
                //_swxApp.CommandCloseNotify += OnCommandCloseNotify;
            }
            catch (Exception ex)
            {
                Console.WriteLine(\\\$"Reconnect failed: {ex.Message}");
            }
        }
        private void ConfigureComponentIdentifiers(IFeatureManager featureMgr)
        {
            int identifier = featureMgr.ComponentPrimaryIdentifier;
            if (identifier != 1)
            {
                featureMgr.SetComponentIdentifiers(1, 8, 0);
                featureMgr.SetComponentIdentifiers(1, 16, 0);
                featureMgr.SetComponentIdentifiers(1, 4, 0);
            }
            else
            {
                featureMgr.SetComponentIdentifiers(2, 8, 0);
                featureMgr.SetComponentIdentifiers(1, 8, 0);
                featureMgr.SetComponentIdentifiers(1, 16, 0);
                featureMgr.SetComponentIdentifiers(1, 4, 0);
            }
        }
        private void SubscribeToSaveEvents(ModelDoc2 modelDoc)
        {
            switch ((swDocumentTypes_e)modelDoc.GetType())
            {
                case swDocumentTypes_e.swDocASSEMBLY:
                    _assemblySaved = OnAssemblySave;
                    (modelDoc as AssemblyDoc)!.FileSaveNotify += _assemblySaved;
                    break;
                case swDocumentTypes_e.swDocPART:
                    _partSaved = OnPartSave;
                    (modelDoc as PartDoc)!.FileSaveNotify += _partSaved;
                    break;
                case swDocumentTypes_e.swDocDRAWING:
                    _drawingSaved = OnDrawingSave;
                    (modelDoc as DrawingDoc)!.FileSaveNotify += _drawingSaved;
                    break;
            }
        }
        private int OnAssemblySave(string docFileName) => ZoomToFitActiveDoc();
        private int OnPartSave(string docFileName) => ZoomToFitActiveDoc();
        private int OnDrawingSave(string docFileName)
        {
            if (_swxApp?.ActiveDoc is DrawingDoc drawingDoc)
            {
                if (drawingDoc.GetEditSheet())
                    drawingDoc.EditTemplate();
                drawingDoc.EditSheet();
                drawingDoc.ForceRebuild();
            }
            return 0;
        }
        //private int OnCommandCloseNotify(int command, int reason)
        //{
        //    if (command is (int)swCommands_e.swCommands_Save or
        //                   (int)swCommands_e.swCommands_SaveAll or
        //                   (int)swCommands_e.swCommands_SaveAs)
        //    {
        //        ZoomToFitActiveDoc();
        //    }
        //    return 0;
        //}
        private int ZoomToFitActiveDoc()
        {
            if (_swxApp?.ActiveDoc is IModelDoc2 modelDoc)
            {
                modelDoc.ShowNamedView2("", 7);
                modelDoc.ViewZoomtofit2();
            }
            return 0;
        }
        public bool DisconnectFromSW()
        {
            _reconnectTimer?.Stop();
            _reconnectTimer?.Dispose();
            if (_swxApp != null)
            {
                //_swxApp.CommandCloseNotify -= OnCommandCloseNotify;
                _swxApp.SendMsgToUser("Rosenxt SolidWorks AddIn unloaded");
                if (_partSaved != null && _swxApp?.ActiveDoc is PartDoc partDoc)
                    partDoc.FileSaveNotify -= _partSaved;
                if (_assemblySaved != null && _swxApp?.ActiveDoc is AssemblyDoc assemblyDoc)
                    assemblyDoc.FileSaveNotify -= _assemblySaved;
                if (_drawingSaved != null && _swxApp?.ActiveDoc is DrawingDoc drawingDoc)
                    drawingDoc.FileSaveNotify -= _drawingSaved;
                SolidWorksConnector.ReleaseComObject(_swxApp);
            }
            _swxApp = null;
            return true;
        }
    }
}
