列出对象方法和属性

the*_*eta 20 reflection vbscript

有没有办法在VBS中列出已创建对象的可用方法?

例如:

Set IE = CreateObject("InternetExplorer.Application")
Run Code Online (Sandbox Code Playgroud)

我想列出此对象的可用属性,如下所示:

IE.AddressBar
IE.Application
IE.Busy
...
Run Code Online (Sandbox Code Playgroud)

或方法:

IE.ClientToWindow
IE.ExecWB
IE.GetProperty
...
Run Code Online (Sandbox Code Playgroud)

如何在VBS中发现任意有效对象的可用属性?

Ans*_*ers 10

VBScript中本身不支持类型反省外面TypeNameVarType功能,这将给你一个对象的类型,但不会给你访问它的内部结构.

正如其他答案所解释的那样,有一个DLL可以提供这个功能,但它不附带Windows,因为它是旧版Visual Studio的一部分,现在可能没有合法的方法来获取它.

  • 那么Vbsedit,Primalscript等如何根据当前脚本中创建的对象显示自动对象浏览器? (4认同)

小智 10

虽然这部分属实,但其不完整.... Google,GetObjectText_,Methods_,&Propeties_

引用的方法将只收集而连接到经由WbemScripting.SWbemLocator对象的远程主机的cimv2命名空间对象.如果这个对象能够在localhost上工作,那对我来说是不明显的.

执行此操作后,您可以查询其中的任何类[Win32_Services,Win32_Drives等],并使用对象上的For-Next循环查询结果集中的对象,如下所示...

For Each oProp in oObject.Properties_
    'be careful here because some propeties may be an object or an array.
    'so test for that here using "typename" or "vartype"
    wScript.Echo oProp.Name & vbTab & oProp
Next
Run Code Online (Sandbox Code Playgroud)

要么...

For Each oMethod in oObject.Methods_
    wScript.Echo oProp.Name
Next
Run Code Online (Sandbox Code Playgroud)

最后,......

For Each oProp in oObject.Properties_
   'This will display all of an objects properties
   oProp.GetObjectText_
Next
Run Code Online (Sandbox Code Playgroud)

  • 只有[WMI](http://msdn.microsoft.com/en-us/library/windows/desktop/aa394582.aspx)对象支持此功能. (4认同)

tra*_*cki 9

使用TypeLib Information Objectstlbinf32.dll有可能列出一个类的所有成员.

tlbinf32.dllVisual Studio 6.0的一部分,它是2000年左右的当前版本.微软似乎不再提供DLL供下载(2017年中期),但你可以从互联网上的各个站点下载它.我在https://www.dll4free.com/tlbinf32.dll.html或其他网站上找到版本1.1.88.4,Build 8804,版权所有Matthew Curland 1996,Microsoft 1997-2000,大小148.480字节.

要在Win32中安装DLL,请将其复制到该目录%windir%\System32以管理员身份调用regsvr32.exe tlbinf32.dll.

要在Win64中安装DLL,将其复制到%windir%\syswow64,然后以管理员身份注册%windir%\syswow64\regsvr32.exe,最后使用%windir%\syswow64\cscript.exe(或wscript.exe)运行vbscript .谢谢BuvinJ提示

下面的脚本演示了包含函数VariableInfo,它将返回一个带有传递变量类型的字符串,如果是Object,则所有成员都有详细信息,包括类型Property,可调用类型(SubFunction),参数名称和返回类型以防万一功能 在对象的情况下,COM对象的类型名称将是已实现的接口的名称.不确定它是否适用于多个实现的接口,但AFAIK COM无论如何都无法在一个类中实现多个接口.

它不支持任何方式的递归,因为这会导致某些类型的无限循环.

将为您提供VBS中几乎全面的工作反映.非常适合使用Microsoft Script Debugger来探索API .

' Reflection for VBScript via tlbinfo32.dll
'
' Patrick Strasser-Mikhail 2017-2019
' Ansgar Wiechers 2019
' https://stackoverflow.com/questions/14305750/list-object-methods-and-properties/44459670#44459670

Option Explicit

' Returns a String describing the passed object/variable on the first level, no recursion.
Function VariableInfo(obj)
    Const invokeKindPropertyGet = 0
    Const invokeKindFunction = 1
    Const invokeKindPropertyPut = 2
    Const invokeKindPropertyPutRef = 4

    If isEmpty(obj) Or _
       isNull(obj) _
    Then
        VariableInfo = TypeNameFromVarType(VarType(obj))
    ElseIf Not IsObject(obj) Then
        If Not isArray(obj) Then
            VariableInfo = TypeNameFromVarType(VarType(obj)) & ", Value: " & obj
        Else

            VariableInfo = TypeNameFromVarType(VarType(obj)) & "("
            Dim dimension
            Dim size

            On Error Resume Next
            Err.Clear

            For dimension = 1 To 10 ' deliberate limit to prevent infinite loop
                size = Ubound(obj, dimension) + 1
                If Err.Number <> 0 Then
                    Exit For
                End If
                If dimension > 1 Then
                    VariableInfo = VariableInfo & ","
                End If
                VariableInfo = VariableInfo & Ubound(obj, dimension)
            Next

            On Error Goto 0

            VariableInfo = VariableInfo & ")"
        End If
    ElseIf TypeName(obj) = "Nothing" Then
        VariableInfo = "Nothing (The Invalid Object)"
    Else
        Dim TLI
        Dim MemberInfo
        Dim TypeInfo
        Set TLI = CreateObject("TLI.TLIApplication")
        VariableInfo = "Object " & TypeName(obj)

        On Error Resume Next
        Err.Clear
        Set TypeInfo = TLI.InterfaceInfoFromObject(obj)

        If Err.Number <> 0 Then
            VariableInfo = VariableInfo & "; Error " & Err.Number
            VariableInfo = VariableInfo & ": " & Err.Description
            Err.Clear
            Exit Function
        End If

        For Each MemberInfo In TypeInfo.Members
            Dim Desc
            Desc = ""
            Select Case MemberInfo.InvokeKind
                Case InvokeKindFunction
                    If MemberInfo.ReturnType.VarType <> 24 Then
                        Desc = "  Function " & TypeNameFromVarType(MemberInfo.ReturnType.VarType)
                    Else
                        Desc = "  Sub"
                    End If

                    Desc = Desc & " " & MemberInfo.Name
                    Dim ParameterList
                    ParameterList = Array()
                    Dim Parameter
                    For Each Parameter In MemberInfo.Parameters
                        ReDim Preserve parameterList(UBound(ParameterList) + 1)
                        ParameterList(Ubound(parameterList)) = Parameter.Name
                    Next
                    Desc = Desc & "(" & Join(ParameterList, ", ") & ")"
                    'Set parameters = Nothing
                Case InvokeKindPropertyGet
                    Desc = "  Property " & MemberInfo.Name
                Case InvokeKindPropertyPut
                    Desc = "  Property (set/get) " & MemberInfo.Name
                Case InvokeKindPropertyPutRef
                    Desc = "  Property (set ref/get) " & MemberInfo.Name
                Case Else
                    Desc = "  Unknown member, InvokeKind " & MemberInfo.InvokeKind
            End Select
            VariableInfo = VariableInfo & vbNewLine & Desc
        Next

        Set TypeInfo = Nothing
        Set TLI = Nothing
    End If
End Function

' Decode Type Number to something readable
Function TypeNameFromVarType(typeNr)
    Dim typeDetails
    set typeDetails = CreateObject("Scripting.Dictionary")

    typeDetails.add 0,  "vbEmpty (uninitialized variable)"
    typeDetails.add 1,  "vbNull (value unknown)"
    typeDetails.add 2,  "vbInteger" ' Short?
    typeDetails.add 3,  "vbLong" ' Integer?
    typeDetails.add 4,  "vbSingle"
    typeDetails.add 5,  "vbDouble"
    typeDetails.add 6,  "vbCurrency"
    typeDetails.add 7,  "vbDate"
    typeDetails.add 8,  "vbString"
    typeDetails.add 9,  "vbObject"
    typeDetails.add 10, "Exception"
    typeDetails.add 11, "vbBoolean"
    typeDetails.add 12, "vbVariant"
    typeDetails.add 13, "DataObject"
    typeDetails.add 14, "vbDecimal"
    typeDetails.add 17, "vbByte"
    typeDetails.add 18, "vbChar"
    typeDetails.add 19, "ULong"
    typeDetails.add 20, "Long" ' realy Long?
    typeDetails.add 24, "(void)"
    typeDetails.add 36, "UserDefinedType"

    If typeDetails.Exists(typeNr) Then
        TypeNameFromVarType = typeDetails(typeNr)
    ElseIf typeNr > 8192 Then
        TypeNameFromVarType = "vbArray{" & TypeNameFromVarType(typeNr - 8192) & "}"
    Else
        typeNameFromVarType = "Unknown Type " & typeNr
    End If
End Function

' Some nice example class to demonstrate all possible interfaces.
Class MyClass
    Dim Name_
    Dim Name2_

    Public Property Get Name
        Name = Name_
    End Property

    Public Property Let Name(ByVal Value)
      Name_ = Value
    End Property

    Public Property Let Name2(ByRef Value)
      Set Name2_ = Value
    End Property

    Sub TestSub()
        WScript.Echo "Test"
    End Sub

    Sub TestFunc(message)
        WScript.Echo "Test: " & message
    End Sub

    Sub TestFunc2(ByRef message)
        WScript.Echo "Test: " & message
    End Sub

    Function Add(first, second)
        Add = first + second
    End Function

    Function Substract(ByVal first, ByRef second)
        Add = first - second
    End Function
End Class

Sub testVariableInfo()
    Dim variable
    ' vbEmpty
    Wscript.Echo VariableInfo(variable)

    variable = Null
    Wscript.Echo VariableInfo(variable)

    Set variable = Nothing
    Wscript.Echo VariableInfo(variable)

    Dim MyObject
    Set MyObject = new MyClass
    Wscript.Echo VariableInfo(MyObject)
    Set MyObject = Nothing

    Dim TestA1(3, 7)
    Wscript.Echo VariableInfo(TestA1)
    Dim TestA2()
    Wscript.Echo VariableInfo(TestA2)

    Dim TestA3
    TestA3 = Array(4, 5, 6)
    Wscript.Echo VariableInfo(TestA3)
End Sub

testVariableInfo
Run Code Online (Sandbox Code Playgroud)

有关Typelib 接口的更多信息,请从Microsoft KB artivle 224331获取文档帮助文件

Matthew Curland提供在网站上下载他的书Advanced Visual Basic 6的好程序类型库编辑器(EditTLBEval.exe)作为评估版本,以及相应的文档

特别是在这种情况下,我真的很喜欢这行.如果你是一个拒绝承认VB普遍接受的限制的Visual Basic开发人员,这本书绝对适合你.由泰德帕蒂森.这里只需用VBScript替换VB.

VBWebProfi给出了 TLI 的提示,谢谢你.编写细节和编写代码是几个小时的工作,但是;-)

  • 很好的解决方案!但这是一个重要的注意事项:这是一个纯粹的32位机制!在64位操作系统上,您需要将tlbinf32.dll复制到%windir%/ syswow64,然后在%windir%/ syswow64 / regsvr32.exe中注册,最后使用%windir%运行vbscript。 / syswow64 / cscript.exe`(或“ wscript.exe”) (2认同)