Подтвердить что ты не робот

Код VBscript для захвата stdout, без отображения окна консоли

Это пример кода 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, в котором показано, как выполнить script, не показывая окно консоли.

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.Exec

используется objShell.Run

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

4b9b3361

Ответ 1

Это доказательство понятия script:

' pocBTicks.vbs - poor man 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 и временные файлы, чтобы получить что-то вроде backticks со скрытой консолью. Достойная обработка файлов, цитирование в sCmd, очистка возвращаемых строк и обработка кодировок потребуют больше работы. Но, возможно, вы можете использовать стратегию для реализации того, что соответствует вашим потребностям.

Ответ 2

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

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 

Для более продвинутых команд youc wrap для comspec (cmd)

my res = execStdOut("%comspec%" & " /c " & """" & "dir /b c:\windows\*.exe" & """" & " && Echo. && Echo finished") 

Ответ 3

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

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

Ответ 4

Чтобы вернуть в 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

Ответ 5

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

Если существует клавиша 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 или других инструментов.