Here or there I have found Cleanmgr.exe and Ccleaner to hang. When they do, typically the CPU usage is upwards of 90%+. The hangs are intermittent and hard to reproduce, but when they hang, task manager has reported running them running for over 8 hours. 99% CPU usage is typical for a few seconds.
So I wrote a short little vbScript to run the apps, then kill it if it takes too long - I'm thinking no more than 3 minutes per app. FYI, I'm running out of box, from WinXp to 8.1, so I really only have vbScript and the command line.
First attempt appeared successful, but then I found I had to apply a second test, again with another timer, however, now I find my script doesn't exit at all when Cleanmgr or CCleaner hangs.
This started simple, and now it's nuts. I'm hoping someone out here can help me. I think the issue is, the process is chewing up my CPU, so the timer check in my script can't run...
It occurred to me, I'm calling this from a cmd file using cScript - could there be some issue there?
Is there a way to track the process time rather than from a timer? Create a thread higher priority than the process so it can terminate when it hangs? Maybe I have bug in my code? Help please, I'm going nuts. Thank you.
Option Explicit
On Error Goto 0
Dim wshShell, sysPath, waitTime, i, str, masterTimer, mElapsed, slp
Dim apps(), paths(), params()
Set wshShell=WScript.CreateObject("wScript.Shell")
sysPath = wshShell.ExpandEnvironmentStrings("%SystemRoot%")
waitTime = 90
slp = 2255
ReDim apps(2)
ReDim paths(2)
ReDim params(2)
apps(0) = "cleanmgr.exe"
paths(0) = sysPath&"\System32"
params(0) = "/SageRun:101"
apps(1) = "ccleaner.exe"
paths(1) = "C:\Program Files\ccleaner"
params(1) = "/AUTO"
apps(2) = "ccleaner64.exe"
paths(2) = "C:\Program Files\ccleaner"
params(2) = "/AUTO"
For i=LBound(apps) to UBound(apps)
str="cmd.exe /C taskkill.exe /im " & apps( i ) & " /f /t"
wshShell.run str
str="cmd.exe /C taskkill.exe /im " & apps( i ) & " /f"
wshShell.run str
str="cmd.exe /C tskill.exe " & apps( i ) & " /a /v"
wshShell.run str
WScript.Sleep slp
masterTimer = Timer
mElapsed = 0
RunCleaner paths(i),apps(i),params(i)
str="cmd.exe /C taskkill.exe /im " & apps( i ) & " /f /t"
wshShell.run str
str="cmd.exe /C taskkill.exe /im " & apps( i ) & " /f"
wshShell.run str
str="cmd.exe /C tskill.exe " & apps( i ) & " /a /v"
wshShell.run str
Set Str=Nothing
Wscript.sleep slp
Next
ReDim apps(0)
ReDim paths(0)
ReDim params(0)
Erase apps
Erase paths
Erase params
Set slp=Nothing
Set sysPath=Nothing
Set wshShell=Nothing
Set waitTime=Nothing
WScript.Quit(0)
Public Sub RunCleaner( strPath, prog, args )
Dim objFSO, objWMIService, objProcess, objStartup, objConfig, colMonitoredProcesses, objLatestProcess
Dim intProcessID, erReturn, processes, proc
Dim fullPath, elapsed, startTime, running
Set objFSO=CreateObject( "Scripting.FileSystemObject" )
fullPath = "" & strpath & "\" & prog
If objFSO.FileExists( fullPath ) Then
Set objWMIService= GetObject( "winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2" )
Set objProcess = GetObject( "winmgmts:root\cimv2:Win32_Process" )
Set objStartup = objWMIService.Get( "Win32_ProcessStartup" )
Set objConfig = objStartup.SpawnInstance_
objConfig.ShowWindow = 1
elapsed = -1 * slp
startTime = Timer
Wscript.sleep slp
erReturn = objProcess.Create ( fullPath & " " & args, Null, objConfig, intProcessID )
Set colMonitoredProcesses = objWMIService. _
ExecNotificationQuery( "select * From __InstanceDeletionEvent " _
& " within 1 where TargetInstance isa 'Win32_Process'" )
Do While ( ( elapsed < waitTime ) And ( ( mElapsed ) < waitTime ) )
Set objLatestProcess = colMonitoredProcesses.NextEvent
If objLatestProcess.TargetInstance.ProcessID = intProcessID Then
Exit Do
End If
elapsed = Timer - startTime
mElapsed = Timer - masterTimer
Loop
WScript.sleep slp
running = True
Do While ( ( running ) And ( elapsed < waitTime ) And ( mElapsed < waitTime ) )
SET processes = GetObject( "winmgmts:" )
running = False
elapsed = ( Timer - startTime ) / 2
For Each proc in processes.InstancesOf( "Win32_Process" )
If ( StrComp( LCase( proc.Name ), LCase( prog ), vbTextCompare ) = 0 ) Then
running = True
Exit For
End If
Next
Set processes=Nothing
mElapsed = ( Timer - masterTimer ) / 2
Loop
WScript.sleep slp
fullPath = "cmd.exe /C taskkill.exe /im " & prog & " /f /t"
wshShell.run fullPath
fullPath = "cmd.exe /C taskkill.exe /im " & prog & " /f"
wshShell.run fullPath
fullPath = "cmd.exe /C tskill.exe " & prog & " /a /v"
wshShell.run fullPath
Set objWMIService=Nothing
Set objProcess=Nothing
Set objStartup=Nothing
Set objConfig=Nothing
Set objProcess=Nothing
Set erReturn=Nothing
Set intProcessID=Nothing
Set colMonitoredProcesses=Nothing
Set elapsed=Nothing
Set startTime=Nothing
Set objLatestProcess=Nothing
Set running=Nothing-1 * slp
Set proc=Nothing
Set fullPath=Nothing
End If
Set objFSO=Nothing
End Sub
Your script seems a bit complex for what it needs to do. Try this out.
The exes are executed consecutively. If any are running for longer than 3 minutes then they're terminated via taskkill. If you want to do away with WMI queries altogether (which is probably where your script is having to fight for CPU) you could simply wait three minutes for each exe you start and then send a taskkill without checking whether it's still running. You could also do a tasklist rather than a WMI query.
Dim fso, shl, wmi
Set fso = CreateObject("Scripting.FileSystemObject")
Set shl = CreateObject("WScript.Shell")
Set wmi = GetObject("winmgmts:\\.\root\cimv2")
Dim app1, app2, app3, apps()
ReDim apps(-1)
app1 = fso.BuildPath(shl.ExpandEnvironmentStrings("%SYSTEMROOT%"), "System32\cleanmgr.exe")
app2 = "C:\Program Files\ccleaner\ccleaner.exe"
app3 = "C:\Program Files\ccleaner\ccleaner64.exe"
If fso.FileExists(app1) Then AddApp app1, "/SageRun:101"
If fso.FileExists(app2) Then AddApp app2, "/AUTO"
If fso.FileExists(app3) Then AddApp app3, "/AUTO"
If UBound(apps) < 0 Then WScript.Quit ' None of the programs exist
Dim apptorun, starttime, running, process
For Each apptorun In apps
starttime = Now
process = fso.GetFile(apptorun.exe).Name
shl.Run apptorun.exe & " " & apptorun.param, 0, False
Do While 1
WScript.Sleep 5000
Set running = wmi.ExecQuery("select * from win32_process where name = """ & process & """")
If running.Count = 0 Then Exit Do
If DateDiff("n", starttime, Now) > 3 Then
shl.Run "taskkill /f /im " & process, 0, True
Exit Do
End If
Loop
Next
Sub AddApp(app, arg)
ReDim Preserve apps(UBound(apps) + 1)
Set apps(UBound(apps)) = New program
apps(UBound(apps)).exe = app
apps(UBound(apps)).param = arg
End Sub
Class program
Dim exe, param
End Class
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
I want to see all the processes running on my computer but the cmd command only gives the applications, not any scripts or smaller files. I am trying to figure out a way to list all the processes in a more advanced way that will list EVERYTHING currently running. Does anyone know a way to do that with vbscript? Or if there is a better way to do this what is it?
Using TaskList Command
TaskList Command can be used to display a list of all running applications and services with their details and Process IDs(PIDs).
Dim ProTFPath, ProTF, StrPrInfo, StrPrInfoA, PrInfo
Set WshShell = WScript.CreateObject("Wscript.Shell")
Set FSO = WScript.CreateObject("Scripting.FileSystemObject")
ProTFPath = "C:\PROCESSES.txt"
WshShell.Run "CMD /C TASKLIST /V /FO LIST > """ + ProTFPath + """", 0, True
' Here Run is used instead Exec to avoid console window flashes.
If FSO.FileExists(ProTFPath) Then
Set ProTF = FSO.OpenTextFile(ProTFPath, 1, False)
End If
StrPrInfoA = ProTF.ReadAll
PrInfo = Split(StrPrInfoA, VbCrLf + VbCrLf)
For I = 0 To UBound(PrInfo)
WScript.Echo PrInfo(I)
Next
Erase PrInfo
ProTF.Close
If you no longer need this file, add following lines to the end of the script:
If FSO.FileExists(ProTFPath) Then
FSO.DeleteFile(ProTFPath, True)
End If
See more information about TaskList here.
EXE_Process = AllProcessRunningEXE(".")
Vbs_Process = AllProcessRunningVBS (".")
Function AllProcessRunningEXE( strComputerArg )
strProcessArr = ""
Dim Process, strObject
strObject = "winmgmts://" & strComputerArg
For Each Process in GetObject( strObject ).InstancesOf( "win32_process" )
strProcessArr = strProcessArr & ";" & vbNewLine & Process.name
Next
AllProcessRunningEXE = Mid(strProcessArr,3,Len(strProcessArr))
End Function
Function AllProcessRunningVBS (strComputerArg)
strProcessArr = ""
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputerArg & "\root\cimv2")
Set colItems = objWMIService.ExecQuery ("Select * from Win32_Process Where Name = 'cscript.exe' OR Name = 'wscript.exe'")
For Each objItem in colItems
strProcessArr = strProcessArr & ";" & vbNewLine & objItem.CommandLine
Next
AllProcessRunningVBS = Mid(strProcessArr,3,Len(strProcessArr))
Set objWMIService = Nothing
Set colItems = Nothing
End Function
I am trying to launch an application from the Windows shell using VBScript. The application runs without errors when run from QtCreator. However, it crashes when run from VBScript and exits with error code 255.
Here's the script:
Set objShell = WScript.CreateObject("WScript.Shell")
rv = objShell.Run("path\to\application.exe", 1 , True)
If rv <> 0 Then
MsgBox "Failed : " & rv
End If
WScript.Sleep 120000
objShell.Run "taskkill /im path\to\application.exe"
Set objShell = Nothing
Could someone please point out what I am missing?
Give a try for this vbscript and tell me the result :
Option Explicit
Dim Title,objShell,rv,ProcessPath,ProcessName
Title = "Launching and killing application using Vbcript"
Set objShell = CreateObject("WScript.Shell")
ProcessPath = "C:\Windows\system32\Calc.exe"
rv = objShell.Run(DblQuote(ProcessPath),1,False)
If rv <> 0 Then
MsgBox "Failed : " & rv
End If
Set objShell = Nothing
WScript.Sleep 12000
ProcessPath = Split(ProcessPath,"\")
ProcessName = ProcessPath(UBound(ProcessPath))
Msgbox "The Process named "& DblQuote(ProcessName) &" is being to be killed now !",_
vbExclamation,Title
Call Kill(ProcessName)
'****************************************************
Sub Kill(ProcessName)
Dim Ws,Command,Execution
Set Ws = CreateObject("Wscript.Shell")
Command = "cmd /c Taskkill /F /IM "& DblQuote(ProcessName) &""
Execution = Ws.Run(Command,0,True)
Set Ws = Nothing
End Sub
'****************************************************
Function DblQuote(Str)
DblQuote = Chr(34) & Str & Chr(34)
End Function
'****************************************************
Try This way :
Set objShell = WScript.CreateObject("WScript.Shell")
rv = objShell.Run(chr(34)&"c:\windows\system32\Mspaint.exe"&chr(34), 1 , False)
If rv <> 0 Then
MsgBox "Failed : " & rv
End If
WScript.Sleep 2000
objShell.Run "taskkill /f /im ""Mspaint.exe"" ",0,False
Set objShell = Nothing
I was able to find the error. I set the current directory to the folder that contains the .exe file.This is the modified script:
Option Explicit
Dim Title,objShell,rv,ProcessPath,ProcessName
Title = "Launching and killing application using Vbcript"
Set objShell = CreateObject("WScript.Shell")
objShell.CurrentDirectory = "path\to\folder\containing\.exe"
ProcessPath = "path\to\application.exe"
objShell.Run DblQuote(ProcessPath),1,False
If rv <> 0 Then
MsgBox "Failed : " & rv
End If
Set objShell = Nothing
WScript.Sleep 12000
ProcessPath = Split(ProcessPath,"\")
ProcessName = ProcessPath(UBound(ProcessPath))
Msgbox "The Process named "& DblQuote(ProcessName) &" is being to be killed now !",_
vbExclamation,Title
Call Kill(ProcessName)
Sub Kill(ProcessName)
Dim Ws,Command,Execution
Set Ws = CreateObject("Wscript.Shell")
Command = "cmd /c Taskkill /F /IM "& DblQuote(ProcessName) &""
Execution = Ws.Run(Command,0,True)
Set Ws = Nothing
End Sub
Function DblQuote(Str)
DblQuote = Chr(34) & Str & Chr(34)
End Function
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.
To monitor the bandwidth usage and not to unnecessarily load programs in the start up,I want to execute the dumeter.exe then firefox.exe.When I shutdown firefox it should kill dumeter.I used the following code to start
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "c:\progra~1\dumeter\dumeter.exe"
WshShell.Run "c:\progra~1\mozill~1\firefox.exe
Need to run taskkill only when firefox is closed.Tried using a bat file but sometimes the dumeter starts and closes on its own does not wait.
WshShell.Run "taskkill /f /im dumeter.exe"
Set WshShell = Nothing
You can wait for a process to end by subscribing to the appropriate WMI event. Here's an example:
strComputer = "."
Set oWMI = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
''# Create an event query to be notified within 5 seconds when Firefox is closed
Set colEvents = oWMI.ExecNotificationQuery _
("SELECT * FROM __InstanceDeletionEvent WITHIN 5 " _
& "WHERE TargetInstance ISA 'Win32_Process' " _
& "AND TargetInstance.Name = 'firefox.exe'")
''# Wait until Firefox is closed
Set oEvent = colEvents.NextEvent
More info here: How Can I Start a Process and Then Wait For the Process to End Before Terminating the Script?
Option Explicit
Const PROC_NAME = "<Process_You_Want_to_Check>"
Const SLEEP_INTERVAL_MS = 5000 '5 secs
Dim objWMIService
Dim colProcesses, objProcess, inteproc
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
inteproc = -1 'set in unknown state
Do Until inteproc = 0
Set colProcesses = objWMIService.ExecQuery(_
"Select * from Win32_Process where Name='" & PROC_NAME & "'")
inteproc = colProcesses.count
If inteproc > 0 then
WSCRIPT.ECHO "Process " & PROC_NAME & " is still runing, wait for " & SLEEP_INTERVAL_MS / 1000 & " seconds"
WScript.Sleep(SLEEP_INTERVAL_MS)
else
wscript.echo "Process " & PROC_NAME & " Finished. Continue running scripts"
End If
Loop