A problem was reported in the beta of Inventor 2017, where an error dialog is appearing when shutting down Inventor. The error was being thrown by one of the add-ins delivered with Inventor. However, the Autodesk team was unable to reproduce the problem and couldn’t find any problems with the add-in. Someone suggested that maybe the cause was another add-in and after some testing an add-in on the Autodesk App Store could be used to reproduce the problem and using it the actual cause of the problem was found. Last week, I was notified that they identified the add-in that was causing the problem for the customer and it turned out to be my Sheet Metal Extents add-in. Not good.
My add-in has run fine for many releases now and I haven’t changed anything but apparently something has changed in some Microsoft components that is causing the problem to appear. After understanding the problem, it really is an error in my add-in and I’ve just been lucky that it hasn’t shown up before. The reason my Sheet Metal Extents add-in is causing the problem is because of how it is releasing the Inventor objects its referencing. It’s using the .NET function FinalReleaseComObject. Without going into a lot of COM details about object lifetimes and reference counting, this function forces an object to be released. At the time of the call everything seems fine, but the problem is that it might not be the only add-in using that Inventor object and when the other add-in tries to use that object the problem appears.
When we first started supporting .NET for writing add-ins, there was quite a bit of discussion about how to make it all work. With Visual Basic 6, when a variable goes out of scope or you explicitly set it to Nothing, the reference to the internal Inventor object is immediately released (actually the reference count is decremented by one and if it goes to zero then it’s released). With .NET, this doesn’t happen immediately but relies on the Garbage Collector to clean things up. That’s fine, but the Garbage Collector runs at an indeterminate time. Usually that’s ok but in the case of add-ins it was preventing Inventor from shutting down because Inventor thought there were still active external references to Inventor objects. .NET supports some functions to force the release of references and to force garbage collection. The functions FinalReleaseComObject and ReleaseComObject will do an explicit release. ReleaseCOMObject being the safer because it just decrements the reference count so if others are using the object it will still be available to them.
So, after seeing this I was planning to change my add-in to use ReleaseComObject instead of FinalReleaseComObject. However, I did a bit more research and found a very interesting article. It also made me feel better to see that Microsoft was struggling with some of the same problems. They strongly recommend to not use FinalReleaseComObject or ReleaseComObject but to allow the Garbage Collector to do it’s job. There were also some changes made in Inventor some time ago so that it won’t let an add-in keep it from shutting down.
What You Need to Do
In summary, you need to check your add-ins for any calls to FinalReleaseComObject and either change them to ReleaseComObject or even better is to remove them and just make sure you’re setting that reference to Nothing (null) so that the Garbage Collector can handle it correctly. If you’ve used the Inventor Add-In Template that’s delivered as part of the Inventor SDK, you should be in good shape because it’s already doing the correct thing. In the Deactivate method of the the add-in, It’s setting the variable that reference global Inventor objects to Nothing and then calls the Collect method of the garbage collection to force a collection. Let us know if you find any problems after making this change. I’ve removed the FinalReleaseComObject call from my Sheet Metal Extents add-in and everything seems to be working fine.