2011-02-07 10 views
17

これは、コマンドラインプログラムが標準出力に送信するものを捕捉する方法を示すVBScriptのコード例です。 コマンドxcopy /?を実行し、メッセージボックスに出力を表示します。メッセージボックスが表示される前に、スプリット秒間、コンソールウィンドウがポップアップして表示されます。コンソールウィンドウを表示せずにstdoutをキャプチャするVBscriptコード

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 

またはあなたはそれがフォーム<script><space><executor>を持って見ることができるように

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

。 最後の例は、私が知らないことは、コンソールウィンドウを表示せず、(バッチファイルから必要に応じて)、コマンドラインプログラムを実行し、標準出力をキャッチする方法であるobjShell.Run代わりのobjShell.Exec

使用しています。何か案は?

答えて

3

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

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

+0

巧妙な解決策です。一時ファイルについての同情。しかしそれはポイントがあなたのものであるように要件を満たしています。ありがとう、マルセル。 – mgr326639

5

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

cscriptにはいくつかのコマンドラインオプションがあります。最も重要なのは、スイッチ// NOLOGOです。前年比は、それが

13

私は通常、この使用...マイクロソフトの商品を省略します(cscript //nologo myscript.vbsを)それを使用する場合:より高度なコマンドについて

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 

を(CMD)

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

あなたのプログラムが多すぎる(約4KBのIIRC)を出力し、それが隠されていない場合、これはハングすることに注意してください。 –

+0

@CamiloMartinどこから4KB制限を取得していますか?これは 'StdOut.ReadAll()'の制限です。 109KBのファイルで 'StdOut.ReadLine()'をhttp://ss64.com/vb/stdoutread.htmlで問題なく使用しました。私は "隠されていない"観察を確認することができますが、厳密な要件としてOPごとに "隠されたウィンドウ"を求めている人にはこの解決策は理想的ではありません。 – tresf

+0

@QZSupport正直なところ、私はもうほんとうのかわいい手がかりを持っていませんが、おそらく私はそれを試し、何かが4KBの後ろにぶら下がっていて、何かが掛かっていたので他の2人がやってきました。それが実際にうまくいけば、サポートしているすべてのWindowsバージョンでテストしてください。 (また、気づくべきである:それは*非常に可能性があります* 'ReadAll'はすべてをRAMに読み込み、それ自体は非常に醜いでしょう - 私はStdOutをストリーミングする必要があると言いますが、 'ReadLine'はバイナリ出力には良くないでしょう)。 –

0

をCOMSPECためにラップをyouc 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 
+3

-1の場合: 'createobejct'、' cmd'の前に見落としがあり、 "hidden"が指定されていません。 –

-1

代わりのWScript.ShellSW_HIDEでプロセスを起動するstartupInfo.ShowWindow = 0Win32_Processを使用して使用することを検討してください。私はVBS Run cmd.exe output to a variable; not text fileの下に詳細な例を掲載しました。

+0

興味深いコードです。しかし、あなたはまだ一時ファイルに頼っているので、私はこのケースでは本当に利点を見ていません。 – mgr326639

0

タスクバーのボタンが表示されても構わない場合は、起動する前にコンソールウィンドウを画面外に移動することができます。

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 

、あなたは、IEや他のツールを使用してのVBScriptを経由して画面サイズを取得することができます。

関連する問題