- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
有没有办法列出 VBS 中创建的对象的可用方法?
例如:
Set IE = CreateObject("InternetExplorer.Application")
IE.AddressBar
IE.Application
IE.Busy
...
IE.ClientToWindow
IE.ExecWB
IE.GetProperty
...
最佳答案
使用 TypeLib Information Objects
中的 tlbinf32.dll
可以列出类的所有成员。
`tlbinf32.dll` 是 *Visual Studio 6.0* 的一部分,它是 2000 年左右的当前版本。Microsoft 似乎不再提供 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\运行 vbscript cscript.exe`(或`wscript.exe`)。感谢 [BuvinJ](/users/3220983/buvinj) 的 [提示](/questions/14305750/list-object-methods-and-properties/44459670?noredirect=1#comment86169321_44459670)
以下脚本演示了包含的函数 VariableInfo
,它将返回一个字符串,其中包含传递变量的类型,如果是 Object,则返回所有成员的详细信息,包括 Property
的类型、可调用类型(Sub
或 Function
)以及参数名称和函数的返回类型。如果是 COM
对象,对象的类型名称将是已实现接口(interface)的名称。不确定它是否适用于多个实现的接口(interface),但 AFAIK 无论如何都不可能通过 COM
在一个类中实现多个接口(interface)。
它不以任何方式支持递归,因为这会导致某些类型的无限循环。
这个 会给你 在 VBS 中几乎完全工作的 反射 。非常适合探索 API,例如使用 Microsoft Script Debugger。
' Reflection for VBScript via tlbinfo32.dll
'
' Patrick Strasser-Mikhail 2017-2021
' Ansgar Wiechers 2019
' https://stackoverflow.com/questions/14305750/list-object-methods-and-properties/44459670#44459670
'
' v1.1 2021-02-01: Show values of arrays and objects, but only one level
' Returns a String describing the passed object/variable on the first level,
' no recursion.
Function VariableInfo(obj)
VariableInfo = VariableInfoToLevel(obj, 0, 1)
End Function
' Returns a String describing the passed object/variable on the first level,
' recurse down to level max_level(0=no recursion).
Function VariableInfoToLevel(obj, level, max_level)
Const invokeKindPropertyGet = 0 ' simple data member
Const invokeKindFunction = 1 ' method: Sub or Function
Const invokeKindPropertyPut = 2 ' Docs: has a value setter; reality: more like is settable
Const invokeKindPropertyPutRef = 4 ' Docs: has a reference setter; reality: more like is not settable
If level > max_level Then
VariableInfoToLevel = ""
Exit Function
End If
Dim indent : indent = Space(4 * level)
VariableInfoToLevel = indent
If isEmpty(obj) Or _
isNull(obj) _
Then
VariableInfoToLevel = VariableInfoToLevel & TypeNameFromVarType(VarType(obj))
ElseIf Not IsObject(obj) Then
If Not isArray(obj) Then
VariableInfoToLevel = indent & TypeNameFromVarType(VarType(obj)) & ", Value: [" & obj & "]"
Else
VariableInfoToLevel = indent & TypeNameFromVarType(VarType(obj))
Dim dimension
ReDim sizes(0)
Dim size
On Error Resume Next
Err.Clear
For dimension = 0 To 10 ' deliberate limit to prevent infinite loop
size = Ubound(obj, dimension + 1)
If Err.Number <> 0 Then
' report ther then Index out of Bounds
If Err.Number <> 9 Then
WScript.Echo "Exception " & Err.Number & ": " & Err.Description & "; in " & Err.Source
End If
Exit For
End If
ReDim Preserve sizes(dimension)
sizes(dimension) = size
Next
On Error Goto 0
VariableInfoToLevel = VariableInfoToLevel & "(" & Join(sizes, ",") & ")"
Select Case dimension
Case 1
VariableInfoToLevel = VariableInfoToLevel & " {" & vbCrlf
Dim idx
For idx = LBound(obj) To UBound(obj)
VariableInfoToLevel = VariableInfoToLevel & indent & _
" " & idx & ":" & _
Trim(VariableInfoToLevel(obj(idx), level + 1, max_level)) & vbCrlf
Next
VariableInfoToLevel = VariableInfoToLevel & indent & "}" & vbCrlf
Case 2
VariableInfoToLevel = indent & "{" & vbCrlf
Dim idx1, idx2
For idx1 = LBound(obj, 1) To UBound(obj, 1)
For idx2 = LBound(obj, 2) To UBound(obj, 2)
VariableInfoToLevel = VariableInfoToLevel & indent & _
" " & idx1 & "," & idx2 & ":" & _
Trim(VariableInfoToLevel(obj(idx1, idx2), level + 1, max_level)) & vbCrlf
Next
Next
VariableInfoToLevel = VariableInfoToLevel & indent & " }" & vbCrlf
Case Else
' 0 is empty anyway, more is too complicated to print, just leave it for now
End Select
End If
ElseIf TypeName(obj) = "Nothing" Then
VariableInfoToLevel = indent & "Nothing (The Invalid Object)"
Else
' Object
VariableInfoToLevel = indent & "Object " & TypeName(obj)
'' Need to think about that... True for Err, but not for System.Dictionary
'' Seems Err is very special, and we should compare explicitly with internal/predifined Objects (Err, WScript)
'If varType(obj) <> vbObject Then
' hm, interresting...
' VariableInfoToLevel = VariableInfoToLevel & " with default property (no analysis possible)"
' Exit Function
'End If
Dim TLI
Dim MemberInfo
Dim TypeInfo
Set TLI = CreateObject("TLI.TLIApplication")
VariableInfoToLevel = indent & "Object " & TypeName(obj)
On Error Resume Next
Err.Clear
Set TypeInfo = TLI.InterfaceInfoFromObject(obj)
If Err.Number <> 0 Then
VariableInfoToLevel = VariableInfoToLevel & "; Error " & Err.Number
VariableInfoToLevel = VariableInfoToLevel & ": " & Err.Description
Err.Clear
On Error Goto 0
Exit Function
End If
On Error Goto 0
For Each MemberInfo In TypeInfo.Members
Dim Desc
Dim printNextLevel : printNextLevel = vbFalse
Desc = ""
' based on .Net System.Runtime.IteropService.ComTypes
'' FIXME: Call by Value/Reference and settable seems to be switched some
'' InvokeKind seems to not encode value passing, rather settable/not settable
'' Needs more work to decode byValue/byReference
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 = " Data Member " & MemberInfo.Name
printNextLevel = vbTrue
Case InvokeKindPropertyPut
' Seems to be
Desc = " Property " & MemberInfo.Name & " [set by val"
If IsGettable(obj, MemberInfo.Name) Then
Desc = Desc & "/get"
printNextLevel = vbTrue
End If
Desc = Desc & "]"
'Stop
Case InvokeKindPropertyPutRef
'Stop
Desc = " Property " & MemberInfo.Name & " [set by ref"
If IsGettable(obj, MemberInfo.Name) Then
Desc = Desc & "/get"
printNextLevel = vbTrue
End If
Desc = Desc & "]"
'Stop
Case Else
Desc = " Unknown member, InvokeKind " & MemberInfo.InvokeKind
End Select
VariableInfoToLevel = VariableInfoToLevel & vbNewLine & _
indent & Desc
If printNextLevel And level < max_level Then
VariableInfoToLevel = VariableInfoToLevel & vbNewLine & _
VariableInfoToLevel(eval("obj." & MemberInfo.Name), level + 1, max_level)
End If
Next
Set TypeInfo = Nothing
Set TLI = Nothing
End If
End Function
Function IsGettable(obj, memberName)
Dim value
On Error Resume Next
Err.Clear
value = eval("obj." & memberName)
Stop
If Err.Number <> 0 And _
Err.Number <> 438 And _
Err.Number <> 450 Then
WScript.Echo Err.Number & ": " & Err.Description
End If
'438: Object doesn't support this property or method
'450: Wrong number of arguments or invalid property assignment
If Err.Number = 438 Or _
Err.Number = 450 Then
IsGettable = vbFalse
Else
IsGettable = vbTrue
End If
End Function
Function IsSimpleType(obj)
If (isEmpty(obj) Or isNull(obj)) And (Not IsObject(obj)) And (Not isArray(obj)) Then
IsSimpleType = vbTrue
Else
IsSimpleType = vbFalse
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_
Dim Name3_
Dim Name4_
Dim dict
Private Sub Class_Initialize()
Name_ = "foo"
Name2_ = "bar"
Name3_ = "baz"
Name4_ = "spam"
Set dict = CreateObject("Scripting.Dictionary")
End Sub
Private Sub Class_Terminate()
Set dict = Nothing
End Sub
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
Public Property Get Name3
Name3 = Name3_
End Property
Public Property Set Name3(ByVal Value)
Set Name3_ = Value
End Property
Public Property Get Name4
Name4 = Name4_
End Property
Public Property Set Name4(ByRef Value)
Set Name4_ = 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)
Wscript.Echo VariableInfo(Int(23))
Wscript.Echo VariableInfo(cLng(23))
Wscript.Echo VariableInfo(2147483647)
Wscript.Echo VariableInfo(5/4)
Wscript.Echo VariableInfo(4 * Atn(1)) ' Simplest way to pi, not all inverse functions like arcsin are defined.
Wscript.Echo VariableInfo(3.4E38)
Wscript.Echo VariableInfo(CDbl(3.4E38))
Wscript.Echo VariableInfo(cCur(20.123456))
Wscript.Echo VariableInfo(now)
Wscript.Echo VariableInfo("Some Text")
Wscript.Echo VariableInfo(Err)
Dim MyObject
Set MyObject = new MyClass
Wscript.Echo VariableInfo(MyObject)
Set MyObject = Nothing
Dim TestAEmpty()
Wscript.Echo VariableInfo(TestAEmpty)
ReDim TestA1(17)
Wscript.Echo VariableInfo(TestA1)
Dim TestA2(3, 7)
Wscript.Echo VariableInfo(TestA2)
Dim TestA3
TestA3 = Array(4, 5, 6)
Wscript.Echo VariableInfo(TestA3)
Dim dict
Set dict = CreateObject("Scripting.Dictionary")
WScript.Echo VariableInfo(dict)
Set dict = Nothing
End Sub
testVariableInfo
有关 Typelib 接口(interface)的更多信息,请从
Microsoft KB artivle 224331 获取文档帮助文件
关于reflection - 列出对象方法和属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14305750/
如何从单个输入字段中的逗号分隔值输出列表(无论是作为单个值还是作为数组)? 示例 用户在文本输入字段中输入以下内容:Steve、Bruce、Matt、Natasha、Peter 结果: 史蒂夫 布鲁斯
如何列出与 Jena 中的实例关联的所有对象属性? 例如:Person 有一个名为“hasVehicle”的对象属性,它与类 Vehicle 相关联 最佳答案 合适的 Jena 方法是 OntClas
如何列出与 Jena 中的实例关联的所有对象属性? 例如:Person 有一个名为“hasVehicle”的对象属性,它与类 Vehicle 相关联 最佳答案 合适的 Jena 方法是 OntClas
我知道 Python 是一种动态语言,但下面的代码让我很困扰。 我有下面的简单程序,它有一些辅助函数来包装命令执行。 EventLoaderToVerticaHelper 是一个有两个方法的辅助类,所
我有以下代码 public void saveProjects(List proj) throws DatabaseException { for (Project listItems: pr
我有一个列表,其中元素是: struct element { double priority; int value;
我看到对于 pull 请求的提交,根据文档最大限制为 250:List commits on a Pull Request如果 pull 请求超过 250 次提交,则建议使用另一个端点:List Co
我是 django 的新手,我想列出一个 django 项目的应用程序,例如: FeinCMS 我知道 startapp 会为应用程序创建目录结构。请问有没有函数或者文件可以获取应用列表。 以Fein
你能列出所有在 Hibernate 框架中使用的设计模式吗? 我了解一些设计模式,如 DAO、ORM 等。 如果可能的话,一些例子。 最佳答案 Hibernate 中使用的设计模式: 领域模型模式——
我正在尝试在终端中使用 psql 来查找数据库中所有可为空的列。如果我使用 select * from information_schema.check_constraints; 我得到如下信息 c
您可以使用以下步骤列出 WSO2 碳基产品使用的所有管理服务。 使用 OSGI 控制台启动服务器。转至 /bin 使用命令 shell 。 i) 例如:Linux sh wso2server.s
我想列出数据库中的所有表名。我的应用程序必须独立于 DBMS。不同的 DBMS 有不同的命令来列出表,例如: PstgreSQL: SELECT * FROM pg_catalog.pg_table
主要是为了我自己的启发,我试图列出当前 Emacs session 中加载的所有全局变量。我正在考虑做的是生成一个包含所有列出的功能的 HTML 文件。当然,定义函数、var 等的文件也很有用。 em
我如何定义 lists:append具有列表理解功能? 我想要类似的东西 1> append([[1, 2, 3], [a, b], [4, 5, 6]]). [1,2,3,a,b,4,5,6] 最佳
使用以下 Powershell 代码段,我可以获取当前用户的组成员名称: $groups = [System.Security.Principal.WindowsIdentity]::GetCurre
如何列出 Docker 容器的所有卷?我知道它应该很容易获得,但我找不到方法。 另外,是否可以获取已删除容器的卷并将其删除? 最佳答案 您可以使用 docker ps,获取容器 ID 并写入: $ d
来自微软独库: The "\\.\" prefix will access the Win32 device namespace instead of the Win32 file namespace
这个问题在这里已经有了答案: 9年前关闭。 Possible Duplicate: Finding all Namespaces in an assembly using Reflection (Do
是否有命令行选项可以列出您的 Cucumber 测试套件中的所有标签? 例如,我想要这样的东西: cucumber --show-tags foo.feature 那会给我类似的东西: @ci @de
有没有一种快速的方法来列出为数据库定义的所有实际上没有被任何字段使用的 Firebird 域?我有一个包含许多表和许多域的大型数据库,似乎其中很多不再使用,所以我想是时候进行清理了! 我认为这可以通过
我是一名优秀的程序员,十分优秀!