I am doing COM automation with a 3rd party library. When trying to access certain properties I need to use obj.get_Property() instead of obj.Property.
This seems to be happening only for properties of type string that have both a getter and a setter.
I would like to understand why C# can't handle these cases, and if there's anything I can do to address this.
Edit - Additional info:
- The automation target application ships with type libraries in .tlb format, which Visual Studio uses to produce interop libraries.
- The decompiled interop library of interest looks similar to this:
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using NS0;
namespace NS1
{
[ComImport]
[Guid("AAAAAAAA-BBBB-CCCC-DDDD-000000000000")]
[TypeLibType(1234)]
public interface SpecialDocument : Document
{
//...
[DispId(1234567890)]
new string Name
{
[MethodImpl(MethodImplOptions.InternalCall)]
[DispId(1234567890)]
[return: MarshalAs(UnmanagedType.BStr)]
get;
[MethodImpl(MethodImplOptions.InternalCall)]
[DispId(1234567890)]
[param: In]
[param: MarshalAs(UnmanagedType.BStr)]
set;
}
//...
[DispId(1234567891)]
new string FullName
{
[MethodImpl(MethodImplOptions.InternalCall)]
[DispId(1234567891)]
[return: MarshalAs(UnmanagedType.BStr)]
get;
}
//...
[DispId(1234567892)]
new bool IsVisible
{
[MethodImpl(MethodImplOptions.InternalCall)]
[DispId(1234567892)]
get;
[MethodImpl(MethodImplOptions.InternalCall)]
[DispId(1234567892)]
[param: In]
set;
}
}
- In the code snippet above, of the 3 properties defined, only Name must be accessed with get_Name or set_Name. The other properties get accessed as one would expect in C#.
- Both Name and FullName are inherited from the parent class Document, defined in NS0, where they have the same definition.
- According to the documentation, all automation interfaces for the product derive from IDispatch.
Edit - Adding repro steps:
- Acquire a license for FancySoft and install the product.
- Start a new .NET 4.8 console project in VS 2022.
- Import COM reference.
- In Main, connect to the running COM server with
Marshal.GetActiveObject("FancySoft.Application"); - Navigate to a SpecialDocument instance, and attempt to read the document's Name property.
- CS1545
Edit - Additional info from the .TLB (extracted with oleview.exe):
// From "dispinterface Document":
[
uuid(AAAAAAAA-BBBB-CCCC-DDDD-111111111111),
helpcontext(0x00001111),
dual
]
dispinterface Document {
properties:
methods:
// ...
[id(0x76543210), propget, helpcontext(0x00001234)]
BSTR Name();
[id(0x76543210), propput, helpcontext(0x00001234)]
void Name([in] BSTR* rhs);
// ...
};
// From "interface Document":
[
odl,
uuid(AAAAAAAA-BBBB-CCCC-DDDD-111111111111),
helpcontext(0x00001111),
dual,
oleautomation
]
interface Document : BaseObject {
// No member description for the 'Name' property.
};
// From "dispinterface BaseObject":
[
uuid(AAAAAAAA-BBBB-CCCC-DDDD-222222222222),
helpcontext(0x00002222),
dual
]
dispinterface BaseObject {
properties:
methods:
// ...
[id(0x76543210), propget, helpcontext(0x00001234)]
BSTR Name();
[id(0x76543210), propput, helpcontext(0x00001234)]
void Name([in] BSTR* rhs);
// ...
};
// From "interface BaseObject":
[
odl,
uuid(AAAAAAAA-BBBB-CCCC-DDDD-222222222222),
helpcontext(0x00002222),
dual,
oleautomation
]
interface BaseObject : BaseDispatch {
// ...
[id(0x76543210), propget, helpcontext(0x00001234)]
HRESULT Name([out, retval] BSTR* oNameBSTR);
[id(0x76543210), propput, helpcontext(0x00001234)]
HRESULT Name([in] BSTR* oNameBSTR);
// ...
};