【问题标题】:Ping error return always equals 0Ping 错误返回总是等于 0
【发布时间】:2016-06-01 20:28:11
【问题描述】:

无法让此代码正常工作。我可以在 vbscript 中运行脚本(有更改)并且运行良好。但我无法让这个版本返回 0 以外的 ping 错误返回值。感谢任何帮助。

这是扫描带有复选框的远程计算机列表并返回选中的值。我想在继续之前运行 ping 以验证远程机器是否存在。但是对于所有查询都返回 0 的错误是没有用的。

function statuschk3(){
var checkedValue = null; 
var inputElements = document.getElementsByName("comp");
for(var i=0; inputElements[i]; ++i){
  if(inputElements[i].checked)
  {checkedValue = inputElements[i].value;
var WshShell = new ActiveXObject("WScript.Shell");
var status = WshShell.run ("ping -n 1 -a"  + checkedValue + ",0 ,true");
    if(status == 0)
    {   var fso = new ActiveXObject("Scripting.FileSystemObject");
        var s = fso.OpenTextFile("C:/script/testfile1.txt", 8, true);
        s.WriteLine(checkedValue + " is turned off or off the domain");
        s.Close();
    } 
    else` 

【问题讨论】:

标签: jscript hta


【解决方案1】:

这是我用来测试连接性的函数。我使用了这个的 vbscript 版本,但我用 javascript 重写了它。

function Reachable(strComputer) 
{
    var wmiQuery = "Select * From Win32_PingStatus Where Address = '" + strComputer + "'";
    var objWMIService = GetObject("winmgmts://./root/cimv2");
    var colItems = objWMIService.ExecQuery(wmiQuery);
    var enumItems = new Enumerator(colItems)
    for (; !enumItems.atEnd(); enumItems.moveNext())
    {
        var objStatus = enumItems.item();
        if ((objStatus.StatusCode == null) || (objStatus.Statuscode != 0))
        {
            return false //if computer is unreachable, return false
        }
        else
        {
            return true //'if computer is reachable, return true
        }
    }
}

用法:

vbscript:
If Reachable(strComputer) Then MsgBox "Online" Else MsgBox "Offline"

javascript:
if (Reachable(strComputer)) { alert("Online") } else { alert("Offline") }

编辑:

如果你想调整这个的超时时间,你可以在这一行添加以下内容:

var wmiQuery = "Select * From Win32_PingStatus Where Address = '" + strComputer + "' and Timeout=500";

其中 500 是 500 毫秒。

这里有更多关于 Win32_PingStatus 类的信息,其中表示默认超时为 1000 毫秒。

另一个编辑来解决你原来的问题:

您的原始代码似乎存在一些语法问题:

var status = WshShell.run ("ping -n 1 -a"  + checkedValue + ",0 ,true");

需要

var status = WshShell.run ("ping -n 1 -a "  + checkedValue, 0,true);

注意a后面的空格和checkedValue后面的引号

此外,逻辑是倒退的。 if(status==0) 则设备在线。

【讨论】:

  • 感谢您的帮助,是的,我在提交问题后注意到引号的问题。一旦我改变了猜测,它就开始起作用了……它总是盯着你的脸,让你发疯。 : ) :) 以及我遇到的逻辑错误,因为我仍在测试它。谢谢。
  • 如果您只是测试连接性,您确定需要-a 开关吗?
【解决方案2】:

就其价值而言,如果 langstrom 的 WMI 解决方案有效,我认为我更喜欢它而不是我自己的解决方案。我回答的目的是帮助您找出您的脚本出了什么问题。

首先,ping.exe 可以从网关收到错误响应,说“没有到主机的路由”或类似的。但是收到响应(错误与否)后,退出状态为 0。最好检查命令的输出以获取有效响应以确定成功/失败。

但更直接的问题是shellObj.run() 正在异步分叉 ping 进程。它是非阻塞的。

使用shellObj.exec() 可以解决这两个问题。下面是一个使用控制台 JScript 的示例:

// returns 0 for success, non-zero for fail
function ping(host) {

    var osh = WSH.CreateObject('Wscript.Shell'),
        proc = osh.exec('ping -n 1 ' + host);

    while (!proc.Status) WSH.Sleep(25);
    return !/\btime\b/i.test(proc.StdOut.ReadAll());
}

不幸的是,由于浏览器/HTA JScript 不理解WSHSleep,您必须创造性地使用setInterval 阻止直到ping 可执行文件完成。 (这就是为什么 langstrom 的 WMI 解决方案比生成可执行文件更可取。尝试将非阻塞命令破解成阻塞的东西对于 HTA JScript 来说既麻烦又尴尬。)

// alerts true on success, false on fail
function ping(host) {

    var osh = new ActiveXObject('Wscript.Shell'),
        proc = osh.exec('ping -n 1 ' + host),
        waitForExit = setInterval(function() {
            if (proc.Status) {
                clearInterval(waitForExit);
                alert(/\btime\b/i.test(proc.StdOut.ReadAll()));
            }
        }, 25);
}

ping('localhost');

【讨论】:

    猜你喜欢
    • 2017-03-21
    • 1970-01-01
    • 2019-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-13
    • 2015-09-27
    相关资源
    最近更新 更多