Answered by:
VB.Net Reflection Method Invoke returns null

Question
-
User-1962621908 posted
I need to access few private methods and members in the Microsoft.VisualStudio.Data.Tools.Package.dll . I did the following coding. everything works fine until the last code line.
Dim dte As EnvDTE.DTE Dim configuration As EnvDTE.Configuration Dim projectConfigProperties As Microsoft.VisualStudio.Data.Tools.Package.Project.Internal.ProjectConfigProperties ' Get the Assembly info Dim name As AssemblyName = New AssemblyName() name.CodeBase = "file://C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\Extensions\Microsoft\SQLDB\Microsoft.VisualStudio.Data.Tools.Package.dll" Dim dbProjectType As Type = assembly.GetType("Microsoft.VisualStudio.Data.Tools.Package.Project.DatabaseProjectPropertyValueType", True, True) ' Retrieve the enum info from the assembly Dim fields As FieldInfo() = dbProjectType.GetFields((BindingFlags.Public Or BindingFlags.Static Or BindingFlags.NonPublic)) Dim databaseProjectConfig As Microsoft.VisualStudio.Data.Tools.Package.Project.DatabaseProjectConfig configuration = project.ConfigurationManager.ActiveConfiguration projectConfigProperties = CType(configuration.Object, Microsoft.VisualStudio.Data.Tools.Package.Project.Internal.ProjectConfigProperties) projectConfigObject = projectConfigProperties.GetType().GetProperty("ProjectConfig", System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Instance).GetValue(projectConfigProperties) databaseProjectConfig = CType(projectConfigObject, Microsoft.VisualStudio.Data.Tools.Package.Project.DatabaseProjectConfig) Dim types As Type() = New Type() {GetType(String), GetType(Boolean), dbProjectType} ' Get method info Dim myMethod As MethodInfo = databaseProjectConfig.GetType().GetMethod("GetConfigurationProperty", BindingFlags.NonPublic Or BindingFlags.Instance, Nothing, types, Nothing) ' Invoke the method Dim val = myMethod.Invoke(projectConfigObject, New Object() {"SqlCommandVariablesFile", False, fields(0).GetValue(Nothing)})
The myMethod populates correctly. But when I try to invoke it, the val is always getting a null value. It would be great if someone can tell me where I went wrong.
Thursday, January 5, 2017 3:56 AM
Answers
-
User-1962621908 posted
Hi,
I found the route cause in this problem when we are Invoking a method through reflection, we need to pass-in the exact matching param types in the Invoke method. That is why it was returned as null. After I passed in the exact same param types the method returned successfully.
Following is the code I used and it worked.
Setting up the type properties.
Dim fields As FieldInfo() = dbProjectType.GetFields((BindingFlags.Public Or BindingFlags.Static Or BindingFlags.NonPublic)) '' Get Internal enum DatabaseProjectEventPropagation using reflection Dim dbeventPropagationType As Type = assembly.GetType("Microsoft.VisualStudio.Data.Tools.Package.Project.DatabaseProjectEventPropagation", True, True) Dim dbEventPropgationFields As FieldInfo() = dbeventPropagationType.GetFields((BindingFlags.Public Or BindingFlags.Static Or BindingFlags.NonPublic)) Dim readTypes As Type() = New Type() {GetType(String), GetType(Boolean), dbProjectType} Dim writeTypes As Type() = New Type() {GetType(String), GetType(String), dbeventPropagationType, GetType(Microsoft.VisualStudio.Shell.Interop._PersistStorageType)}
Define the methods that we need to access via reflection
projectConfigProperties = CType(configuration.Object, Microsoft.VisualStudio.Data.Tools.Package.Project.Internal.ProjectConfigProperties) projectConfigObject = projectConfigProperties.GetType().GetProperty("ProjectConfig", System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Instance).GetValue(projectConfigProperties) databaseProjectConfig = CType(projectConfigObject, Microsoft.VisualStudio.Data.Tools.Package.Project.DatabaseProjectConfig) Dim getPropertyMethod As MethodInfo = databaseProjectConfig.GetType().GetMethod("GetConfigurationProperty", BindingFlags.NonPublic Or BindingFlags.Instance, Nothing, readTypes, Nothing) Dim setPropertyMethod As MethodInfo = databaseProjectConfig.GetType().GetMethod("SetConfigurationProperty", BindingFlags.NonPublic Or BindingFlags.Instance, Nothing, writeTypes, Nothing)
Invoking methods
Dim val = getPropertyMethod.Invoke(projectConfigObject, New Object() {"AnsiNulls", False, fields(0).GetValue(Nothing)}) setPropertyMethod.Invoke(projectConfigObject, New Object() {"AnsiNulls", "False", dbEventPropgationFields(0).GetValue(Nothing), Microsoft.VisualStudio.Shell.Interop._PersistStorageType.PST_PROJECT_FILE})
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Monday, January 16, 2017 10:07 PM
All replies
-
User-271186128 posted
Hi priyalwalpita,
projectConfigObject = projectConfigProperties.GetType().GetProperty("ProjectConfig", System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Instance).GetValue(projectConfigProperties) Dim val = myMethod.Invoke(projectConfigObject, New Object() {"SqlCommandVariablesFile", False, fields(0).GetValue(Nothing)})
According to your code, it seems that you are invoke the property, instead of the methods. Please set a break point to check whether you set value for this property.
More details about using reflection, please refer to the following code:
Imports System Imports System.Reflection Public Class MagicClass Private magicBaseValue As Integer Public Sub New() magicBaseValue = 9 End Sub Public Function ItsMagic(preMagic As Integer) As Integer Return preMagic * magicBaseValue End Function End Class Public Class TestMethodInfo Public Shared Sub Main() ' Get the constructor and create an instance of MagicClass Dim magicType As Type = Type.GetType("MagicClass") Dim magicConstructor As ConstructorInfo = magicType.GetConstructor(Type.EmptyTypes) Dim magicClassObject As Object = magicConstructor.Invoke(New Object(){}) ' Get the ItsMagic method and invoke with a parameter value of 100 Dim magicMethod As MethodInfo = magicType.GetMethod("ItsMagic") Dim magicValue As Object = magicMethod.Invoke(magicClassObject, New Object(){100}) Console.WriteLine("MethodInfo.Invoke() Example" + vbNewLine) Console.WriteLine("MagicClass.ItsMagic() returned: {0}", magicValue) End Sub End Class
When invoke the method, you could also set a break point in the method to check the return data.
More details, see: https://msdn.microsoft.com/en-us/library/a89hcwhh(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2
Best regards,
DillionFriday, January 6, 2017 10:04 AM -
User-1962621908 posted
Hi,
I found the route cause in this problem when we are Invoking a method through reflection, we need to pass-in the exact matching param types in the Invoke method. That is why it was returned as null. After I passed in the exact same param types the method returned successfully.
Following is the code I used and it worked.
Setting up the type properties.
Dim fields As FieldInfo() = dbProjectType.GetFields((BindingFlags.Public Or BindingFlags.Static Or BindingFlags.NonPublic)) '' Get Internal enum DatabaseProjectEventPropagation using reflection Dim dbeventPropagationType As Type = assembly.GetType("Microsoft.VisualStudio.Data.Tools.Package.Project.DatabaseProjectEventPropagation", True, True) Dim dbEventPropgationFields As FieldInfo() = dbeventPropagationType.GetFields((BindingFlags.Public Or BindingFlags.Static Or BindingFlags.NonPublic)) Dim readTypes As Type() = New Type() {GetType(String), GetType(Boolean), dbProjectType} Dim writeTypes As Type() = New Type() {GetType(String), GetType(String), dbeventPropagationType, GetType(Microsoft.VisualStudio.Shell.Interop._PersistStorageType)}
Define the methods that we need to access via reflection
projectConfigProperties = CType(configuration.Object, Microsoft.VisualStudio.Data.Tools.Package.Project.Internal.ProjectConfigProperties) projectConfigObject = projectConfigProperties.GetType().GetProperty("ProjectConfig", System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Instance).GetValue(projectConfigProperties) databaseProjectConfig = CType(projectConfigObject, Microsoft.VisualStudio.Data.Tools.Package.Project.DatabaseProjectConfig) Dim getPropertyMethod As MethodInfo = databaseProjectConfig.GetType().GetMethod("GetConfigurationProperty", BindingFlags.NonPublic Or BindingFlags.Instance, Nothing, readTypes, Nothing) Dim setPropertyMethod As MethodInfo = databaseProjectConfig.GetType().GetMethod("SetConfigurationProperty", BindingFlags.NonPublic Or BindingFlags.Instance, Nothing, writeTypes, Nothing)
Invoking methods
Dim val = getPropertyMethod.Invoke(projectConfigObject, New Object() {"AnsiNulls", False, fields(0).GetValue(Nothing)}) setPropertyMethod.Invoke(projectConfigObject, New Object() {"AnsiNulls", "False", dbEventPropgationFields(0).GetValue(Nothing), Microsoft.VisualStudio.Shell.Interop._PersistStorageType.PST_PROJECT_FILE})
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Monday, January 16, 2017 10:07 PM