14
Set wshShell = WScript.CreateObject ("WSCript.shell")
wshshell.run "runas ..."

How do I get the results and display in a MsgBox

Nilpo
  • 4,675
  • 1
  • 25
  • 39
Cocoa Dev
  • 9,361
  • 31
  • 109
  • 177
  • 1
    Define "results". Runas exit code? Exit code of the application run via runas? The application's console output? – Helen May 20 '11 at 05:49

5 Answers5

28

You will want to use the WshShell object's Exec method instead of Run. Then simply read the command line's output from the standard streams. Try this one:

Const WshFinished = 1
Const WshFailed = 2
strCommand = "ping.exe 127.0.0.1"

Set WshShell = CreateObject("WScript.Shell")
Set WshShellExec = WshShell.Exec(strCommand)

Select Case WshShellExec.Status
   Case WshFinished
       strOutput = WshShellExec.StdOut.ReadAll
   Case WshFailed
       strOutput = WshShellExec.StdErr.ReadAll
End Select

WScript.StdOut.Write strOutput  'write results to the command line
WScript.Echo strOutput          'write results to default output
MsgBox strOutput                'write results in a message box
Nilpo
  • 4,675
  • 1
  • 25
  • 39
  • Would we be able to do the same kind of thing with WshShell.Run? – Feytality Jan 05 '16 at 17:48
  • 1
    No. Run does not provide access to standard streams. – Nilpo Jan 05 '16 at 22:25
  • 2
    Note: This is asynchronous so you will likely see an incorrect `WshShellExec.Status` at `Select Case` – Matt Borja May 25 '16 at 23:12
  • 1
    @MattBorja If you use it as intended, to run command line programs, it will run the command and return an object at completion. However, if you launch a windowed application such as calc.exe, you would need a loop since the command line would return before the program execution ended. In that case, you would simply loop until `WshShellExec.Status <> 0`. – Nilpo May 28 '16 at 09:04
  • @Nilpo, it fails using your own strCommand value. It returns 0 (meaning Running) Fixed at http://stackoverflow.com/questions/32920690/vbscript-capturing-output-from-stdout – ChrisJJ Oct 19 '16 at 22:23
  • @ChrisJJ Please see my previous comment. – Nilpo Oct 20 '16 at 03:40
  • 2
    @Nilpo I had the same issue when running anything. As rdev5 said, `Exec` is asynch, so `WshShellExec.Status` is still 0 (running) at the time you first check it. You need to loop until it's done with something like `While WshShellExec.Status = 0 : WScript.Sleep 50 : Wend` Perhaps consider editing your answer. – BoffinBrain Jul 24 '17 at 14:54
9

This is a modified version of Nilpo's answer that fixes the issue with WshShell.Exec being asynchronous. We do a busy-loop waiting until the shell's status is no longer running, and then we check the output. Change the command-line argument -n 1 to a higher value to make ping take longer, and see that the script will wait longer until completion.

(If anyone has a true asynchronous, event-based solution to the problem, then please let me know!)

Option Explicit

Const WshRunning = 0
Const WshFinished = 1
Const WshFailed = 2

Dim shell : Set shell = CreateObject("WScript.Shell")
Dim exec : Set exec = shell.Exec("ping.exe 127.0.0.1 -n 1 -w 500")

While exec.Status = WshRunning
    WScript.Sleep 50
Wend

Dim output

If exec.Status = WshFailed Then
    output = exec.StdErr.ReadAll
Else
    output = exec.StdOut.ReadAll
End If

WScript.Echo output
BoffinBrain
  • 6,337
  • 6
  • 33
  • 59
3

The solution of BoffinBrain still doesn't work, since exec.Status doesn't return an error level (returns just 0 while running and 1 when finished). For that purpose you must use exec.ExitCode (Returns the exit code set by a script or program run using the Exec() method.). So the solution changes to

Option Explicit

Const WshRunning = 0
' Const WshPassed = 0    ' this line is useless now
Const WshFailed = 1

Dim shell : Set shell = CreateObject("WScript.Shell")
Dim exec : Set exec = shell.Exec("ping.exe 127.0.0.1 -n 1 -w 500")

While exec.Status = WshRunning
    WScript.Sleep 50
Wend

Dim output

If exec.ExitCode = WshFailed Then
    output = exec.StdErr.ReadAll
Else
    output = exec.StdOut.ReadAll
End If

WScript.Echo output
WillyB
  • 31
  • 1
1

I think this makes the most sense. It is WshFinished, not WshFailed. I print the output as it comes, instead of at the end.

Function ExecCommand(cmd)
    Const WshRunning = 0
    Const WshFinished = 1

    Dim objWshShell : Set objWshShell = CreateObject("WScript.Shell")
    Dim oExec : Set oExec = objWshShell.Exec(cmd)

    Do
        Finished = ( oExec.Status = WshFinished )

        While oExec.StdOut.AtEndOfStream <> True
            WScript.StdOut.WriteLine(oExec.StdOut.ReadLine())
        Wend

        While oExec.StdErr.AtEndOfStream <> True
            WScript.StdErr.WriteLine("ERROR: " & oExec.StdErr.ReadLine())

        WScript.StdOut.WriteLine("ExitCode: " & oExec.ExitCode)
        Wend

        WScript.Sleep 100
    Loop Until Finished
End Function

A good example is: ExecCommand "ping.exe 127.0.0.1 -n 3 -w 500"

See error output with: ExecCommand "cmd /c Echo Test Error >&2"

0
var errorlevel = new ActiveXObject('WScript.Shell').Run(command, 0, true)

the third parameter must be true, and errorlevel will be return value, check if it is equal 0.

netawater
  • 15,214
  • 4
  • 24
  • 21