8 Replies Latest reply on Jul 12, 2018 9:11 AM by Jack Qu

    How to get solidworks handle (C#)

    Jack Qu

      Hello,

      In the standalone api of SolidWorks (C#), I use  ISldWorks app = (ISldWorks)Activator.CreateInstance(Type.GetTypeFromProgID("SldWorks.Application")) to create an instance, and use OpenDoc6 to open a file. In my addin program, I try to get this SolidWorks handle by using:  SldWorks app = (SldWorks)System.Runtime.InteropServices.Marshal.GetActiveObject("SldWorks.Application"), but this command does not work. Please give me some advices. Thanks.

      My computer: Windows 10, 64 bits, SolidWorks 2018

        • Re: How to get solidworks handle (C#)
          Alex Burnett

          If you're creating an add-in for SW then the connection logic is different. From what I understand, Solidworks will call a ConnectToSW function in the add-in and it will pass its program handle to your add-in.

           

          2016 SOLIDWORKS API Help - ConnectToSW Method (ISwAddin)

            • Re: How to get solidworks handle (C#)
              Jack Qu

              My addin is no problem when I directly open solidworks. My problem is when I create an instance from the standalone api, I cannot get the solidworks handle (app) in my addin  or in the sub-function of this standalone program.

               

              ISldWorks app = (ISldWorks)Activator.CreateInstance(Type.GetTypeFromProgID("SldWorks.Application"))  //works

               

              I need to get the handle in other sub-function:

              SldWorks app = (SldWorks)System.Runtime.InteropServices.Marshal.GetActiveObject("SldWorks.Application")  //no work???

              But this command does not work. So I have no way to get the active object handle.

                • Re: How to get solidworks handle (C#)
                  Alex Burnett

                  I need to know a little more about your code and workflow. Are you saying that you have an external API program that creates its own instance of SolidWorks? From there, you can't get your add-in to connect to the running instance?

                   

                  Why is this needed? Are you debugging your add-in by creating an instance and then trying to connect to that specific instance? I don't believe that will work.

                    • Re: How to get solidworks handle (C#)
                      Jack Qu

                      Some time ago, I have created an addin api. In this addin, I use UserControl to create a form with edit boxes and buttons and add it in the Task Pane. So I can input data and update solidworks model by the form with edit boxes and buttons.

                      In some functions of the user interface, I use SldWorks app = (SldWorks)System.Runtime.InteropServices.Marshal.GetActiveObject("SldWorks.Application") to get default handle app. This addin works without any problems.

                       

                      Recently, I create a new standalone api. In this program, I use ISldWorks app = (ISldWorks)Activator.CreateInstance(Type.GetTypeFromProgID("SldWorks.Application")) to get an instance of solidworks. Then I open a model with app.OpenDoc6(xxx) and add addin with app.LoadAddIn(xx). Till here, everything is ok. I can directly edit the model. The problem is when I click the button on the addin of Task Pane, it does not work. I find the problem is from the SldWorks app = (SldWorks)System.Runtime.InteropServices.Marshal.GetActiveObject("SldWorks.Application"), which means active solidworks handle cannot be found.

                       

                      Furthermore, I have some tests. Only run standalone api without considering addin. In the same standalone api, I use ISldWorks app = (ISldWorks)Activator.CreateInstance(Type.GetTypeFromProgID("SldWorks.Application")) to get an instance of solidworks. But I cannot use SldWorks app2 = (SldWorks)System.Runtime.InteropServices.Marshal.GetActiveObject("SldWorks.Application") to get the active solidworks handle in other functions. Both app and app2 do not match.

                       

                      My question: how to get the default active solidworks handle after you create an instance of solidworks using ISldWorks app = (ISldWorks)Activator.CreateInstance(Type.GetTypeFromProgID("SldWorks.Application")). Thanks.

                • Re: How to get solidworks handle (C#)
                  David Stockdale

                  I had to do something similar.  In my case, I had access to the process ID from a running instance of SOLIDWORKS using the function ISldWorks::GetProcessID.  I wrote the following helper class to get the active solidworks instance relating to the process ID.  If you have access to the PID, try the following:

                   

                  using System;
                  using System.Collections.Generic;
                  using System.Runtime.InteropServices;
                  using System.Runtime.InteropServices.ComTypes;
                  using SolidWorks.Interop.sldworks;
                  namespace your.prog.namespace
                  {
                      class MsDev
                      {
                          [DllImport("ole32.dll")]
                          public static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable port);
                          [DllImport("ole32.dll")]
                          public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc);
                  
                          public static SldWorks GetSolidWorksInstance(int PID)
                          {
                              IntPtr numFetched = IntPtr.Zero;
                              IRunningObjectTable runningObjectTable;
                              IEnumMoniker monikerEnumerator;
                              IMoniker[] monikers = new IMoniker[1];
                              GetRunningObjectTable(0, out runningObjectTable);
                              runningObjectTable.EnumRunning(out monikerEnumerator);
                              IBindCtx b;
                              monikerEnumerator.Reset();
                              while (monikerEnumerator.Next(1, monikers, numFetched) == 0)
                              {
                                  IBindCtx ctx;
                                  CreateBindCtx(0, out ctx);
                                  string runningObjectName;
                                  monikers[0].GetDisplayName(ctx, null, out runningObjectName);
                                  if (runningObjectName.Contains("SolidWorks"))
                                  {
                                      object runningObjectVal;
                                      runningObjectTable.GetObject(monikers[0], out runningObjectVal);
                                      // we should be safe to cast to our "real" solidworks object
                                      SldWorks swObj = runningObjectVal as SldWorks;
                                      if (swObj != null && swObj.GetProcessID() == PID)
                                      {
                                          return swObj;
                                      }
                                  }
                              }
                              return null;
                          }
                      }
                  }
                  
                  
                  
                  
                  
                  
                  
                  

                   

                  Hopefully this will help.

                   

                  Thanks,

                   

                  David

                  • Re: How to get solidworks handle (C#)
                    Artem Taturevych

                    Check this article: Connect to SOLIDWORKS from Stand-Alone Application

                    This will explain the differences when getting the pointers to sw. However in your addin you should only utilize the pointer passed to ConnectToSw function as this is ensured to be the current session. You need to pass this poinet to TaskPane or any other place within your add-in. The simplest way is to make the variable which holds sw pointer in your add-in class to be public and static.

                     

                    Basically you need to avoid using Activator.CreateInstance or Running Object Table to retrieve the poiner to sw within your add-in unless you need to connect to external instance of sw.