Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Visual Basic late binding failure on COM objects #90541

Closed
MikeJDeck opened this issue Aug 14, 2023 · 3 comments · Fixed by #91399
Closed

Visual Basic late binding failure on COM objects #90541

MikeJDeck opened this issue Aug 14, 2023 · 3 comments · Fixed by #91399

Comments

@MikeJDeck
Copy link

MikeJDeck commented Aug 14, 2023

Description

When a COM object is used (through an interop assembly) in Visual Basic, late binding can fail in two cases:

  1. If the object has been cast to a plain Object type.
  2. 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

Other information

No response

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Aug 14, 2023
@AaronRobinsonMSFT
Copy link
Member

AaronRobinsonMSFT commented 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# 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.

/cc @agocke @jkoritzinsky @cston

@AaronRobinsonMSFT AaronRobinsonMSFT added this to the 9.0.0 milestone Aug 15, 2023
@AaronRobinsonMSFT AaronRobinsonMSFT added help wanted [up-for-grabs] Good issue for external contributors and removed untriaged New issue has not been triaged by the area owner help wanted [up-for-grabs] Good issue for external contributors labels Aug 15, 2023
@AaronRobinsonMSFT
Copy link
Member

The look up logic could be updated to inspect the COM instance below:

Friend Function LookupNamedMembers(ByVal memberName As String) As MemberInfo()

@MikeJDeck
Copy link
Author

MikeJDeck commented 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:

  • 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.

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Aug 31, 2023
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Aug 31, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Oct 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants