InvokeMember给出的结果与直接调用不同

时间:2013-07-10 12:17:54

标签: .net vb.net reflection

我在VB.NET中调用Shell.BrowseForFolder因为我需要在rootFolder参数中传递一个任意路径。所以我实现了这样的目标:

Dim shellType As Type = Type.GetTypeFromProgID("Shell.Application")
Dim shell = Activator.CreateInstance(shellType)

然后我打电话给:

Dim folder = shell.BrowseForFolder(0, message, &H241, rootFolder)

它无法正常工作(根文件夹F:未使用)

Direct call

但是如果我使用相同参数的反射:

Dim folder = shellType.InvokeMember("BrowseForFolder", _
  BindingFlags.InvokeMethod, Nothing, shell, New Object() {0, message, &H241, _
  rootFolder})

有效!

Reflection

但对我来说,2次调用(InvokeMember和直接调用)应该产生类似的结果(参数是相同的)。发生了什么事?

修改

事实上,如果我调用ToString()或者我放了一个litteral:

,它就可以工作
Dim folder = shell.BrowseForFolder(0, message, &H241, rootFolder.ToString())

Dim folder = shell.BrowseForFolder(0, message, &H241, "F:")

但是如果rootFolder是一个参数,它就不起作用,例如:

Function BrowseForFolder(ByVal message As String, ByVal rootFolder As String) As String
    Dim shellType As Type = Type.GetTypeFromProgID("Shell.Application")
    Dim shell = Activator.CreateInstance(shellType)
    Dim folder = shell.BrowseForFolder(0, message, &H241, rootFolder)
    If folder Is Nothing Then
        Return ""
    End If
    Return folder.Self.Path
End Function

2 个答案:

答案 0 :(得分:2)

我使用vs 2012在Windows 7 64位下重现此问题的唯一方法是在该变量中使用无效的rootFolder,如空字符串或废话数据。

你可以在那一行做一个断点:

   Dim folder = shell.BrowseForFolder(0, message, &H241, rootFolder)

并检查rootFolder是什么?

找到了尝试的方法;

  Dim folder = shell.BrowseForFolder(0, message, &H241, rootFolder.ToString())

我的代码:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim rootFolder As Object = "f:"
    Dim shellType As Type = Type.GetTypeFromProgID("Shell.Application")
    Dim shell = Activator.CreateInstance(shellType)
    Dim folder = shell.BrowseForFolder(0, "message", &H241, rootFolder.ToString())
End Sub

答案 1 :(得分:1)

您可以直接使用folderBrowserDialog:

Dim f As New FolderBrowserDialog
f.SelectedPath = "f:"
f.ShowDialog()

虽然我看不到如何将它带到显示F: