使用VbScript静默运行命令行并获取输出?

40

我希望能够通过命令行运行程序,并用VbScript启动它。我还想获取命令行的输出并将其赋值给一个变量,而且我希望所有这些都可以在没有弹出cmd窗口的情况下静默完成。我已经分别完成了两件事情,但是没有一起完成过。以下是我目前所拥有的内容。 从cmd中运行命令并获取输出:

Dim WshShell, oExec
Set WshShell = WScript.CreateObject("WScript.Shell")
Set oExec = WshShell.Exec("C:\snmpget -c public -v 2c 10.1.1.2 .1.3.6.1.4.1.6798.3.1.1.1.5.1")
x = oExec.StdOut.ReadLine
Wscript.Echo x

上面的脚本可以正常运行,但是命令提示符会短暂地弹出。下面是一个可以静默运行但无法获取输出的脚本。
Set WshShell = WScript.CreateObject("WScript.Shell")
Return = WshShell.Run("C:\snmpset -c public -v 2c -t 0 10.1.1.2 .1.3.6.1.4.1.6798.3.1.1.1.7.1 i 1", 0, true)

有没有办法让这两者相互配合?

让我给你讲一下我为什么想这样做的背景。我基本上每5-10分钟轮询一个单位,当满足一定条件时,我将通过脚本发送电子邮件或弹出消息框,但我不想整天看到命令行在我的电脑上弹出。有什么建议吗? 谢谢


可能是这个问题的重复:VBscript代码以捕获stdout,而不显示控制台窗口 - phuclv
7个回答

40

你可以将输出重定向到一个文件,然后读取该文件:

return = WshShell.Run("cmd /c C:\snmpset -c ... > c:\temp\output.txt", 0, true)

Set fso  = CreateObject("Scripting.FileSystemObject")
Set file = fso.OpenTextFile("c:\temp\output.txt", 1)
text = file.ReadAll
file.Close

还可以看一下我之前问过的类似问题:https://dev59.com/wW445IYBdhLWcg3wUote - mgr326639

10

我已经采取了这个和其他评论,并创建了一个更高级的函数来运行应用程序并获取输出。

调用函数的示例:仅以目录方式输出C:\的DIR列表。输出将返回到变量CommandResults中,并保留在C:\OUTPUT.TXT中。

CommandResults = vFn_Sys_Run_CommandOutput("CMD.EXE /C DIR C:\ /AD",1,1,"C:\OUTPUT.TXT",0,1)

函数

Function vFn_Sys_Run_CommandOutput (Command, Wait, Show, OutToFile, DeleteOutput, NoQuotes)
'Run Command similar to the command prompt, for Wait use 1 or 0. Output returned and
'stored in a file.
'Command = The command line instruction you wish to run.
'Wait = 1/0; 1 will wait for the command to finish before continuing.
'Show = 1/0; 1 will show for the command window.
'OutToFile = The file you wish to have the output recorded to.
'DeleteOutput = 1/0; 1 deletes the output file. Output is still returned to variable.
'NoQuotes = 1/0; 1 will skip wrapping the command with quotes, some commands wont work
'                if you wrap them in quotes.
'----------------------------------------------------------------------------------------
  On Error Resume Next
  'On Error Goto 0
    Set f_objShell = CreateObject("Wscript.Shell")
    Set f_objFso = CreateObject("Scripting.FileSystemObject")
    Const ForReading = 1, ForWriting = 2, ForAppending = 8
      'VARIABLES
        If OutToFile = "" Then OutToFile = "TEMP.TXT"
        tCommand = Command
        If Left(Command,1)<>"""" And NoQuotes <> 1 Then tCommand = """" & Command & """"
        tOutToFile = OutToFile
        If Left(OutToFile,1)<>"""" Then tOutToFile = """" & OutToFile & """"
        If Wait = 1 Then tWait = True
        If Wait <> 1 Then tWait = False
        If Show = 1 Then tShow = 1
        If Show <> 1 Then tShow = 0
      'RUN PROGRAM
        f_objShell.Run tCommand & ">" & tOutToFile, tShow, tWait
      'READ OUTPUT FOR RETURN
        Set f_objFile = f_objFso.OpenTextFile(OutToFile, 1)
          tMyOutput = f_objFile.ReadAll
          f_objFile.Close
          Set f_objFile = Nothing
      'DELETE FILE AND FINISH FUNCTION
        If DeleteOutput = 1 Then
          Set f_objFile = f_objFso.GetFile(OutToFile)
            f_objFile.Delete
            Set f_objFile = Nothing
          End If
        vFn_Sys_Run_CommandOutput = tMyOutput
        If Err.Number <> 0 Then vFn_Sys_Run_CommandOutput = "<0>"
        Err.Clear
        On Error Goto 0
      Set f_objFile = Nothing
      Set f_objShell = Nothing
  End Function

非常感谢您的分享。今天让我的生活变得非常轻松。 - Matt H

3

我是一个新手,但我发现如果通过CScript.exe(控制台脚本宿主)启动脚本,则在执行()时不会弹出窗口:因此,在运行时:

cscript myscript.vbs //nologo

myscript.vbs中的任何.Exec()调用都不会打开额外的窗口,这意味着您可以使用原始解决方案的第一种变体(使用exec)。

(请注意,上面代码中的两个斜杠是有意的,请参见cscript /?)


1

这里我找到了一个解决方案,对我很有效:

set wso = CreateObject("Wscript.Shell")
set exe = wso.Exec("cmd /c dir /s /b d:\temp\*.jpg")
sout = exe.StdOut.ReadAll

0

在你的第一个脚本中,尝试将输出分配到剪贴板,然后在第二个脚本中解析剪贴板的值。


-1

@Mark Cidade

谢谢Mark!这解决了我几天的研究,我一直在想如何从PHP WshShell中调用它。所以感谢你的代码,我明白了...

function __exec($tmppath, $cmd)
{
   $WshShell = new COM("WScript.Shell");
   $tmpf = rand(1000, 9999).".tmp"; // Temp file
   $tmpfp = $tmppath.'/'.$tmpf; // Full path to tmp file

   $oExec = $WshShell->Run("cmd /c $cmd -c ... > ".$tmpfp, 0, true);

   // return $oExec == 0 ? true : false; // Return True False after exec
   return $tmpf;
}

这是在我的情况下有效的方法。根据您的需求,随意使用和修改。您可以在函数内部添加功能,自动读取临时文件,将其赋值给变量和/或返回它,然后删除临时文件。 再次感谢 @Mark!


-1
Dim path As String = GetFolderPath(SpecialFolder.ApplicationData)
 Dim filepath As String = path + "\" + "your.bat"
    ' Create the file if it does not exist. 
    If File.Exists(filepath) = False Then
        File.Create(filepath)
    Else
    End If
    Dim attributes As FileAttributes
    attributes = File.GetAttributes(filepath)
    If (attributes And FileAttributes.ReadOnly) = FileAttributes.ReadOnly Then
        ' Remove from Readonly the file.
        attributes = RemoveAttribute(attributes, FileAttributes.ReadOnly)
        File.SetAttributes(filepath, attributes)
        Console.WriteLine("The {0} file is no longer RO.", filepath)
    Else
    End If
    If (attributes And FileAttributes.Hidden) = FileAttributes.Hidden Then
        ' Show the file.
        attributes = RemoveAttribute(attributes, FileAttributes.Hidden)
        File.SetAttributes(filepath, attributes)
        Console.WriteLine("The {0} file is no longer Hidden.", filepath)
    Else
    End If
    Dim sr As New StreamReader(filepath)
    Dim input As String = sr.ReadToEnd()
    sr.Close()
    Dim output As String = "@echo off"
    Dim output1 As String = vbNewLine + "your 1st cmd code"
    Dim output2 As String = vbNewLine + "your 2nd cmd code "
    Dim output3 As String = vbNewLine + "exit"
    Dim sw As New StreamWriter(filepath)
    sw.Write(output)
    sw.Write(output1)
    sw.Write(output2)
    sw.Write(output3)
    sw.Close()
    If (attributes And FileAttributes.Hidden) = FileAttributes.Hidden Then
    Else
        ' Hide the file.
        File.SetAttributes(filepath, File.GetAttributes(filepath) Or FileAttributes.Hidden)
        Console.WriteLine("The {0} file is now hidden.", filepath)
    End If
    Dim procInfo As New ProcessStartInfo(path + "\" + "your.bat")
    procInfo.WindowStyle = ProcessWindowStyle.Minimized
    procInfo.WindowStyle = ProcessWindowStyle.Hidden
    procInfo.CreateNoWindow = True
    procInfo.FileName = path + "\" + "your.bat"
    procInfo.Verb = "runas"
    Process.Start(procInfo)

它将保存你的 .bat 文件到“当前用户的Appdata”中,如果不存在则删除属性, 然后在编写cmd代码后将“隐藏”属性设置为文件, 并静默运行并捕获所有输出保存到文件中, 所以如果你想将cmd的所有输出保存到文件中,只需添加你的命令。

code > C:\Users\Lenovo\Desktop\output.txt

只需将单词“code”替换为您的.bat文件代码或命令,然后是输出文件的目录。 最近我在搜索中找到了一个代码 如果您想在vb或c#中运行.bat文件,或者只是简单地运行 只需按照我编写的方式添加即可


我知道,但它确实保存了所有执行的输出 :) - Aditya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接