Introduction
When I started programming in VBScript, I didn't know the real difference between Run
and Exec
in VBScript
present in the WScript.Shell
object. I'm writing this tip to help you to know when
to use Run
or Exec
and I will show examples that can be implemented
in your code (async command-line
reading is an interesting thing!).
Background
When you need to run an external program that does not have COM
access, you need to call CMD.
This tip pretends to show you the right choice depending on your objective and program you
are calling.
Run
We use Run
when we are calling an external command-line program (or any command that
the prompt recognizes). It can return
%ERRORLEVEL%
and with this code, we can show a message to the user saying if the operation was success or not.
It doesn't support async output, it means that you can't show to the user the output of the external program in real-time,
you need to wait till the program exits. It does not support it because Run()
reads the exit code that is released only when
an external application exits.
Set objShell = CreateObject("WScript.Shell")
strErrorCode = objShell.Run ipconfig,0,True
WScript.Echo strErrorCode
With this, ipconfig will be executed in command prompt. The CMD prompt will not
be shown (0) and our script will wait till the program exits before
it continues
processing (True).
ERRORLEVEL
will be set in
the strErrorCode
variable.
Exec
We can use it to call GUI applications, because then Run
does not call CMD to execute the action.
The principal difference between Exec
and Run
is that
Exec
supports real-time output to the user (if it is a command-line program),
but we can't get ERRORLEVEL
using this method.
If we want to call explorer.exe (or an external program), we just need to call it.
Set objShell = CreateObject("WScript.Shell")
Set objExec = objShell.Exec("explorer.exe")
For async output, we need to call CMD.exe and read the output with VBScript.
Note: Some programs do not support real-time output (WGet and DISM are examples). Use Run
instead.
Set objShell = CreateObject("WScript.Shell")
comspec = objShell.ExpandEnvironmentStrings("%comspec%")
Set objExec = objShell.Exec(comspec & " /c ipconfig")
Do
WScript.StdOut.WriteLine(objExec.StdOut.ReadLine())
Loop While Not objExec.Stdout.atEndOfStream
WScript.StdOut.WriteLine(objExec.StdOut.ReadAll)
We expand the %comspec%
variable (it returns the location of the command-line interpreter of Windows).
If you're running Windows NT, it returns CMD.exe.
For Windows 9x users, command.com will be called. It will call the correct version of CMD.exe depending on the ARCH of your OS.
For example: if you have Windows x64, C:\Windows\system32\cmd.exe (64-bits CMD) will be called, not C:\Windows\SysWow64\cmd.exe (32-bit version).
It is important for DISM, for example, that it fails if we try to modify an image if 32-bit CMD is called on
an x64-bit environment.
After calling the command-line, it will read the output in real-time and write changes on the same window of our script. When the program closes,
VBScript will read all output from the prompt and write it on screen.
History
- 12 Dec 2012: Tip published.