16 Replies Latest reply on Nov 2, 2017 12:44 PM by Peter Brinkhuis

    OpenDoc6 only works after manual file open

    Peter Brinkhuis

      Hi guys,

       

      I'm getting my hands dirty with C# add-ins and I'm running into the most basic stuff. I'm trying to open a drawing from a part file. This is the code that does the work, I've removed the checks and most try catch blocks for clarity.The strange thing is that the code usually goes into the catch block, unless I've opened and closed the drawing file in this current SolidWorks session. If I've opened it before, it just works. There is a FileNotFoundException and the error variable remains at zero. Any idea what could be going wrong here?

       

        SldWorks swApp;

        ModelDoc2 swModel;

        DrawingDoc drawing;

        int errors = 0;

        int warnings = 0;

       

        // Get currently running SW app

       

        swApp = (SldWorks)Marshal.GetActiveObject("SldWorks.Application");

        swModel = (ModelDoc2)swApp.ActiveDoc;

       

        // Create drawing path

        drawingLocation = Path.ChangeExtension(swModel.GetPathName(),"slddrw");

       

        try

        {

           swModel = swApp.OpenDoc6(drawingLocation, (int)swDocumentTypes_e.swDocDRAWING, (int)swOpenDocOptions_e.swOpenDocOptions_Silent, "", ref errors, ref warnings);

        }

        catch

        {

        MessageBox.Show($"Open didn't work, error = {errors}");

        return;

        }

        • Re: OpenDoc6 only works after manual file open
          Nilesh Patel

          Hi Peter,

           

          Have you tried ".slddrw" instead  of just "slddrw" in Path.ChangeExtension method?

           

          Regards,

          • Re: OpenDoc6 only works after manual file open
            Peter Brinkhuis

            Great, just found an issue from 2010 that looks a lot like mine:

            OpenDoc, NewDrawing & NewDocument crash SW when trying to open Drawing

             

            They state the issue doesn't arise when any drawing has been opened before. I hadn't tested that yet, but the exact same behavior occurs here.

              • Re: OpenDoc6 only works after manual file open
                Jim Sculley

                The Knowledge base says that was fixed in SW 2011.

                 

                At this point it would be helpful if you posted a complete example showing the bad behavior.  You say you are working with C# add-ins but the code you posted looks more like a standalone application.  An add-in would never need to use GetActiveObject, since an add-in can only exist inside a running SOLIDWORKS session and already has a SldWorks object (passed to it in the ConnectToSW method) to work with.

                  • Re: OpenDoc6 only works after manual file open
                    Peter Brinkhuis

                    Thanks for helping me trying to figure this out. The Knowledge base indeed states the bug as fixed. It's just that what they describe there looks an awful lot like what I see happening.

                     

                    I may have to explain myself here a bit more, that's true. I'm building an add-in using Luke Malpass' SolidDna that acts as a wrapper around the whole SolidWorks API. Since not all functionality of the API is included yet, I'm using the code above to open a new file.

                • Re: OpenDoc6 only works after manual file open
                  Luke Malpass

                  This issue looks like it has appeared again. Running a SolidDna or standard add-in, doing anything with drawings before they are created (NewDocument, NewDrawing, OpenDoc6/7) all cause the same issue.

                   

                   

                  The issue is, SolidWorks has a bug that isn't loading the file dependencies and dlls that are needed to open drawings. Calling the above functions from an add-in (works fine for macros), causes initially this error:

                   

                   

                  Could not load file or assembly 'CmdInterface, Version=25.1.0.49, Culture=neutral, PublicKeyToken=5fb9ba1b1131ddb5' or one of its dependencies. The system cannot find the file specified.

                   

                  at BaseDimData_c.{ctor}{BaseDimData_c*, uiModelDoc_c* activeDoc)}

                   

                  Source: annotationcplu

                   

                   

                  To resolve that issue (messy but just to try and diagnose more), I did:

                   

                  AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

                   

                  private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)

                  {

                      var applicationDirectory = @"C:\Program Files\SOLIDWORKS Corp\SOLIDWORKS";

                   

                      var fields = args.Name.Split(',');

                      var assemblyName = fields[0];

                      string assemblyCulture;

                   

                      if (fields.Length < 2)

                          assemblyCulture = null;

                      else

                          assemblyCulture = fields[2].Substring(fields[2].IndexOf('=') + 1);

                   

                      var assemblyFileName = assemblyName + ".dll";

                      string assemblyPath;

                   

                      if (assemblyName.EndsWith(".resources"))

                      {

                          // Specific resources are located in app subdirectories

                          var resourceDirectory = Path.Combine(applicationDirectory, assemblyCulture);

                   

                          assemblyPath = Path.Combine(resourceDirectory, assemblyFileName);

                      }

                      else

                          assemblyPath = Path.Combine(applicationDirectory, assemblyFileName);

                   

                      if (File.Exists(assemblyPath))

                      {

                          //Load the assembly from the specified path.                   

                          Assembly loadingAssembly = Assembly.LoadFrom(assemblyPath);

                   

                          //Return the loaded assembly.

                          return loadingAssembly;

                      }

                      else

                          return null;

                  }

                   

                  This resolves all assemblies it tries to load which would typically fail. However it cannot find any .resources files like that of AnnotationWPF.resources, so they fail to load without a FileNotFound though.

                   

                  Then the open command fails with:

                   

                  System.Windows.ResourceReferenceKeyNotFoundException: ''BorderStyle_None' resource not found.'

                   

                     at MS.Internal.Helper.FindResourceHelper.DoTryCatchWhen(Object arg)

                     at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)

                     at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

                     at MS.Internal.Helper.FindResourceHelper.TryCatchWhen()

                     at System.Windows.FrameworkElement.FindResource(Object resourceKey)

                     at AnnotationWPF.DimOnScreenWnd.NotifyParenthesisBorderChanged()

                     at AnnotationCoupling.DimDataCoupler_c.DataChanged()

                     at SolidWorks.Interop.sldworks.ISldWorks.NewDocument(String TemplateName, Int32 PaperSize, Double Width, Double Height)

                   

                  This issue is due to the missing resource files. They exist nowhere on my machine so I suspect they are perhaps embedded resources that are not loaded. If someone can find those, this solution would then work if we load those resources I believe.

                   

                  I also notice when opening a drawing manually, that the dll C:\Program Files\SOLIDWORKS Corp\SOLIDWORKS\drwcplu.dll is loaded too, which is not even requested when done through the API.

                  Manually loading this dll in advance however changes nothing.

                   

                  That is as much time as I have to dig into this, perhaps someone can report the bug to SW.

                   

                  The solution I see, although messy, is perhaps to create a simple OpenDocument macro that you then call RunMacro from your add-in to bypass this issue for now.

                    • Re: OpenDoc6 only works after manual file open
                      Peter Brinkhuis

                      Thanks for looking into it Luke. I'll go figure out how to report a bug and point em to this topic.

                       

                      Edit: sent an email to api support as I don't have a VAR, hope it gets handled from there.

                      • Re: OpenDoc6 only works after manual file open
                        Peter Brinkhuis

                        With help of SW API support we looked into this issue. We were able to open a drawing file from the standard SW addin template. That means there's hope

                         

                        When switching back to my code, including the SolidDna wrapper, we found the same error of a missing file CmdInterface version 25.1.0.49. This file with the same version number can be found in C:/Program Files/SOLIDWORKS Corp/SOLIDWORKS, so the default folder. Why it's not being found in the default installation folder is the next mystery they are trying to solve.

                          • Re: OpenDoc6 only works after manual file open
                            Luke Malpass

                            If you checkout my example code above I got past that and showed the issue. The reason the standard template works is it has nothing that forces an annotation to fire off a WPF render so it's the contents of the template.

                             

                            The underlying issue is that the API is not doing an assembly load to load all dependencies required to open drawing files. I also solved that by manually loading them on demand.

                             

                            The remaining issue is it asks to load .resources files which contain WPF styles that the drawing templates in question use.

                             

                            As those resources don't exist in the installation so I am guessing the API loads them from embedded into another file.

                             

                            If we can find where the resources are my fix can be finished to work around the issue 

                        • Re: OpenDoc6 only works after manual file open
                          Peter Brinkhuis

                          A few months later, I'm trying to get this problem over with. I still can't get a drawing to open/create via my add-in when no drawing has been opened before in this session.

                           

                          Luke suggested:

                          The solution I see, although messy, is perhaps to create a simple OpenDocument macro that you then call RunMacro from your add-in to bypass this issue for now.

                          I tried calling a macro that opens or creates a drawing from my addin. Calling a macro works, until I add a line to do something with a drawing. Then I get an error message that something goes wrong with the macro and that the system might be unstable.

                           

                          When done through the standard add-in template supplied by SolidWorks, it does work. That's why api support told me to "just use that template and ditch SolidDNA." To be honest, that's not really constructive or helpful.

                           

                          Does anyone have any idea how to approach this issue? I'm really out of my depth here.