18 Replies Latest reply on Feb 4, 2019 9:57 AM by Peer Larson

    C# Stand Alone - Get active SW App

    Alexander Klammer

      Hi,

       

      I just tried to create a Stand Alone Application.

       

      However i tried to connect to my current Solidworks App.

       

      With these two methods:

      SldWorks swApp = (SldWorks)Activator.CreateInstance(Type.GetTypeFromProgID("SldWorks.Application"));
      
      SldWorks swApp = (SldWorks)System.Runtime.InteropServices.Marshal.GetActiveObject("SldWorks.Application");
      
      

       

      However i just was not able to get the first one going - when i tried to set swModel to the Active doc it always returned 0:

      (swModel = (ModelDoc2)swApp.ActiveDoc;)
      

       

      Any ideas what´s going wrong here?

       

      The second one worked but "just" when both - the Stand Alone App and SolidWorks where running as Administrator.

      I guess this is "normal" behaviour, but i´d like to make some stand alone applications for our engineers and running the stand alone app and solidworks as administrator won´t be possible because of user permissions.

       

      Does anyone have a solution for that?

       

      BR

      Alex

        • Re: C# Stand Alone - Get active SW App
          Alex Burnett

          I haven't had to set up a standalone program that connects to SW but the below code should work.

           

          swApp = CreateObject("SldWorks.Application")

           

          This thread outlines a couple different methods for creating or attaching to a SW instance.

          Create new instance of SOLIDWORKS

          • Re: C# Stand Alone - Get active SW App
            Viktor Bovzdarenko

            Hi Alexander,

            Try:

            ISldWorks app = Activator.CreateInstance(Type.GetTypeFromProgID("SldWorks.Application.25")) as ISldWorks;

            Where "25" - stands for SW 2017; you can use all other numbers for other versions of SW: 24 for SW 2016 and so on.

             

            Regards

            Viktor

            • Re: C# Stand Alone - Get active SW App
              Ivana Kolin

              can you try this? It is vb.net (easier for me, but it can be converted to C#)

              create new vb.net console application. Add reference to SolidWorks.Interop.sldworks. Check solidworks.exe path.

              No solidworks running. Run code.

              Module Module1
                  Dim ReadOnly SolidWorksPath As String = "C:\Program Files\SOLIDWORKS Corp\SOLIDWORKS\SLDWORKS.exe"
              
              
                  Sub Main()
                      Try
                          startSolidwoks
                          Dim swApp = getSwApp()
              
              
                      Catch ex As Exception
                          MsgBox(ex.Message)
                      End Try
                  End Sub
                  Private Sub startSolidwoks()
                      Dim swapp As SolidWorks.Interop.sldworks.SldWorks = Nothing
                      Dim startInfo As New ProcessStartInfo(SolidWorksPath)
                      startInfo.WindowStyle = ProcessWindowStyle.Normal
                      startInfo.Arguments = "-m"
                      Process.Start(startInfo)
                      Do While swapp Is Nothing
                          Try
                              swapp = TryCast(GetObject(, "SldWorks.application"), SolidWorks.Interop.sldworks.SldWorks)
                          Catch ex As Exception
              
              
                              Threading.Thread.Sleep(3000)
                          End Try
                      Loop
                  End Sub
                  Private Function getSwApp() As SolidWorks.Interop.sldworks.SldWorks
              
              
                      Dim iCountSw = Process.GetProcessesByName("SLDWORKS").Count(Function(process2) process2.MainWindowHandle <> IntPtr.Zero)
                      If iCountSw > 1 Then
                          Throw New ApplicationException("SolidWorks has been started multiple times.")
                      ElseIf iCountSw = 1 Then
                          ' this is ok
                      Else
                          Throw New ApplicationException("SolidWorks is not started.")
                      End If
              
              
                      Dim swApp As SolidWorks.Interop.sldworks.SldWorks = getSldWorksObject()
                      If swApp Is Nothing Then
                          Throw New ApplicationException("An instance of SolidWorks could not be retrieved.")
                      End If
                      Return swApp
                  End Function
              
              
                  Private Function getSldWorksObject() As SolidWorks.Interop.sldworks.SldWorks
                      Try
                          Return CType(System.Runtime.InteropServices.Marshal.GetActiveObject("SldWorks.Application"), SolidWorks.Interop.sldworks.SldWorks) '
                      Catch ex As Exception
                          Return Nothing
                      End Try
                  End Function
              
              End Module
              
                • Re: C# Stand Alone - Get active SW App
                  Alexander Klammer

                  Hi Ivana,

                   

                  Thank you very much for your help!

                  I´ll try this later - when i have some time - and report you how it worked.

                   

                  I just tried my code on another machine and it worked - so now i believe this is something machine specific.

                   

                  Machine 1 (where its NOT working) :

                  WIN 10 - 64 BIT - SWX 2017 and SWX 2018 Installed.

                   

                  Machine 2 (where it works):

                  WIN 7 - 64 BIT - SWX 2017 Installed.

                   

                  BR and Thank´s for your help!

                  Alex

                  • Re: C# Stand Alone - Get active SW App
                    Peer Larson

                    That was very helpful Ivana!

                     

                    Here's a shortened version I created based off of what you did:

                     

                    using System;
                    using SolidWorks.Interop.sldworks;
                    
                    
                    namespace ConnectToSW
                    {
                        class Program
                        {
                            static void Main(string[] args)
                            {
                                SldWorks swApp = null;
                                try
                                {
                                    swApp = (SldWorks)System.Runtime.InteropServices.Marshal.GetActiveObject("SldWorks.Application");
                                }
                                catch (System.Runtime.InteropServices.COMException  ex)
                                {
                                    switch (ex.ErrorCode)
                                    {
                                        case -2147221021: //Failed to find the object we are looking for, so start a new one.
                                            Console.WriteLine("SW is not running, starting a new instance.");
                                            swApp = new SldWorks();
                                            break;
                                        default:
                                            Console.WriteLine("HRESULT = 0x" + ex.ErrorCode.ToString("X") + " " + ex.Message);
                                            break;
                                    }
                                }
                                if (swApp != null)
                                {
                                    string currentversion;
                                    string baseversion;
                                    swApp.GetBuildNumbers(out baseversion, out currentversion);
                                    Console.WriteLine($"You are running SOLIDWORKS version {baseversion}.");
                                    swApp.ExitApp();
                                }
                                swApp = null;
                            }
                        }
                    }
                    
                  • Re: C# Stand Alone - Get active SW App
                    Alexander Klammer

                    It turned out my Installation was broken. Thanks for your help.

                     

                    However i stumbled over one Error that´s may be of relevance:

                    c# - Exception from HRESULT: 0x800401E3 (MK_E_UNAVAILABLE) Workarounds - Stack Overflow

                    This occurs when the Application which is  trying to connect and the target application are not running on the same permission level. (i often had solidworks running without Admin privileges but had Visual Studio - then this error pops up.)

                     

                    Maybe it would make sense to add some code that checks if both Applications run on the same permission level.

                     

                    Thank´s Ivana Kolin and Peer Larson for your very helpful contributions.

                    Further a big thank´s also for Artem Taturevych for this great article: Create C# Stand-Alone Application for SOLIDWORKS

                     

                    In the meanwhile i stick with this piece of code for my purposes - which if needed i will extend with the oportunity to connect to a specific session.

                     public ISldWorks GetSolidWorks(string progId, string process_name)
                            {
                                try
                                {
                                    if (Process.GetProcessesByName(process_name).GetLength(0) == 0)
                                    {
                                        MessageBox.Show("No running SolidWorks session detected - a new Session will be started!");
                                        //Start a new Session
                                        var progType = System.Type.GetTypeFromProgID(progId);
                    
                    
                                        swApp = System.Activator.CreateInstance(progType) as SolidWorks.Interop.sldworks.ISldWorks;
                                        swApp.Visible = true;
                                        return swApp;
                                    }
                                    else if (Process.GetProcessesByName(process_name).GetLength(0) == 1)
                                    {
                                        try
                                        {
                                            //Connect to running Session --> Important this app needs to run with same permission level as SolidWorks - i.e.Admin - Admin or None-None
                                            swApp = System.Runtime.InteropServices.Marshal.GetActiveObject(progId) as SolidWorks.Interop.sldworks.ISldWorks;
                                            return swApp;
                                        }
                                        catch (Exception ex)
                                        {
                                            MessageBox.Show("Failed to connect to SOLIDWORKS instance: (Permission issue?) " + ex.Message);
                                            return swApp = null;
                                        }
                                    }
                                    else if (Process.GetProcessesByName(process_name).GetLength(0) != 1)
                                    {
                                        MessageBox.Show("More than one Solidworks sessions are running, - please make shure that only 1 session is running before starting!");
                                        //Add Code to let user choose which session he wants to connect do
                    
                    
                    
                    
                                        return swApp = null;
                                    }
                                    else
                                    {
                                        MessageBox.Show("Unknown error occured.");
                                        //System.Windows.Application.Current.Shutdown();
                                        return swApp = null;
                                    }
                                }
                                catch (Exception ex)
                                {
                                    MessageBox.Show("Failed to connect to/start SOLIDWORKS instance: " + ex.Message);
                                    return swApp = null;
                                }
                            }
                    

                     

                    BR

                    Alex