Код VBscript для захвата стандартного вывода без отображения окна консоли - PullRequest
18 голосов
/ 07 февраля 2011

Это пример кода VBScript, который показывает, как перехватить все, что программа командной строки отправляет на стандартный вывод.Он выполняет команду xcopy /? и показывает вывод в окне сообщения.Прежде чем появится окно сообщения, на долю секунды вы увидите всплывающее окно консоли.

Set objShell = WScript.CreateObject("WScript.Shell")
Set objExec = objShell.Exec("xcopy /?")
Do
    line = objExec.StdOut.ReadLine()
    s = s & line & vbcrlf
Loop While Not objExec.Stdout.atEndOfStream
WScript.Echo s

Вот другой пример кода VBScript, который показывает, как выполнить сценарий без отображения окна консоли.

objShell.Run "c:\temp\mybatch.bat C:\WINDOWS\system32\cmd.exe", 0

или

objShell.Run "c:\temp\myscript.vbs C:\WINDOWS\system32\cscript.exe", 0

Как вывидно, что он имеет вид <script><space><executor>.В последнем примере используется objShell.Run вместо objShell.Exec

Чего я не знаю, так это как выполнить программу командной строки (при необходимости из командного файла), перехватить стандартный вывод без отображения консолиокно.Есть идеи?

Ответы [ 7 ]

14 голосов
/ 11 июля 2012

Я обычно использую это:

Wscript.echo execStdOut("ping google.com")

Function execStdOut(cmd)
   Dim goWSH : Set goWSH = CreateObject( "WScript.Shell" ) 
   Dim aRet: Set aRet = goWSH.exec(cmd)
   execStdOut = aRet.StdOut.ReadAll()
End Function 

Для более сложных команд вы можете перейти в comspec (cmd)

my res = execStdOut("%comspec%" & " /c " & """" & "dir /b c:\windows\*.exe" & """" & " && Echo. && Echo finished") 
6 голосов
/ 28 июля 2011

Чтобы перенаправить вывод на консоль, запустите скрипт, используя cscript, например: c:\cscript myscript.vbs.

cscript имеет несколько параметров командной строки. Наиболее важным (для меня) является переключатель // NOLOGO. Если вы используете его (cscript //nologo myscript.vbs), товар Microsoft будет опущен ...

3 голосов
/ 11 февраля 2011

Этот сценарий проверки концепции:

' pocBTicks.vbs - poor man's version of backticks (POC)

Option Explicit

' Globals

Const SW_SHOWMINNOACTIVE =  7
Const ForReading         =  1

Dim goFS  : Set goFS  = CreateObject( "Scripting.FileSystemObject" )
Dim goWSH : Set goWSH = CreateObject( "WScript.Shell" )

' Dispatch
WScript.Quit demoBTicks()

' demoBTicks -
Function demoBTicks()
  demoBTicks = 1
  Dim aCmds : aCmds = Array( _
      "dir pocBTicks.vbs" _
    , "dur pocBTicks.vbs" _
    , "xcopy /?" _
  )
  Dim sCmd
  For Each sCmd In aCmds
      WScript.Echo "########", sCmd
      Dim aRet : aRet = BTicks( sCmd )
      Dim nIdx
      For nIdx = 0 To UBound( aRet )
          WScript.Echo "--------", nIdx
          WScript.Echo aRet( nIdx )
      Next
  Next
  demoBTicks = 0
End Function ' demoBTicks

' BTicks - execute sCmd via WSH.Run
'  aRet( 0 ) : goWSH.Run() result
'  aRet( 1 ) : StdErr / error message
'  aRet( 2 ) : StdOut
'  aRet( 3 ) : command to run
Function BTicks( sCmd )
  Dim aRet    : aRet     = Array( -1, "", "", "" )
  Dim sFSpec2 : sFSpec2  = goFS.GetAbsolutePathName( "." )
  Dim sFSpec1 : sFSpec1  = goFS.BuildPath( sFSpec2, goFS.GetTempName() )
                sFSpec2  = goFS.BuildPath( sFSpec2, goFS.GetTempName() )

  aRet( 3 ) = """%COMSPEC%"" /c """ + sCmd + " 1>""" + sFSpec1 + """ 2>""" +  sFSpec2 + """"""
  Dim aErr
 On Error Resume Next
  aRet( 0 ) = goWSH.Run( aRet( 3 ), SW_SHOWMINNOACTIVE, True )
  aErr      = Array( Err.Number, Err.Description, Err.Source )
 On Error GoTo 0
  If 0 <> aErr( 0 ) Then
     aRet( 0 ) = aErr( 0 )
     aRet( 1 ) = Join( Array( aErr( 1 ), aErr( 2 ), "(BTicks)" ), vbCrLf )
     BTicks    = aRet
     Exit Function
  End If

  Dim nIdx : nIdx = 1
  Dim sFSpec
  For Each sFSpec In Array( sFSpec2, sFSpec1 )
      If goFS.FileExists( sFSpec ) Then
         Dim oFile : Set oFile = goFS.GetFile( sFSpec )
         If 0 < oFile.Size Then
            aRet( nIdx ) = oFile.OpenAsTextStream( ForReading ).ReadAll()
            goFS.DeleteFile sFSpec
         End If
      End If
      nIdx = nIdx + 1
  Next
  BTicks = aRet
End Function

показывает, как использовать .Run и временные файлы, чтобы получить что-то вроде обратных галочек со скрытой консолью.Достойная обработка файлов, цитирование в sCmd, очистка возвращаемых строк и работа с кодировками потребуют больше работы.Но, возможно, вы можете использовать эту стратегию для реализации того, что соответствует вашим потребностям.

1 голос
/ 20 июня 2014

Если вы не возражаете против появления кнопки на панели задач *1001*, вы можете просто переместить окно консоли за пределы экрана перед его запуском.

Если клавиша HKCU\Console\WindowPosition существует, Windows будет использоватьего значение для позиционирования окна консоли.Если ключ не существует, вы получите системное окно.

Итак, сохраните исходное значение этого ключа, установите собственное значение, чтобы расположить его за пределами экрана, вызвать Exec() и захватить еговывод, затем восстановите исходное значение ключа.

Ключ WindowPosition ожидает 32-разрядное значение.Старшее слово - это координата X, а младшее - это координата Y (XXXXYYYY).

With CreateObject("WScript.Shell")

    ' Save the original window position. If system-positioned, this key will not exist.
    On Error Resume Next
    intWindowPos = .RegRead("HKCU\Console\WindowPosition")
    On Error GoTo 0

    ' Set Y coordinate to something crazy...
    .RegWrite "HKCU\Console\WindowPosition", &H1000, "REG_DWORD"

    ' Run Exec() and capture output (already demonstrated by others)...
    .Exec(...)

    ' Restore window position, if previously set. Otherwise, remove key...
    If Len(intWindowPos) > 0 Then
        .RegWrite "HKCU\Console\WindowPosition", intWindowPos, "REG_DWORD"
    Else
        .RegDelete "HKCU\Console\WindowPosition"
    End If

End With

Если вы действительно хотите убедиться, что координаты находятся вне экрана, вы можетеполучить размеры экрана через VBScript с помощью IE или других инструментов.

0 голосов
/ 02 сентября 2018

Это способ, которым вы можете получить командную строку StdOut (результат) без просмотра этого всплывающего окна с черными досками в vbscript:

Set Sh = CreateObject("WScript.Shell")
tFile=Sh.ExpandEnvironmentStrings("%Temp%")&"\t.txt"
Sh.Run "cmd.exe /c xcopy /? > """&tFile&""" ",0,False
Wscript.echo CreateObject("Scripting.FileSystemObject").openTextFile(tFile).readAll()
0 голосов
/ 03 марта 2014

Вместо WScript.Shell рассмотрите возможность использования Win32_Process с startupInfo.ShowWindow = 0 для запуска процесса с SW_HIDE. Я разместил подробный пример в VBS Запустите вывод cmd.exe в переменную; не текстовый файл .

0 голосов
/ 08 февраля 2013

Чтобы вернуть в VBA все подпапки в G: \ OF

sub M_snb()
  c00= createobejct("wscript.Shell").exec("cmd /c Dir G:\OF\*. /s/b").stdout.readall
end sub

, чтобы разбить возвращенную строку на массив

sub M_snb()
  sn=split(createobejct("wscript.Shell").exec("cmd /c Dir G:\OF\*. /s/b").stdout.readall,vbCrLf)

  for j=0 to ubound(sn)
     msgbox sn(j)
  next
End Sub
...