Список методов и свойств объекта объекта
Есть ли способ перечислить доступные методы для созданного объекта в VBS?
Например:
Set IE = CreateObject("InternetExplorer.Application")
Я хочу перечислить доступные свойства этого объекта, например:
IE.AddressBar
IE.Application
IE.Busy
...
или методы:
IE.ClientToWindow
IE.ExecWB
IE.GetProperty
...
Как узнать доступные свойства для произвольного действительного объекта в VBS?
Ответы
Ответ 1
Сам по себе VBScript не поддерживает самоанализ типов вне функций TypeName
и VarType
, которые сообщают вам тип объекта, но не дают доступа к его внутренней структуре.
Как объясняли другие ответы, есть библиотека DLL, которая будет предоставлять эту функцию, но она не поставляется с Windows, и, поскольку она была частью старой версии Visual Studio, в настоящее время не может быть легального способа получить ее.
Ответ 2
Хотя это частично верно, его неполные.... Google, GetObjectText_, Methods_ и Propeties _
Указанные методы будут работать только с объектами, собранными при подключении к пространству имен cimv2 удаленного хоста через объект WbemScripting.SWbemLocator. Если этот объект обладает способностью работать на локальном хосте, он непригоден для меня.
После этого вы можете запросить любой из классов, содержащихся в нем [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
Или...
For Each oMethod in oObject.Methods_
wScript.Echo oProp.Name
Next
Наконец,...
For Each oProp in oObject.Properties_
'This will display all of an objects properties
oProp.GetObjectText_
Next
Ответ 3
Используя TypeLib Information Objects
tlbinf32.dll
из tlbinf32.dll
можно составить список всех членов класса.
tlbinf32.dll
был частью Visual Studio 6.0, которая была текущим выпуском примерно в 2000 году. Кажется, Microsoft больше не предлагает DLL для загрузки (ситуация в середине 2017 года), но вы можете скачать ее с различных сайтов в Интернете.На веб-сайте https://www.dll4free.com/tlbinf32.dll.html или на других сайтах я обнаружил версию 1.1.88.4, сборку 8804, авторские права Мэтью Керланда, 1996, Microsoft 1997-2000, размер 148,480 байт.
Чтобы установить DLL-библиотеку в Win32, скопируйте ее в %windir%\System32
и в качестве администратора вызовите regsvr32.exe tlbinf32.dll
из этого каталога regsvr32.exe tlbinf32.dll
.
Чтобы установить DLL в Win64, скопируйте ее в %windir%\syswow64
, затем в качестве администратора зарегистрируйтесь в %windir%\syswow64\regsvr32.exe
и, наконец, запустите vbscript с %windir%\syswow64\cscript.exe
(или wscript.exe
)Спасибо BuvinJ за подсказку
Следующий скрипт демонстрирует включенную функцию VariableInfo
которая будет возвращать строку с типом переданной переменной, а в случае объекта - все члены с деталями, включая тип Property
, вызываемый тип (Sub
или Function
) и имена параметров и тип возврата в случае функции. Имя типа объекта в случае COM
объекта будет именем реализованного интерфейса. Не уверен, что он работает для нескольких реализованных интерфейсов, но AFAIK в любом случае невозможно реализовать несколько интерфейсов в одном классе через COM
.
Он не поддерживает рекурсию в любом случае, потому что это приведет к бесконечным циклам для некоторых типов.
Это даст вам практически полное рабочее отражение в VBS. Отлично подходит для изучения API, например, с помощью Microsoft Script Debugger.
' 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
Для получения дополнительной информации об интерфейсе Typelib, получите файл справки документации от Microsoft KB artivle 224331
Мэтью Керланд предлагает для загрузки на веб-сайте своей книги Advanced Visual Basic 6 прекрасный редактор типов библиотек программ (EditTLBEval.exe) в качестве ознакомительной версии и соответствующую документацию.
Особенно в этом контексте мне очень нравится строка. Если вы разработчик Visual Basic, который отказывается признавать общепринятые ограничения VB, эта книга определенно для вас.Тед Паттисон.Просто замените VB на VBScript здесь.
VBWebProfi дал подсказку для TLI, спасибо за это. Однако проработка деталей и написание кода заняли несколько часов ;-)
Ответ 4
Если вы используете HP UFT или QTP, выполните следующие действия:
1) Установите любую версию MS Visual Studio на свой ноутбук. (Не беспокойтесь о лицензировании, вы не будете запускать VS)
2) Перезагрузите компьютер.
3) Запустите UFT или QTP, загрузите script и нажмите F11 (или остановитесь на любом фрагменте кода, который находится рядом с объектом, который вы хотите проверить).
4) Добавьте объект в окно просмотра. Это может быть объект репозитория объекта или программное описание.
Если объект существует, объект теперь будет отображать два знака Plus (+) в окне Watch, которые можно развернуть, чтобы показать все доступные методы и свойства, а также дочерние объекты, которые можно развернуть.
Ответ 5
Используйте TLI. Класс TLI.TLIApplication
(из tlbinf32.dll
) может проверять различные COM-объекты из их экземпляра. Изучите библиотеку TLI в Excel или другом продукте Microsoft, который поддерживает сценарии и имеет редактор сценариев, который может добавлять ссылки, а затем добавить tlbinf32.dll
. Название в ссылках "Информация о Typelib".
Обратите внимание, что DLL не поставляется с Windows, хотя.
Используйте метод InterfaceInfoFromObject()
для классов VBScript и, альтернативно, попробуйте ClassInfoFromObject()
.
Option Explicit
Dim TLI
Dim MyObject
Dim TypeInfo
Dim MemberInfo
Set TLI = CreateObject("TLI.TLIApplication")
Set MyObject = New MyClass
Set TypeInfo = TLI.InterfaceInfoFromObject(MyObject)
For Each MemberInfo In TypeInfo.Members
WScript.Echo MemberInfo.Name
Next
Class MyClass
Dim Name_
Public Property Get Name
Name = Name_
End Property
Public Property Let Name(ByVal Value)
Name_ = Value
End Property
End Class
Ответ 6
Попробуйте это...
For i = 0 To webElementCount-1 Step 1
innertextProp = myValue2(i).GetROProperty("innertext")
print i & innertextProp
print innertextProp
Next