Cyb*_*aco 7 vbscript excel vba hta identification
编辑:到目前为止,大多数响应都涉及检查可能不存在的对象,这些对象在使用Option Explicit on的VBA中完全不起作用(它会抛出编译时错误,因此On Error不起作用,并且关闭Option Explicit不是一个选项).还有其他一些环形/开箱即用的方法来找出这里需要什么吗?
我正在尝试编写通用的复制粘贴代码,这些代码可以在独立的VBScript(.vbs文件),.hta文件和VBA(例如,在Excel文件中)中使用.要做到这一点,我需要一些方法让代码本身告诉它运行的引擎.
到目前为止我听到的最好的想法是测试某些对象是否存在,但在VBA中,在编译时失败(因此我无法绕过On Error),因此无法解决问题.试图找出它运行的文件的名称并不是最终可行的; 根据代码运行的三个脚本引擎中的哪一个,这是不同的事情之一.我希望有这样简单的东西,但我不确定要填写什么:
Option Explicit
'--- Returns a string containing which script engine this is running in,
'--- either "VBScript", "VBA", or "HTA".
Function ScriptEngine()
If {what goes here?} Then ScriptEngine="VBS"
If {what goes here?} Then ScriptEngine="VBA"
If {what goes here?} Then ScriptEngine="HTA"
End Function
Run Code Online (Sandbox Code Playgroud)
如果填写正确,您应该能够将该功能复制并粘贴到任何VBA,VBS或HTA文件中而无需修改,调用它,并获得结果而不是错误,即使启用了Option Explicit也是如此.最好的方法是什么?
Option ExplicitVBA实施中对要求的限制使得这比其他情况要困难得多(没有它就是单线)......具有讽刺意味的是,它也是解决方案的关键.如果你不限制自己只使用一个函数,你可以通过这样做来逃避它:
Dim hta
Sub window_onload()
hta = True
End Sub
Function HostType()
On Error Resume Next
If hta Then
HostType = "HTA"
Else
Dim foo
Set foo = foo
If Err.Number = 13 Then
HostType = "VBA"
Else
HostType = "VBS"
End If
End If
End Function
Run Code Online (Sandbox Code Playgroud)
它的工作方式如下 - 如果它是通过HTA文件加载的,则window_onload事件处理程序运行,将hta变量设置为True.这是第一次测试.第二个"测试"是关于线路抛出的错误Set foo = foo.这是在VBA中,它被理解为试图类型不匹配Set一Variant来Empty,这是不兼容的类型.同一行代码在VBScript中抛出错误424(需要对象),因为它不是强类型语言.这意味着跳过VBA的类型检查,它会尝试实际执行分配(失败).其余的只是弄清楚它是如何投掷并返回结果的.
VBA
Option Explicit
Dim hta
Sub Test()
Debug.Print HostType 'VBA
End Sub
Sub window_onload()
hta = True
End Sub
Function HostType()
On Error Resume Next
If hta Then
HostType = "HTA"
Else
Dim foo
Set foo = foo
If Err.Number = 13 Then
HostType = "VBA"
Else
HostType = "VBS"
End If
End If
End Function
Run Code Online (Sandbox Code Playgroud)
VBScript中
WSCript.Echo HostType
Dim hta
Sub window_onload()
hta = True
End Sub
Function HostType()
On Error Resume Next
If hta Then
HostType = "HTA"
Else
Dim foo
Set foo = foo
If Err.Number = 13 Then
HostType = "VBA"
Else
HostType = "VBS"
End If
End If
End Function
Run Code Online (Sandbox Code Playgroud)
HTA
<HTML>
<BODY>
<script type="text/vbscript">
Dim hta
Sub Test()
MsgBox HostType
End Sub
Sub window_onload()
hta = True
End Sub
Function HostType()
On Error Resume Next
If hta Then
HostType = "HTA"
Else
Dim foo
Set foo = foo
If Err.Number = 13 Then
HostType = "VBA"
Else
HostType = "VBS"
End If
End If
End Function
</script>
<button onclick="vbscript:Test()">Click me</button>
</BODY>
</HTML>
Run Code Online (Sandbox Code Playgroud)
编辑:
如果Option Explicit不需要FWIW,上面提到的单线程就是这样:
Function HostString()
HostString = Application & document & WScript
End Function
Run Code Online (Sandbox Code Playgroud)
所有三个对象都有一个返回a的默认属性String.在VBScript中,这将返回"Windows Script Host".在VBA中,它将返回主机的名称(即Excel中的"Microsoft Excel").在HTA中它将返回"[object]".
虽然我同意@this,但这里是我的Option Explicit-safe 方法,没有On Error使用Window_OnLoadHTA 侦听器的语句(就像Comintern那样)和行标签技巧来区分 VBScript 和 VBA。
Dim IsInHTA, IsInVBScript
Sub Window_Onload()
IsInHTA = True
End Sub
Sub LineLabelTest()
'VBA and VB6 (maybe VB5 too, IDK) treats "DummyLabel:" as a line label
'VBScript treats "DummyLabel" as an expression to call and treats ":" as a statement separator.
DummyLabel:
End Sub
Sub DummyLabel()
'this is called by the LineLabelTest subroutine only in VBScript
IsInVBScript = True
End Sub
Function HostType()
LineLabelTest
If IsInVBScript Then
If IsInHTA Then
HostType = "HTA"
Else
HostType = "VBS" 'Other hosts incuding WSH, ASP, Custom
End If
Else
HostType = "VBA" 'VBA or VB6 (maybe VB5 too, don't know)
End If
End Function
Run Code Online (Sandbox Code Playgroud)
Noo*_*les -1
Application所有程序都有一个至少提供全局对象的主机。WScript 提供了全局WScript、Word/ExcelApplication对象、HTA 和 IE Window 对象(通过父属性可以访问InternetExplorer.Application对象的访问)。
在 COM 中,我们在 IUnknown 接口上调用 QueryRef 来查找它拥有哪些对象。这发生在幕后。原则是您尝试使用它并查找表示属性 E_Not_Implemented 的错误。
这是应用程序对象中应包含的内容的标准https://learn.microsoft.com/en-au/previous-versions/windows/desktop/automat/using-the-application-object-in-a-type-图书馆
所以wscript.name、InternetExplorer.Application.Name、 和Word.Application.Name。
在 Wscript 中,此代码打印Windows Scripting Host. 在Word 中打印Normal 424 Object Required。在 HTA 中Microsoft VBScript runtime error 424 Object required。
On Error Resume Next
x = wscript.name
If err.Number = 0 then
Msgbox x
Else
Msgbox err.source & " " & err.number & " " & err.description
End If
Run Code Online (Sandbox Code Playgroud)
在 Word Microsoft Word、VBSMicrosoft VBScript runtime error 424 Object required和 HTA中也是如此Microsoft VBScript runtime error 424 Object required。
On Error Resume Next
x = Application.Name
If Err.Number = 0 Then
MsgBox x
Else
MsgBox Err.Source & " " & Err.Number & " " & Err.Description
End If
Run Code Online (Sandbox Code Playgroud)
另请注意,对应用程序是否已定义的测试并不稳健。Excel 还有一个 Application 对象。您必须测试name.
| 归档时间: |
|
| 查看次数: |
571 次 |
| 最近记录: |