I use this snippet in vbscript:
Set WSH = CreateObject("WScript.Shell")
cmd = "some command"
flag = WSH.Run(cmd, 0, true)
As it can be noticed, in .Run() call, "WaitOnReturn" is set to "true" as I want to know when external program finishes and additionally it status
Problem is that external program needs some time to finish and I want to pop "Please wait..." MsgBox but I can't this way as I set "WaitOnReturn" on "true" which I need as I need result from that program for additional processing
Is there a way I can show somehow this MsgBox while external program is executed?
Sorry, it slipped to me that i can call MsgBox just before executing, Run()
:embarrassed:
Edit:
for no user interaction here is one workaround (taken from http://www.robvanderwoude.com/vbstech_ui_progress.php)
Function ProgressMsg( strMessage, strWindowTitle )
' Written by Denis St-Pierre
Set wshShell = WScript.CreateObject( "WScript.Shell" )
strTEMP = wshShell.ExpandEnvironmentStrings( "%TEMP%" )
If strMessage = "" Then
On Error Resume Next
objProgressMsg.Terminate( )
On Error Goto 0
Exit Function
End If
Set objFSO = CreateObject("Scripting.FileSystemObject")
strTempVBS = strTEMP + "\" & "Message.vbs"
Set objTempMessage = objFSO.CreateTextFile( strTempVBS, True )
objTempMessage.WriteLine( "MsgBox""" & strMessage & """, 4096, """ & strWindowTitle & """" )
objTempMessage.Close
On Error Resume Next
objProgressMsg.Terminate( )
On Error Goto 0
Set objProgressMsg = WshShell.Exec( "%windir%\system32\wscript.exe " & strTempVBS )
Set wshShell = Nothing
Set objFSO = Nothing
End Function
Then call it with:
ProgressMsg "Installing, Please wait.", "Some title"
end terminate it with:
ProgressMsg "", "Some title"
I was given an answer on another blog, basically, all I had to do was dim the variable "ProgressMsg" globally.
Thanks
Related
Every time I need to grant user access to a file share on our server, I get numerous occurrences of this popup because the process hits various files whose access rights I can't modify:
This isn't a problem, but I got tired of having to repeatedly stop what I was working on to click on the "Continue" button. So, I wrote a program to continually scan for an "Error Applying Security" window, and whenever it found one, send it an "Enter" keypress. This worked well enough, but since the central loop never terminates, I decided to add the ability to end the program when it was finished. I could have used an .hta file, but I decided to try a different approach that kept everything in a single file to make future maintenance easier. I adopted the code from this Stack Overflow question to find my program's PID and allow the program to be ended using the Windows TASKKILL command after a popup was closed.
The program seems to work correctly, identifying its PID and passing it to the popup. However, when TASKKILL runs, it claims the PID doesn't exist. Can anyone see what I'm doing wrong? Thanks in advance to all who respond.
' AutoContinue.vbs
' Program to automatically close all "Error Applying Security" messages
Option Explicit
Const Hidden = 0
Dim objWshShell, objWMILocator, objWMIService
Dim strComputerName, objArgs, objChildProcess, colPIDs, objPID
Set objWshShell = CreateObject( "WScript.Shell" )
Set objWMILocator = CreateObject( "WBemScripting.SWbemLocator" )
Set objWMIService = objWMILocator.ConnectServer( "", "", "", "" )
Function MyProcessID ()
' MyProcessID finds and returns my own PID.
MyProcessID = 0
Set objChildProcess = objWshShell.Exec( "%comspec% /C pause" )
Set colPIDs= objWMIService.ExecQuery( "Select * From Win32_Process" & _
" Where ProcessId=" & objChildProcess.ProcessID,, 0 )
For Each objPID In colPIDs
MyProcessID = objPID.ParentProcessID
Next
Call objChildProcess.Terminate()
End Function
Set objArgs = WScript.Arguments
If objArgs.Count = 1 Then
If objArgs.Item(0) = "Popup" Then
objWshShell.Popup( "AutoContinue PID is " & MyProcessID & _
vbCrLf & "Hit OK when done." )
' objWshShell.Run "taskkill /PID " & MyProcessID & " /T", 1
objWshShell.Run "%comspec% /k taskkill /PID " & MyProcessID & " /T", 1
Set objArgs = Nothing
Set objWshShell = Nothing
WScript.Quit
End If
End If
objWshShell.Run "wscript.exe " & WScript.ScriptName & " Popup", Hidden
Do
Do
WScript.Sleep( 500 )
Loop While Not objWshShell.AppActivate( "Error Applying Security" )
WScript.Sleep( 100 )
objWshShell.AppActivate( "Error Applying Security" )
WScript.Sleep( 100 )
objWshShell.SendKeys( "{ENTER}" )
Loop While True
Set objWshShell = Nothing
The script identifies its own PID correctly. However, you are trying to kill itself (the script instance with supplied Popup argument) while you need to kill the script instance without it (or with another 1st argument?).
The following solution could help: supply PID of the instance to kill as 2nd argument (see variable iPid) along with the Popup one…
' AutoContinue.vbs
' Program to automatically close all "Error Applying Security" messages
Option Explicit
Const Hidden = 0
Dim objWshShell, objWMILocator, objWMIService
Dim strComputerName, objArgs, objChildProcess, colPIDs, objPID
Set objWshShell = CreateObject( "WScript.Shell" )
Set objWMILocator = CreateObject( "WBemScripting.SWbemLocator" )
Set objWMIService = objWMILocator.ConnectServer( "", "", "", "" )
Function MyProcessID ()
' MyProcessID finds and returns my own PID.
MyProcessID = 0
Set objChildProcess = objWshShell.Exec( "%comspec% /C pause" )
Set colPIDs= objWMIService.ExecQuery( "Select * From Win32_Process" & _
" Where ProcessId=" & objChildProcess.ProcessID,, 0 )
For Each objPID In colPIDs
MyProcessID = objPID.ParentProcessID
Next
Call objChildProcess.Terminate()
End Function
Dim iPid
iPid = MyProcessID()
Set objArgs = WScript.Arguments
If objArgs.Count >= 2 Then
If objArgs.Item(0) = "Popup" Then
objWshShell.Popup( "AutoContinue PID is " & objArgs.Item(1) & _
vbCrLf & "Hit OK when done." )
' objWshShell.Run "taskkill /PID " & objArgs.Item(1) & " /T /F", 1
objWshShell.Run "%comspec% /k taskkill /PID " & objArgs.Item(1) & " /T /F", 1
Set objArgs = Nothing
Set objWshShell = Nothing
WScript.Quit
End If
End If
objWshShell.Run "wscript.exe """ _
& WScript.ScriptFullName & """ Popup " & CStr( iPid) , Hidden
'' ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ two arguments
Do
Do
WScript.Sleep( 500 )
Loop While Not objWshShell.AppActivate( "Error Applying Security" )
WScript.Sleep( 100 )
objWshShell.AppActivate( "Error Applying Security" )
WScript.Sleep( 100 )
objWshShell.SendKeys( "{ENTER}" )
Loop While True
How Can I pause speak command in vbscript? I have to play it from the same paused position.
Code block:
Dim Speak, Path
Path = "string"
Path = "C:\Users\sony\Desktop\TheReunion.txt"
const ForReading = 1
Set objFileToRead = CreateObject("Scripting.FileSystemObject").OpenTextFile(Path,ForReading)
strFileText = objFileToRead.ReadAll()
Set Speak=CreateObject("sapi.spvoice")
Speak.Speak strFileText
objFileToRead.Close
Set objFileToRead = Nothing
You need to call the speak method asynchronously before using the pause and resume methods as mentioned by LotPings in the comments.
Code:
Dim Speak, Path
Path = "string"
Path = "C:\Users\sony\Desktop\TheReunion.txt"
const ForReading = 1
Set objFileToRead = CreateObject("Scripting.FileSystemObject").OpenTextFile(Path,ForReading)
strFileText = objFileToRead.ReadAll()
Set Speak=CreateObject("sapi.spvoice")
Speak.Speak strFileText,1 '1=Asynchronous. Click the link below for other possible values "SpeechVoiceSpeakFlags"
'Due to async call to speak method, we can proceed with the code execution while the voice is being played in the background. Now we can call pause and resume methods
wscript.sleep 5000 'voice played for 5000ms
Speak.pause 'paused
wscript.sleep 4000 'remains paused for 4000ms
Speak.resume 'resumes
objFileToRead.Close
Set objFileToRead = Nothing
SpeechVoiceSpeakFlags
Intrigue in this led me to take inspiration from Kira's answer and develop it somewhat (in a bad, novice kind of way), to achieve the pause/resume objective interactively, the code below works for me, and hopefully it's of some help to you...
option explicit
dim strpath, fso, strfile, strtxt, user, voice, flag
flag = 2
call init
sub init
do while len(strpath) = 0
strpath = inputbox ("Please enter the full path of txt file", "Txt to Speech")
if isempty(strpath) then
wscript.quit()
end if
loop
'strpath = "C:\Users\???\Desktop\???.txt"
set fso = createobject("scripting.filesystemobject")
on error resume next
set strfile = fso.opentextfile(strpath,1)
if err.number = 0 then
strtxt = strfile.readall()
strfile.close
call ctrl
else
wscript.echo "Error: " & err.number & vbcrlf & "Source: " & err.source & vbcrlf &_
"Description: " & err.description
err.clear
call init
end if
end sub
sub ctrl
user = msgbox("Press ""OK"" to Play / Pause", vbokcancel + vbexclamation, "Txt to Speech")
select case user
case vbok
if flag = 0 then
voice.pause
flag = 1
call ctrl
elseif flag = 1 then
voice.resume
flag = 0
call ctrl
else
call spk
end if
case vbcancel
wscript.quit
end select
end sub
sub spk
'wscript.echo strtxt
set voice = createobject("sapi.spvoice")
voice.speak strtxt,1
flag = 0
call ctrl
end sub
I’m trying to determine, whether the user clicked NO in the UAC-prompt and if so to not set up the nul-port.
I'm calling this script form a batch-file, which I'd like to exit, if the user clicked no.
The VBScript:
Option Explicit
Main
Sub Main
Dim oShell, objWMIService, servSpooler, objReg, objShellApp, result
Const PrinterPort = "NUL:"
Const HKLM = &h80000002
If Not WScript.Arguments.Named.Exists("elevate") Then
Set objShellApp = CreateObject("Shell.Application")
objShellApp.ShellExecute WScript.FullName, WScript.ScriptFullName & " /elevate", "", "runas", 0
WScript.Quit
End If
result = isElevated()
If result = True Then
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
set servSpooler = objWMIService.Get("Win32_Service.Name='spooler'")
Set objReg = GetObject("winmgmts:root\default:StdRegProv")
servSpooler.StopService
objReg.SetStringValue HKLM, "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Ports", PrinterPort, ""
servSpooler.StartService
Else
WScript.Quit 1
End If
End Sub
Function isElevated
Dim shell, whoami, whoamiOutput, strWhoamiOutput
Set shell = CreateObject("WScript.Shell")
Set whoami = shell.Exec("whoami /groups")
Set whoamiOutput = whoami.StdOut
strWhoamiOutput = whoamiOutput.ReadAll
If InStr(1, strWhoamiOutput, "S-1-16-12288", vbTextCompare) Then
isElevated = True
Else
isElevated = False
End If
End Function
The batch:
cscript "set_port.vbs"
IF ERRORLEVEL 1 (
ECHO FAIL
PAUSE
EXIT
)
Now, I looked at this page:
http://www.robvanderwoude.com/errorlevel.php
and some others and I feel like I tried every possible combination. Probably, I just haven’t had the correct combination yet. Some tips and help would be highly appreciated!
The basic goal: Determine, whether the user clicked NO in the UAC-prompt and then end the VBScript and batch-file.
UPDATE:
Okay, thanks for all the answers so far. I'm pretty certain now it's the script. I use the errorlevel again in the batch-file and there it works just fine now.
As for the VBScript:
In Order to have an error code of let's say 1 when the user clicks NO in the UAC prompt (meaning the current file is not elevated), I need to put it like this:
If result = True Then
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
set servSpooler = objWMIService.Get("Win32_Service.Name='spooler'")
Set objReg = GetObject("winmgmts:root\default:StdRegProv")
servSpooler.StopService
objReg.SetStringValue HKLM, "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Ports", PrinterPort, ""
servSpooler.StartService
WScript.Quit(0)
Else
WScript.Quit(1)
End If
But: in the first WScript.Quit after the ShellExecute, I also need to put WScript.Quit(1), right? Because otherwise I never get an error to be passed to errorlevel (or at least not greater than 0).
So:
objShellApp.ShellExecute WScript.FullName, WScript.ScriptFullName & " /elevate", "", "runas", 0
WScript.Quit(1)
The big problen, I guess, is that clicking NO on the UAC promtp doesnt eally cause an error, so I need to put WSCript.Quit(1) there.
OR i do it the other way round and say: WScript.Quit(1) when the user clicked YES and the script is elevated and put WScript.Quit(0) everyhwere else.
However, in the first case I always get errorlevel 1 and in the second case always errorlevel 0.
----------- UPDATE:
My VBScript file looks like this now:
Option Explicit
Main
Sub Main
Dim objShell, objWMIService, servSpooler, objReg, objShellApp, result, oShell
Dim whoami, strWhoamiOutput, whoamiOutput
Const PrinterPort = "NUL:"
Const HKLM = &h80000002
If Not WScript.Arguments.Named.Exists("elevate") Then
Set objShellApp = CreateObject("Shell.Application")
objShellApp.ShellExecute WScript.FullName, WScript.ScriptFullName & " /elevate", "", "runas", 0
WScript.Quit 10
WScript.Echo("Done")
Else
Set oShell = CreateObject("WScript.Shell")
Set whoami = oShell.Exec("whoami /groups")
Set whoamiOutput = whoami.StdOut
strWhoamiOutput = whoamiOutput.ReadAll
If InStr(1, strWhoamiOutput, "S-1-16-12288", vbTextCompare) Then
Wscript.Echo("ADMIN")
WScript.Echo("Port")
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
set servSpooler = objWMIService.Get("Win32_Service.Name='spooler'")
Set objReg = GetObject("winmgmts:root\default:StdRegProv")
servSpooler.StopService
objReg.SetStringValue HKLM, "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Ports", PrinterPort, ""
servSpooler.StartService
WScript.Quit 1
End if
WScript.Echo("Done 2")
End If
End Sub
And a test batch:
#echo off
cscript "test.vbs"
ECHO %errorlevel%
PAUSE
The errorlevel output is 10 and not 1, although the script is quit as intended and the message "Done" is never shown.
Debugging technique:
Write a VBS script that just sets the errorlevel and quits - and get that working with your batch script.
Then you can massage your full vbs script.
Im getting this error when i try to run my vbs script,
object doesnt support this property or method
My vbs code is
Rem -- This example will show you how to create a very simple runonce configuration.
Rem -- Get current path of this script.
Set fso = CreateObject("Scripting.FileSystemObject")
currentdir = fso.GetAbsolutePathName(".")
Rem -- Read the info xml
Set xmldom = CreateObject("MSXML.DOMDocument")
xmldom.Load("c:\Montupet\PDF" & "\info.xml")
Rem -- Get the program id of the automation object.
progid = xmldom.SelectSingleNode("/xml/progid").text
Rem -- Create the COM object to control the printer.
set obj = CreateObject(progid)
Rem -- Get the default printer name.
Rem -- You can override this setting to specify a specific printer.
printername = "PDF Writer - bioPDF"
runonce = obj.GetSettingsFileName(true)
^
Error here
set oArgs=wscript.Arguments
Rem -- Print all the files in the 'in' folder
dim file_name, template
dim command_line_args
set command_line_args = wscript.Arguments
'Check if any Arguments have been passed to our script.
if command_line_args.count > 0 then
file_name = command_line_args(0)
template = command_line_args(1)
Set oWd = CreateObject("Word.Application")
oWd.Visible = False
wordname = """" & "c:\MTMS\MTMSPRT\" & file_name & """"
wscript.echo wordname
Set oDoc = oWd.Documents.Open(wordname)
Set oPS = oDoc.PageSetup
' Reduce the margins to .5" (36 points)
oPS.LeftMargin = 8.4
oPS.RightMargin = 0.2
'Save changes to doc on closing and quit Word
oDoc.Saveas wordname , 0
wscript.echo "Saved"
oDoc.Close
wscript.echo "close"
oWd.Quit
wscript.echo "Quit"
Set oWd = Nothing
Set objShell = Nothing
wscript.echo "Cleared Word"
Set oWd = Nothing
Set objShell = Nothing
output = "c:\MTMS\MTMSPRT\PDFs\" & Replace(ucase(file_name), "DOC", "") & "PDF"
Rem -- Set the values
obj.Init
obj.SetValue "Output", output
obj.SetValue "ShowSettings", "never"
obj.SetValue "ShowPDF", "no"
obj.SetValue "ShowProgress", "no"
obj.SetValue "ShowProgressFinished", "no"
obj.SetValue "SuppressErrors", "no"
obj.SetValue "ConfirmOverwrite", "no"
obj.SetValue "superimpose", template
Rem -- Write settings to the runonce-Invoice.ini
obj.WriteSettings True
wscript.echo "runonce created"
Rem -- Print the document
printfile = "c:\MTMS\MTMSPRT\" & file_name
cmd = """" & "c:\Montupet\PDF\printto.exe"" """ & printfile & """ """ & printername & """"
wscript.echo "printfile line setup"
Set WshShell = WScript.CreateObject("WScript.Shell")
ret = WshShell.Run(cmd, 1, true)
wscript.echo "shell run start"
Rem -- Wait until the runonce is removed.
Rem -- When the runonce is removed it means that the gui.exe program
rem -- has picked up the print job and is ready for the next.
While fso.fileexists(runonce)
wscript.echo "checking for runonce"
Rem -- Wait for some milliseconds before testing again
wscript.sleep 100
Wend
wscript.echo "runonce gone"
end if
Rem -- Dispose the printer control object
set obj = Nothing
Judging by this blog post for VB6,
runonce = obj.GetSettingsFileName(true)
should instead be
runonce = obj.GetSettingsFilePath(true)
The BioPDF website has a reference which might help further.
This is a VBScript code example that shows how to catch whatever a command line program sends to standard output.
It executes the command xcopy /? and shows the output in a message box. Before the message box appears, for a split second you see the console window popping up.
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
Here is an other VBScript code example that shows how to execute a script without showing the console window.
objShell.Run "c:\temp\mybatch.bat C:\WINDOWS\system32\cmd.exe", 0
or
objShell.Run "c:\temp\myscript.vbs C:\WINDOWS\system32\cscript.exe", 0
As you can see it has the form <script><space><executor>.
The last example uses objShell.Run instead of objShell.Exec
What I don't know is how to execute a command line program (if necessary from a batch file), catch the standard output, without showing the console window. Any ideas?
I usually use this:
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
For more advanced commands youc an wrap to comspec (cmd)
my res = execStdOut("%comspec%" & " /c " & """" & "dir /b c:\windows\*.exe" & """" & " && Echo. && Echo finished")
In order to redirect the output to the console, run the script using cscript, ex.: c:\cscript myscript.vbs.
cscript has a few command line options. The most important (to me) is the switch //NOLOGO. If yoy use it (cscript //nologo myscript.vbs) it will omit Microsoft merchandise...
This proof of concept script:
' 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
shows how to use .Run and temporary files to get something like backticks with a hidden console. Decent file handling, quoting in sCmd, cleaning of the returned strings, and dealing with encodings will require more work. But perhaps you can use the strategy to implement something that fits your needs.
If you don't mind having the taskbar button appear, you can just move the console window offscreen before launching it.
If the HKCU\Console\WindowPosition key exists, Windows will use its value to position the console window. If the key doesn't exist, you'll get a system-positioned window.
So, save the original value of this key, set your own value to position it offscreen, call Exec() and capture its output, then restore the key's original value.
The WindowPosition key expects a 32-bit value. The high word is the X coordinate and the low word is the Y coordinate (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
If you really want to make sure the coordinates are offscreen, you can get the screen dimensions via VBScript by using IE or other tools.
To return in VBA all subfolders in G:\OF
sub M_snb()
c00= createobejct("wscript.Shell").exec("cmd /c Dir G:\OF\*. /s/b").stdout.readall
end sub
to split the returned string into an array
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
This is the way you can get the command line StdOut (result) without see this popup black dos windows in vbscript:
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()
Instead of WScript.Shell, consider using using Win32_Process with startupInfo.ShowWindow = 0 to launch the process with SW_HIDE. I posted a detailed example under VBS Run cmd.exe output to a variable; not text file.