17 Replies Latest reply on Sep 24, 2018 7:35 PM by Artem Taturevych

    Embed Interop Types?

    Taus Moller

      I was looking at Artem Taturevich's nifty tool for creating addins(SwEx.AddIn ). At the very start of the introduction video it is mentioned that it is recommended to set Embed interop types to false. In our development we have it set to true, but only because that is how the Solidworks' own template is set up. So i tried googling a bit and found that it was recommended several places like here and here. I am interested to know why this is recommended. Additionally i couldn't find any official word on it. so i was wondering if there if we should bother changing it. One of the links claims that it is needed to target CLR4. However we seem to be able to do that anyway. The other talks about being able to do "edit and continue" which would indeed be pretty cool, however i strongly suspect there are other issues with this as we also link som c++ libraries and some other stuff.

       

      Unfortunately it seems that it is not entirely free to make the switch as we would have to go through the our addin and do a whole bunch extra type casting. Therefore i would really like to hear peoples recommendation/opinion and reasoning on this. Are we ok to just keep embed interop types set, or should bite the bullet and change it?

        • Re: Embed Interop Types?
          Artem Taturevych

          When you embed your interops it basically means that the interface definitions are getting copied directly  to you assembly. So this is how full name looks like for SOLIDWORKS type when interop embedded:

          And this is when it is not embedded:

          The issues I have seen relates to casting (especially for some sort of handlers, i.e. property manager page, triad manipulator, callout) so InvalidCastException is thrown as SOLIDWORKS cannot 'recognise' that the COM type implements required interface.

           

          I have also seen Property Manager Pages displayed incorrectly when interops are embeded. This is something which I cannot constantly reproduce. But everytime the add-in/stand-alone behaves 'weirdly', this is usually fixed by Embed Interop Types. For example here is a recent case: https://forum.solidworks.com/message/884188#comment-884188

           

          Currently I do not have any example demonstrating the issue neither I found any solid proof or API reference for the possible issue, but I definitely seen strange behaviour with this before and I never seen this with interops embeded so I always have this option set to False and recommend to have it set to false.

            • Re: Embed Interop Types?
              Taus Moller

              We have in fact been faced a fair number of COM exceptions. A mix og RPC_DISCONNECT and InvalidCast. We might actually try to make the switch to see if it improves

               

               

              • Re: Embed Interop Types?
                Taus Moller

                Just a quick follow up question. The solidworkstools assembly seems to differ from the interop assemblies in that it has changed in a very long time. Should this also be referenced without embedding interop types?

                  • Re: Embed Interop Types?
                    Artem Taturevych

                    I think SolidWorksTools is not an interop, this is a pure .NET library, I believe it cannot be embedded (that option should be disabled)

                      • Re: Embed Interop Types?
                        Taus Moller

                        It isn't, but i see that it is already set to false.

                         

                        When i change embed interop types to false, it changes "copy local" to true. I would assume that the idea is that it uses the dll from the installation so i tried setting this to false as well. However this resulted in an error when registering our addin.  Do i need to redistribute the interop Dlls along with our addin?

                          • Re: Embed Interop Types?
                            Artem Taturevych

                            Yes, you need to redistribute all interops as well unless you register them in a GAC (which I would not recommend to do).

                              • Re: Embed Interop Types?
                                Taus Moller

                                Is there some "pretty" way of typecasting arrays that are returned from solidworks. With the interoptypes embedded i used to be able to do this:

                                 

                                    byte[] featureID = _doc.Extension.GetPersistReference3(feature);
                                

                                 

                                The easiest way i know of doing it without the embedded interop types is:

                                 

                                byte[] featureID = Array.ConvertAll((object[])_doc.Extension.GetPersistReference3(feature), x => (byte)x);
                                

                                 

                                Which is a bit cumbersome to do everytime i want to retrieve anything from SW

                                  • Re: Embed Interop Types?
                                    Artem Taturevych

                                    var featureID = _doc.Extension.GetPersistReference3(feature) as byte[];

                                      • Re: Embed Interop Types?
                                        Taus Moller

                                        Jesus christ you are fast

                                         

                                        Are you sure that will work? I tried

                                         

                                        byte[] featureID = (byte[])_doc.Extension.GetPersistReference3(feature)
                                        

                                         

                                        Which threw an exception. I was under the impression that if one fails the other does as well, the only difference being that it fails by returning null rather than throwing and exception

                                         

                                        Sorry to ask rather than testing it out, but i am in the middle of removing the embedded interop types, so my addin is not currently building thanks to whole bunch of type errors

                                      • Re: Embed Interop Types?
                                        Oleg Bezyaev

                                        I use something like this

                                        public static IEnumerable CastFromObject<T>(object input)
                                                {
                                                    return ((IEnumerable) input)?.Cast<object>()
                                                                                .Select(x => (T)x)
                                                                                .ToList();
                                                }
                                        

                                         

                                        And using:

                                        MathVector myVec2 = swMathUtil.CreateVector(new[] {0, 0, 0});
                                        var doubles = DataProccesor.CastFromObject<double>(myVec2.ArrayData);
                                        
                                      • Re: Embed Interop Types?
                                        Taus Moller

                                        I noticed that there is a new interop assembly with each service pack. Does this affect how i should redistribute the interop assemblies?

                                         

                                        I.e. does it matter what service pack a user has installed and what assemblies i redistribute? Would a user running SP 1.0 have issues if i redistribute the assemblies from SP 4? or vice versa?

                                          • Re: Embed Interop Types?
                                            Artem Taturevych

                                            Interops are backwards compatible and forward compatible for all functions which are supported in SW older then the interops. For example:

                                             

                                            IAssemblyDoc::CompConfigProperties5 method was added in SW 2017 (Revision 25.0). Which means it is available in all interops starting from version 25.0 and newer.

                                             

                                            So if you use this interop in say SW 2018 (26.0) - this is fully compatible and you do not need to updated it. But you can also use this interop in SW 2016 or older as long as you are not going to call the IAssemblyDoc::CompConfigProperties5 method as it is not supported by SW 2016.

                                             

                                            For example in SwEx.AddIn framework there is a following code snippet (pseudo example)

                                             

                                                        if (m_App.SupportsHighResIcons())//if sw 2016 or higher
                                                        {
                                            ...
                                                            cmdGroup.MainIconList = iconsList;
                                                            cmdGroup.IconList = iconsConv.ConvertIconsGroup(iconList, true);
                                                        }
                                                        else
                                                        {
                                            ...
                                                            cmdGroup.SmallIconList = smallIconList;
                                                            cmdGroup.LargeIconList = largeIconList;
                                                        }
                                            

                                             

                                            This allows to utilise high res icons in sw 2016 or newer but this code is still supported in older sw versions so the framework can be used there as well.

                                             

                                            I'm usually using the interop from the oldest SW my tool needs to support in this case I ensure the compile time validation of all methods which might not be supported.

                                             

                                            Hope this clarified the issue.

                                • Re: Embed Interop Types?
                                  Keith Rice

                                  My company has written hundreds of .NET programs for customers over the past several years and I have only found one instance where Embed Interop Types = True was causing a problem. In this case we weren't getting an exception, it was just causing dropdown menus to look and work incorrectly. But like Artem said, SolidWorks is obviously failing to execute certain calls.

                                   

                                  Since problems like I just shared seem to be the exception and not the norm, my company uses Embed Interop Types = True because simplifying the number and size of the binaries is a nice (albeit non-essential) benefit, in my opinion. If you want to be as safe as possible, though, I can understand why you would want to set it to False.

                                   

                                  Keith

                                  SolidWorks API Training and Services

                                    • Re: Embed Interop Types?
                                      Oleg Bezyaev

                                      "because simplifying the number and size of the binaries is a nice" - that's all? It's like using ILMerege just to make the user happy. The main thing is not correct code, not any not obvious "ComException" or "ThreadException" or great thing like RPC_DISCONNECT, just make it's smaller!!! I think Artem, who have tens of years of experience, was (and will) right.

                                        • Re: Embed Interop Types?
                                          Keith Rice
                                          1. We wouldn't ship code that is throwing exceptions, though. You seem to miss the point that some developers always set the property to False so they don't have to worry about it ever causing problems, not because setting it to False is inherently superior. If you always set it to false, regardless of whether it was necessary, then you miss out on your binaries being as simple as possible, not to mention that there's no need to remember to modify the property's value (unless NuGet or a template is used).
                                          2. Scott Stanley, the head of SolidWorks API development at SolidWorks Corp, recommended using it (or was at least enthusiastic about its use) when I asked him in person.
                                          3. Hans Passant, the 5th highest ranked user on StackOverflow, wrote this about the property: "Never [set Embed Interop Types = False], it is a very awesome feature that solves irksome deployment details." (source) Of course, he's not a SolidWorks API developer and therefore hasn't encountered some of the problems we have, but the point remains that its benefits aren't trivial.

                                           

                                          Keith

                                          SolidWorks API Training and Services