I am able to retrieve it from a COM object via Reflection and run it with the MethodInfo.Invoke method.
However, I am trying to create a Delegate to be faster because I will use it in a loop. Unfortunately, I couldn't find a solution to the error message below. How can I create a delegate for a COM method?
"Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type."
My Delegate:
Public Delegate Function GetDriveNameDelegate(path As String) As String
My test Button:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim fsoType As Type = Type.GetTypeFromProgID("Scripting.FileSystemObject")
Dim fsoInstance As Object = Activator.CreateInstance(fsoType)
'Dim result As Type
#Region " This is working... "
'Dim dispatch As IDispatchInfo = fsoInstance
'dispatch.GetTypeInfo(0, 0, result)
'Dim mi As MethodInfo = result.GetMethod("GetDriveName")
'Dim param = New Object() {"C:\Windows"}
'MessageBox.Show(mi.Invoke(fsoInstance, param))
#End Region
#Region " This is not working... "
Dim fsoDelegate As GetDriveNameDelegate = GetDelegateFromCOM(fsoInstance, "GetDriveName")
MessageBox.Show(fsoDelegate.Invoke("C:\Windows"))
#End Region
End Sub
My Delegate creator function:
Public Function GetDelegateFromCOM(comObj As Object, methodName As String) As GetDriveNameDelegate
Dim result As Type
CType(comObj, IDispatchInfo).GetTypeInfo(0, 0, result)
Dim mi As MethodInfo = result.GetMethod(methodName)
Return [Delegate].CreateDelegate(GetType(GetDriveNameDelegate), mi, True)
End Function
The IDispatch Interface:
<ComImport>
<InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
<Guid("00020400-0000-0000-C000-000000000046")>
Public Interface IDispatchInfo
''' <summary>
''' Gets the number of Types that the object provides (0 or 1).
''' </summary>
''' <param name="typeInfoCount">Returns 0 or 1 for the number of Types provided by <see cref="GetTypeInfo"/>.</param>
''' <remarks>
''' http://msdn.microsoft.com/en-us/library/da876d53-cb8a-465c-a43e-c0eb272e2a12(VS.85)
''' </remarks>
<PreserveSig>
Function GetTypeInfoCount(ByRef typeInfoCount As Integer) As Integer
''' <summary>
''' Gets the Type information for an object if <see cref="GetTypeInfoCount"/> returned 1.
''' </summary>
''' <param name="typeInfoIndex">Must be 0.</param>
''' <param name="lcid">Typically, LOCALE_SYSTEM_DEFAULT (2048).</param>
''' <param name="typeInfo">Returns the object's Type information.</param>
''' <remarks>
''' http://msdn.microsoft.com/en-us/library/cc1ec9aa-6c40-4e70-819c-a7c6dd6b8c99(VS.85)
''' </remarks>
Sub GetTypeInfo(typeInfoIndex As Integer, lcid As Integer, <MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef:=GetType(TypeToTypeInfoMarshaler))> ByRef typeInfo As Type)
''' <summary>
''' Gets the DISPID of the specified member name.
''' </summary>
''' <param name="riid">Must be IID_NULL. Pass a copy of Guid.Empty.</param>
''' <param name="name">The name of the member to look up.</param>
''' <param name="nameCount">Must be 1.</param>
''' <param name="lcid">Typically, LOCALE_SYSTEM_DEFAULT (2048).</param>
''' <param name="dispId">If a member with the requested <paramref name="name"/>
''' is found, this returns its DISPID and the method's return value is 0.
''' If the method returns a non-zero value, then this parameter's output value is
''' undefined.</param>
''' <returns>Zero for success. Non-zero for failure.</returns>
''' <remarks>
''' http://msdn.microsoft.com/en-us/library/6f6cf233-3481-436e-8d6a-51f93bf91619(VS.85)
''' </remarks>
<PreserveSig>
Function GetDispId(ByRef riid As Guid, ByRef name As String, nameCount As Integer, lcid As Integer, ByRef dispId As Integer) As Integer
' NOTE: The real IDispatch also has an Invoke method next, but we don't need it.
' We can invoke methods using .NET's Type.InvokeMember method with the special
' [DISPID=n] syntax for member "names", or we can get a .NET Type using GetTypeInfo
' and invoke methods on that through reflection.
' Type.InvokeMember: http://msdn.microsoft.com/en-us/library/de3dhzwy.aspx
End Interface
Aucun commentaire:
Enregistrer un commentaire