You're always going to get a window flash with Exec()
. You can use Run()
instead to execute the command in a hidden window. But you can't directly capture the command's output with Run()
. You'd have to redirect the output to a temporary file that your VBScript could then open, read, and delete.
For example:
With CreateObject("WScript.Shell")
' Pass 0 as the second parameter to hide the window...
.Run "cmd /c tasklist.exe > c:out.txt", 0, True
End With
' Read the output and remove the file when done...
Dim strOutput
With CreateObject("Scripting.FileSystemObject")
strOutput = .OpenTextFile("c:out.txt").ReadAll()
.DeleteFile "c:out.txt"
End With
The FileSystemObject
class has methods like GetSpecialFolder()
to retrieve the path of Windows temp folder and GetTempName()
to generate a temporary filename that you can use instead of hardcoding an output filename as I've done above.
Also note that you can use the /FO CSV
argument with tasklist.exe
to create a CSV file which should make parsing it much easier.
Finally, there are VBScript "native" ways to retrieve the list of running processes. WMI's Win32_Process
class, for example, can do this without the need for Run/Exec
.
Edit:
For the sake of completeness, I should mention that your script can relaunch itself in a hidden console window where you can run Exec()
silently. Unfortunately, this hidden console window will also hide your output from functions like WScript.Echo()
. Aside from that, however, you probably won't notice any differences running your script under cscript
vs wscript
. Here's an example of this method:
' If running under wscript.exe, relaunch under cscript.exe in a hidden window...
If InStr(1, WScript.FullName, "wscript.exe", vbTextCompare) > 0 Then
With CreateObject("WScript.Shell")
WScript.Quit .Run("cscript.exe """ & WScript.ScriptFullName & """", 0, True)
End With
End If
' "Real" start of script. We can run Exec() hidden now...
Dim strOutput
strOutput = CreateObject("WScript.Shell").Exec("tasklist.exe").StdOut.ReadAll()
' Need to use MsgBox() since WScript.Echo() is sent to hidden console window...
MsgBox strOutput
Of course, if your script expects command-line parameters, those would need to be forwarded when relaunching your script as well.
Edit 2:
Yet another possibility is to use the Windows clipboard. You can pipe the output of your command to the clip.exe
utility. Then, retrieve the text via any number of available COM objects that can access the contents of the clipboard. For example:
' Using a hidden window, pipe the output of the command to the CLIP.EXE utility...
CreateObject("WScript.Shell").Run "cmd /c tasklist.exe | clip", 0, True
' Now read the clipboard text...
Dim strOutput
strOutput = CreateObject("htmlfile").ParentWindow.ClipboardData.GetData("text")