web-dev-qa-db-ja.com

コンソールウィンドウを表示せずに標準出力をキャプチャするVBscriptコード

これは、コマンドラインプログラムが標準出力に送信するものをキャッチする方法を示す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を使用します

コンソールウィンドウを表示せずに、コマンドラインプログラム(バッチファイルから必要な場合)を実行し、標準出力をキャッチする方法はわかりません。何か案は?

18
mgr326639

この概念実証スクリプト:

' 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での引用​​、返された文字列のクリーニング、およびエンコーディングの処理には、より多くの作業が必要になります。しかし、おそらくこの戦略を使用して、ニーズに合ったものを実装できます。

3
Ekkehard.Horner

私は通常これを使用します:

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") 
14
Jakob Sternberg

出力をコンソールにリダイレクトするには、cscriptを使用してスクリプトを実行します。例:c:\cscript myscript.vbs

cscriptにはいくつかのコマンドラインオプションがあります。 (私にとって)最も重要なのは、スイッチ// NOLOGOです。使用する場合(cscript //nologo myscript.vbs)Microsoftの商品は省略されます...

6
Bob Rivers

taskbarボタンが表示されてもかまわない場合は、起動する前にコンソールウィンドウを画面外に移動するだけです。

_HKCU\Console\WindowPosition_キーが存在する場合、Windowsはその値を使用してコンソールウィンドウを配置します。キーが存在しない場合は、システムに配置されたウィンドウが表示されます。

したがって、このキーの元の値を保存し、独自の値を設定して画面外に配置し、Exec()を呼び出して出力をキャプチャしてから、キーの元の値を復元します。

WindowPositionキーには32ビット値が必要です。上位のWordはX座標で、下位のWordは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
_

本当に座標が画面外であることを確認したい場合は、IEまたは他のツールを使用してVBScriptを介して画面のサイズを取得できます。

1
Bond

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
1
snb

これは、vbscriptでこのポップアップの黒いdosウィンドウを表示せずにコマンドラインStdOut(結果)を取得する方法です。

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
hollopost