【问题标题】:sub function not working in HTA子功能在 HTA 中不起作用
【发布时间】:2024-01-20 07:02:01
【问题描述】:

我不知道为什么,但我的子功能不起作用。我以为我已经遵循了它的工作原理,但它只会导致一个错误,声称我的函数未定义。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="x-ua-compatible" content="IE=edge">
<title>Remote Registry</title>
<HTA:APPLICATION
  APPLICATIONNAME="Remote Registry"
  ID="RemReg"
  VERSION="1.0.0.0"
  SCROLL="no"
  SINGLEINSTANCE="yes"
  CONTEXTMENU="no"
  NAVIGABLE="yes"
 SELECTION="no"
/>
<style type="text/css">
body
{
    margin: 0;
    width: 130px;
    height: 180px;
    overflow: hidden;
        font-family: arial;
    font-weight: bold;
    font-size: 12px;
}
</style>
</head>
<SCRIPT LANGUAGE="VBScript">
Sub CheckService
    strComputer = txtBox.value
    Set objWMIService = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    Set colRunningServices = objWMIService.ExecQuery _
        ("Select * from Win32_Service Where Name=""RemoteRegistry""")
    For Each objService in colRunningServices 
    Output = objService.DisplayName  & " is " & objService.State
    Next
End Sub
</script>
<body>
    <input type="text" name="TxTbox" size="30" value=DTP-> Computer to check<br />
    <input id=checkservice type="button" value="Add Button" onClick="CheckService">
    <div id="strComputer"></div>
</body>
</html>

我错过了什么?真的很简单吗?我已经尝试了函数的替代名称,移动到 VBScript 所在的位置。没有任何效果:sRem

【问题讨论】:

  • 其他计算机是否在同一个域中?您的用户名/密码在其他电脑上是否有效?参考:msdn.microsoft.com/en-us/library/windows/desktop/…
  • 是的,在同一个域上,我使用我的用户名和密码对所有其他 PC 具有完全的管理员访问权限 - 我将它作为 VBScript 工作,但希望在运行时自动检查更动态的东西。跨度>
  • 我评论中的上述链接应该为您提供一些示例和如何进行的良好描述。我认为您缺少用户名/密码,但不确定。
  • 谢谢,我会好好看看,但是,我的问题似乎是我的函数未定义,而不是函数的内部代码不起作用,只是当我点击按钮代码不起作用,因为它说“CheckService 未定义”——我假设如果 VBScript 中有错误,它会抛出一个不同的错误。

标签: html vbscript hta


【解决方案1】:

将您的代码更改为以下代码并使用上面的参考链接进行 WMI 调用,您应该没问题。

<!DOCTYPE html>

<html>

<head>
  <meta http-equiv="x-ua-compatible" content="IE=edge" />
  <title>Remote Registry</title>
  <hta:application
    applicationname="Remote Registry"
    id="RemReg"
    version="1.0.0.0"
    scroll="no"
    singleinstance="yes"
    contextmenu="no"
    navigable="yes"
    selection="no"
  />
  <style type="text/css">
    body
    {
      margin: 0;
      width: 130px;
      height: 180px;
      overflow: hidden;
      font-family: arial;
      font-weight: bold;
      font-size: 12px;
    }
  </style>
</head>

<script type="text/vbscript" id="CheckService">
Sub CheckService()
'
dim strComputer
  '
  strComputer = window.document.getElementById("txtComputer").value
  ' PLACE YOUR CALL TO WMI HERE - (I'm not sure mine is correct!)
  'Set objServices = GetObject( _
    "winmgmts:{impersonationLevel=impersonate," _
    & "authenticationLevel=pktPrivacy}!\\" _
    & strcomputer & "/root/cimv2")
  '
  Set colRunningServices = objWMIService.ExecQuery ("Select * from Win32_Service Where Name=" & chr(34) & "RemoteRegistry" & chr(34))
    if colRunningServices.items.count - 1 > 0 Then
      For Each objService in colRunningServices
        window.document.getElementById("Results").innerText = window.document.getElementById("Results").innerText & objService.DisplayName  & " is " & objService.State & chr(13)
      Next
    else
      window.document.getElementById("Results").innerText = "No running services found at this time!"
    end if
  '
End Sub
</script>

<body>
  <input type="text" id="txtComputer" name="txtComputer" size="30" value="Dtp-"/> Computer to check<br />
  <input id="btnCheckService" name="btnCheckService" type="button" value="Add Button" onclick="CheckService" />
  <div id="Results"></div>
</body>
</html>

更新

我已经修改了代码,去掉了 META 标记,并为您添加了一些示例子例程。

我所做的是将 HTA 保存到我的桌面并从那里通过双击执行。

<!DOCTYPE html>
<html>
<head>
  <title>Remote Registry</title>
  <hta:application
    applicationname="Remote Registry"
    id="RemReg"
    version="1.0.0.0"
    scroll="no"
    singleinstance="yes"
    contextmenu="no"
    navigable="yes"
    selection="no"
  />
  <style type="text/css">
    body
    {
      margin: 0;
      width: 130px;
      height: 180px;
      overflow: hidden;
      font-family: arial;
      font-weight: bold;
      font-size: 12px;
    }
  </style>
</head>
<script type="text/vbscript" id="EnumMyServices">
' <!--
Sub EnumMyServices()
  dim WMI, objs, obj
  '
  set WMI = GetObject("WinMgmts:")
  on error resume next
    set objs = WMI.InstancesOf("Win32_Service")
    if err = 0 Then
      if objs.count > 0 then
        window.document.getElementById("Results").innerText = "SERVICES" & chr(13)
        for each obj in objs
          window.document.getElementById("Results").innerText = window.document.getElementById("Results").innerText & obj.Description & chr(13)
        next
      else
        window.document.getElementById("Results").innerText = "SERVICES" & chr(13)
        window.document.getElementById("Results").innerText = "no services found!" & chr(13)
      end if
    else
      window.document.getElementById("Results").innerText = "SERVICES" & chr(13)
      window.document.getElementById("Results").innerText = "An error occurred whilst trying to enum services!" & chr(13)
    end if
    set WMI=nothing
    set objs = nothing
    set obj = nothing
  on error goto 0
end sub
' -->
</script>

<script type="text/vbscript" id="EnumMyPrinters">
' <!--
Sub EnumMyPrinters()
dim WMI, objs, obj
  '
  set WMI = GetObject("WinMgmts:")
  on error resume next
    set objs = WMI.InstancesOf("Win32_Printer")
    if err = 0 Then
      if objs.count > 0 then
        window.document.getElementById("Results").innerText = "PRINTERS" & chr(13)
        for each obj in objs
          window.document.getElementById("Results").innerText = window.document.getElementById("Results").innerText & obj.Description & chr(13)
        next
      else
        window.document.getElementById("Results").innerText = "PRINTERS" & chr(13)
        window.document.getElementById("Results").innerText = "no printers found!" & chr(13)
      end if
    else
      window.document.getElementById("Results").innerText = "PRINTERS" & chr(13)
      window.document.getElementById("Results").innerText = "An error occurred whilst trying to enum printers!" & chr(13)
    end if
    set WMI=nothing
    set objs = nothing
    set obj = nothing
  on error goto 0
end sub
' -->
</script>

<script type="text/vbscript" id="EnumMyProcesses">
' <!--
Sub EnumMyProcesses()
dim WMI, objs, obj
  '
  set WMI = GetObject("WinMgmts:")
  on error resume next
    set objs = WMI.InstancesOf("Win32_Process")
    if err = 0 Then
      if objs.count > 0 then
        window.document.getElementById("Results").innerText = "PROCESSES" & chr(13)
        for each obj in objs
          window.document.getElementById("Results").innerText = window.document.getElementById("Results").innerText & obj.Description & chr(13)
        next
      else
        window.document.getElementById("Results").innerText = "PROCESSES" & chr(13)
        window.document.getElementById("Results").innerText = "no processes found!" & chr(13)
      end if
    else
      window.document.getElementById("Results").innerText = "PROCESSES" & chr(13)
      window.document.getElementById("Results").innerText = "An error occurred whilst trying to enum processes!" & chr(13)
    end if
    set WMI=nothing
    set objs = nothing
    set obj = nothing
  on error goto 0
end sub
' -->
</script>

<script type="text/vbscript" id="EnumMyProcessors">
' <!--
Sub EnumMyProcessors()
dim WMI, objs, obj
  '
  set WMI = GetObject("WinMgmts:")
  on error resume next
    set objs = WMI.InstancesOf("Win32_Processor")
    if err = 0 Then
      if objs.count > 0 then
        window.document.getElementById("Results").innerText = "PROCESSORS" & chr(13)
        for each obj in objs
          window.document.getElementById("Results").innerText = window.document.getElementById("Results").innerText & obj.Description & chr(13)
        next
      else
        window.document.getElementById("Results").innerText = "PROCESSORS" & chr(13)
        window.document.getElementById("Results").innerText = "no processors found!" & chr(13)
      end if
    else
      window.document.getElementById("Results").innerText = "PROCESSORS" & chr(13)
      window.document.getElementById("Results").innerText = "An error occurred whilst trying to enum processors!" & chr(13)
    end if
    set WMI=nothing
    set objs = nothing
    set obj = nothing
  on error goto 0
end sub
' -->
</script>

<body>
  <div id="mycontainer">
    Results:<br />
    <div id="Results"></div>
  </div><br /><br />
  <input id="btnServices" name="btnServices" type="button" value="Services" onclick="EnumMyServices" />
  <input id="btnPrinters" name="btnPrinters" type="button" value="Printers" onclick="EnumMyPrinters" />
  <input id="btnProcesses" name="btnProcesses" type="button" value="Processes" onclick="EnumMyProcesses" />
  <input id="btnProcessors" name="btnProcessors" type="button" value="Processors" onclick="EnumMyProcessors" />
</body>
</html>

【讨论】:

  • 我尝试了很多组合,但似乎无法实现,当我按下按钮时将任何内容输出到窗口。
  • 剥离 SUB 中的所有代码,并用这两行代码替换它来测试它。当您单击按钮时,文本框中的文本应出现在 div 的下方,这将向您显示 HTA 正在工作,其余部分取决于 WMI 调用。第 1 行是 strComputer = window.document.getElementById("txtComputer").value 和第 2 行是- window.document.getElementById("Results").innerText = strComputer
  • 嗯,这很奇怪,它不起作用,窗口中什么也没有显示。所以一定是某处的代码有问题,会检查一下是否变得明显。
  • 使用我在 UPDATED 部分添加的代码,您应该会在文档窗口中看到相关信息,这些信息是本地计算机上的服务、打印机、进程和处理器。这应该可以确保 HTA 中的代码没有问题,问题与您的网络凭据和调用方法以及对远程计算机的访问级别有关。您可以在此链接msdn.microsoft.com/en-us/library/windows/desktop/… 获得更多信息,这些信息完全符合您的要求以及适用于 WMI 远程过程调用的条件
  • 非常感谢,这就像一个魅力,我将使用您给我的代码并修改以使用我需要的东西。非常感谢您的帮助,非常感谢。
【解决方案2】:

使用括号'()'函数定义如下,它解决了你的问题。

子检查服务()

//你的代码

结束子

【讨论】:

  • 其实是onClick=CheckService call中缺少括号导致错误。 定义 中的括号是可选的。应该是 onClick=CheckService()
【解决方案3】:

[子程序名称]未定义”错误发生在 HTA 文档模式为 9 或更高版本并且从 HTML 代码中调用子程序时没有括号。

在这种特殊情况下,代码 onClick="CheckService" 应该是:onClick="CheckService()"

注意这个HTA的文档模式是不明确的,因为它被声明为:

&lt;meta http-equiv="x-ua-compatible" content="IE=edge"&gt;

这会导致 HTA 中的 HTML 代码使用 MSHTML.dll 提供的最高文档模式呈现。 与边缘浏览器无关

在具有 MSHTML 8 或更低版本的机器上测试此 HTA 的人不会看到错误。在任何具有 MSHTML 9 或更高版本的机器上,都会发生该错误。请注意,MSHTML 9 对应于 2011 年发布的 Internet Explorer 9。因此,到 2013 年发布此问题时,大多数机器都会收到发布的脚本错误。

非官方接受的答案通过删除 meta 行消除了错误,导致 HTA 在 IE 7 模式下运行,在调用子例程时不需要括号HTML 代码。在这种情况下,降级 HTA 文档模式可能没有负面影响,但可能会导致 HTML/CSS 代码产生与预期不同的结果。

有关 HTA 文档模式的更多背景信息

HTA 应以特定 文档模式为目标,以确保 HTML/CSS 代码始终按预期工作。 ie=edge 选项应该只由包含不同 MSHTML 版本的多个 HTML 代码部分的专家编码员使用。这现在已经过时了,因为生产中的任何机器都应该有 MSHTML 11,它于 2013 年推出,并且永远不会有任何进一步的升级。 (注意:Windows 11 不包含 Internet Explorer,但包含 MSHTML 11,因此 HTA 仍然有效。)通常,HTA 应以 IE=9、IE=10 或 IE=11 为目标。选择这三种文档模式中的一种有一些特定的原因,但这是另一回事。

HTA 通常应该以这样的代码开头:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" http-equiv="X-UA-Compatible" content="IE=9">
<hta:application id=oHTA>
</head>

如果您的 HTA 没有 DOCTYPEX-UA-Compatible 声明,它将默认以 IE 5 模式运行。如果它只有 DOCTYPE 声明,它将默认在 IE 7 模式下运行。但是,如果 mshta.exeFEATURE_BROWSER_EMULATION 注册表设置,则 默认 模式将是该注册表值中设置的任何内容。

如果您的 HTA 有 X-UA-Compatible 声明,则无论任何注册表设置如何,它都会在该模式下运行(假设机器没有旧版本的 MSHTML),所以要确保包含如上所示的 meta 行(注意:UTF-8 部分是可选的,但有助于使用特殊字符)。

【讨论】:

  • 很好的答案,信息量很大。 +1
【解决方案4】:

服务列表结果的一些基本 HTML 格式使其更易于阅读。

<!DOCTYPE html>
<html>
    <head>
        <title>Remote Registry</title>
        <hta:application
            applicationname="Remote Registry"
            id="RemReg"
            version="1.0.0.0"
            scroll="YES"
            singleinstance="yes"
            contextmenu="no"
            navigable="yes"
            selection="no"
            />
        <style type="text/css">
            body
            {
                margin: 0;
                width: 100%;
                height: 100%;
                overflow: hidden;
                font-family: arial;
                font-weight: bold;
                font-size: 12px;
            }
        </style>
        <script type="text/vbscript" id="EnumMyServices">

            ' <!--
            Sub EnumMyServices()
            dim WMI, objs, obj
            '
            set WMI = GetObject("WinMgmts:")
            on error resume next
            set objs = WMI.InstancesOf("Win32_Service")
            if err = 0 Then
            if objs.count > 0 then
            strHTML="<table border=1 align=left cellpadding=4 cellspacing=0>"
            strHTML=strHTML &  "<tr>"
            strHTML=strHTML &  "<th>DisplayName</th>"
            strHTML=strHTML &  "<th>State</th>"
            strHTML=strHTML &  "<th>StartMode</th>"
            strHTML=strHTML &  "</tr>"
            for each obj in objs
            ObName = obj.DisplayName 
            ObState = obj.State 
            ObStartMode = obj.StartMode 
            strHTML=strHTML &  "<tr>"
            strHTML=strHTML &  "<td>" & ObName & "</td>"
            strHTML=strHTML &  "<td>" & ObState & "</td>"
            strHTML=strHTML &  "<td>" & ObStartMode & "</td>"
            strHTML=strHTML &  "</tr>"
            next
            else
            strHTML="<table border=1 align=left cellpadding=4 cellspacing=0>"
            strHTML=strHTML &  "<tr>"
            strHTML=strHTML &  "<th>Attention</th>"
            strHTML=strHTML &  "</tr>"
            strHTML=strHTML &  "<tr>"
            strHTML=strHTML &  "<td>no services found!</td>"
            strHTML=strHTML &  "</tr>"
            end if
            else
            strHTML="<table border=1 align=left cellpadding=4 cellspacing=0>"
            strHTML=strHTML &  "<tr>"
            strHTML=strHTML &  "<th>Error!</th>"
            strHTML=strHTML &  "</tr>"
            strHTML=strHTML &  "<tr>"
            strHTML=strHTML &  "<td>An error occurred whilst trying to enum services!</td>"
            strHTML=strHTML &  "</tr>"
            end if
            set WMI=nothing
            set objs = nothing
            set obj = nothing
            on error goto 0

            strHTML=strHTML &  "</table>"
            strHTML=strHTML &  "<p>"   
            Results.InnerHTML=strHTML

            end sub
            ' -->
        </script>

        <script type="text/vbscript" id="EnumMyPrinters">
            ' <!--
            Sub EnumMyPrinters()
            dim WMI, objs, obj
            '
            set WMI = GetObject("WinMgmts:")
            on error resume next
            set objs = WMI.InstancesOf("Win32_Printer")
            if err = 0 Then
            if objs.count > 0 then
            window.document.getElementById("Results").innerText = "PRINTERS" & chr(13)
            for each obj in objs
            window.document.getElementById("Results").innerText = window.document.getElementById("Results").innerText & obj.Description & chr(13)
            next
            else
            window.document.getElementById("Results").innerText = "PRINTERS" & chr(13)
            window.document.getElementById("Results").innerText = "no printers found!" & chr(13)
            end if
            else
            window.document.getElementById("Results").innerText = "PRINTERS" & chr(13)
            window.document.getElementById("Results").innerText = "An error occurred whilst trying to enum printers!" & chr(13)
            end if
            set WMI=nothing
            set objs = nothing
            set obj = nothing
            on error goto 0
            end sub
            ' -->
        </script>

        <script type="text/vbscript" id="EnumMyProcesses">
            ' <!--
            Sub EnumMyProcesses()
            dim WMI, objs, obj
            '
            set WMI = GetObject("WinMgmts:")
            on error resume next
            set objs = WMI.InstancesOf("Win32_Process")
            if err = 0 Then
            if objs.count > 0 then
            window.document.getElementById("Results").innerText = "PROCESSES" & chr(13)
            for each obj in objs
            window.document.getElementById("Results").innerText = window.document.getElementById("Results").innerText & obj.Description & chr(13)
            next
            else
            window.document.getElementById("Results").innerText = "PROCESSES" & chr(13)
            window.document.getElementById("Results").innerText = "no processes found!" & chr(13)
            end if
            else
            window.document.getElementById("Results").innerText = "PROCESSES" & chr(13)
            window.document.getElementById("Results").innerText = "An error occurred whilst trying to enum processes!" & chr(13)
            end if
            set WMI=nothing
            set objs = nothing
            set obj = nothing
            on error goto 0
            end sub
            ' -->
        </script>

        <script type="text/vbscript" id="EnumMyProcessors">
            ' <!--
            Sub EnumMyProcessors()
            dim WMI, objs, obj
            '
            set WMI = GetObject("WinMgmts:")
            on error resume next
            set objs = WMI.InstancesOf("Win32_Processor")
            if err = 0 Then
            if objs.count > 0 then
            window.document.getElementById("Results").innerText = "PROCESSORS" & chr(13)
            for each obj in objs
            window.document.getElementById("Results").innerText = window.document.getElementById("Results").innerText & obj.Description & chr(13)
            next
            else
            window.document.getElementById("Results").innerText = "PROCESSORS" & chr(13)
            window.document.getElementById("Results").innerText = "no processors found!" & chr(13)
            end if
            else
            window.document.getElementById("Results").innerText = "PROCESSORS" & chr(13)
            window.document.getElementById("Results").innerText = "An error occurred whilst trying to enum processors!" & chr(13)
            end if
            set WMI=nothing
            set objs = nothing
            set obj = nothing
            on error goto 0
            end sub
            ' -->
        </script>
    </head>

    <body>
        <input id="btnServices" name="btnServices" type="button" value="Services" onclick="EnumMyServices" />
        <input id="btnPrinters" name="btnPrinters" type="button" value="Printers" onclick="EnumMyPrinters" />
        <input id="btnProcesses" name="btnProcesses" type="button" value="Processes" onclick="EnumMyProcesses" />
        <input id="btnProcessors" name="btnProcessors" type="button" value="Processors" onclick="EnumMyProcessors" />
        <p>
        <Font size="3" face="Tahoma"><h3>Results:</Font><hr></h3>
        <div id="Results">&nbsp</div>

    </body>
</html>

【讨论】:

    最近更新 更多