You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Visual Basic late binding failure on COM objects #90541
When a COM object is used (through an interop assembly) in Visual Basic, late binding can fail in two cases:
If the object has been cast to a plain Object type.
If the object implements more than one interface (e.g. InterfaceA and InterfaceB). If the object is declared as InterfaceA, late binding will fail on a property that is defined on InterfaceB.
This problem shows up in .NET 7 and .NET 8 preview 7. It is a regression from .NET Framework behavior.
The problem does not show up in C# when doing late binding on the dynamic type.
Reproduction Steps
Problem 1 can be shown with Microsoft Excel COM Interop.
The attached Visual Studio solution demonstrates problems 1 and 2. It contains a COM server and .NET test projects. Details are in the README.md file. ATLTest563.zip
Expected behavior
On the Windows OS, late binding on COM objects works the same as in the .NET Framework.
Actual behavior
Late binding fails under the conditions decribed above (more details in the README.md file).
Regression?
It is a regression from .NET Framework 4.8 (and previous versions of .NET Framework).
It is probably not a regression from previous releases of .NET Core.
Problem 1 has been reported previously in .NET 5.
Known Workarounds
The workaround is to use early (compile-time) binding.
That workaround is fine for new code, but there is a lot of existing late-binding code in .NET Framework written against the Autodesk Inventor API by Inventor customers. We want to provide a seemless upgrade path for the authors of that code.
Configuration
.NET 7, and .NET 8 preview 7.
Windows 10
x64 or x86
@MikeJDeck Thanks for this suggestion. I would also like to thank you for an amazing repro sample, it is most appreciated.
As noted, we've previously pushed back on several late bound scenarios. This one is slightly different but in the same domain as the others. I can concieve of a potential solution here by consuming the C# dynamic infrastructure to inspect the COM object, but I am unsure if the effort to do that work is worth the result. This is also just a hypothesis, I've not attempted to prototype that solution.
I'm going to push this into .NET 9 as something to consider rather than just marking this "by design". We need some more interest and if the community indicates there is that we can consider creating a minor affordance here.
@AaronRobinsonMSFT , thanks for looking at this and putting it into .NET 9.
Here's a few more details about our business case. In Inventor, we use Visual Basic as something like a scripting language. It is wrapped in a layer that we call iLogic (Inventor Logic). The user only sees their source code and the results of executing the code. We compile their code into DLLs, but these are generally not visible to the user and are not persisted beyond a single session of Inventor.
Users will often keep the same source code over several releases of Inventor.
Users are writing programs, but they don't need to know about the underlying .NET system. Many don't have a lot of programming experience. For them, we want to make the move from .NET 4.8 to .NET 8 as seamless as possible in our Inventor 2025 release (planned for April 2024). Unless their code is explicitly using .NET types that are no longer supported or have changed, we hope they can compile or run their existing code unchanged.
In the Inventor API, a common example of the pattern of late binding on a base object is:
PartDocument is derived from Document
AssemblyDocument is also derived from Document
a ComponentDefinition property is available on both PartDocument and AssemblyDocument. But these properties have different types.
We're trying to figure out how many people are using these in a late-binding way. Our conservative estimate at this time is 100 programmers and 1500 consumers of those programs.
Here's a text file ComponentDefinition.late.binding.samples.txt
with links to examples of this pattern on our forum. You'll find it on a page if you search for ComponentDefinition and find it as a property of a Document object (such as ThisApplication.ActiveDocument).
All these samples are in Visual Basic (iLogic). You can also find this pattern used in VBA.
In addition, we have customers who are more familiar with programming and write add-ins or standalone executables against the Inventor API. Most of them are probably using C#, but some use Visual Basic and some of those probably have some cases of late binding.
Activity
AaronRobinsonMSFT commentedon Aug 15, 2023
@MikeJDeck Thanks for this suggestion. I would also like to thank you for an amazing repro sample, it is most appreciated.
As noted, we've previously pushed back on several late bound scenarios. This one is slightly different but in the same domain as the others. I can concieve of a potential solution here by consuming the C#
dynamicinfrastructure to inspect the COM object, but I am unsure if the effort to do that work is worth the result. This is also just a hypothesis, I've not attempted to prototype that solution.I'm going to push this into .NET 9 as something to consider rather than just marking this "by design". We need some more interest and if the community indicates there is that we can consider creating a minor affordance here.
/cc @agocke @jkoritzinsky @cston
AaronRobinsonMSFT commentedon Aug 15, 2023
The look up logic could be updated to inspect the COM instance below:
runtime/src/libraries/Microsoft.VisualBasic.Core/src/Microsoft/VisualBasic/CompilerServices/Symbols.vb
Line 950 in 782aea1
MikeJDeck commentedon Aug 15, 2023
@AaronRobinsonMSFT , thanks for looking at this and putting it into .NET 9.
Here's a few more details about our business case. In Inventor, we use Visual Basic as something like a scripting language. It is wrapped in a layer that we call iLogic (Inventor Logic). The user only sees their source code and the results of executing the code. We compile their code into DLLs, but these are generally not visible to the user and are not persisted beyond a single session of Inventor.
Users will often keep the same source code over several releases of Inventor.
Users are writing programs, but they don't need to know about the underlying .NET system. Many don't have a lot of programming experience. For them, we want to make the move from .NET 4.8 to .NET 8 as seamless as possible in our Inventor 2025 release (planned for April 2024). Unless their code is explicitly using .NET types that are no longer supported or have changed, we hope they can compile or run their existing code unchanged.
In the Inventor API, a common example of the pattern of late binding on a base object is:
We're trying to figure out how many people are using these in a late-binding way. Our conservative estimate at this time is 100 programmers and 1500 consumers of those programs.
Here's a text file
ComponentDefinition.late.binding.samples.txt
with links to examples of this pattern on our forum. You'll find it on a page if you search for ComponentDefinition and find it as a property of a Document object (such as ThisApplication.ActiveDocument).
All these samples are in Visual Basic (iLogic). You can also find this pattern used in VBA.
In addition, we have customers who are more familiar with programming and write add-ins or standalone executables against the Inventor API. Most of them are probably using C#, but some use Visual Basic and some of those probably have some cases of late binding.