I want to get the result of a simple command from the command line (cmd.exe) using a Windows script (.vbs). How is this done? I haven't been able to find a good/simple example or explanation. You could use the "date" or "time" command to provide an example with.
Such as:
P.S. I am able to write the script code that opens cmd.exe and sends the command.
Thanks!
When in doubt, read the documentation. You probably want something like this:
Set p = CreateObject("WScript.Shell").Exec("%COMSPEC% /c date /t")
Do While p.Status = 0
WScript.Sleep 100
Loop
WScript.Echo p.StdOut.ReadAll
Edit: When using Exec() you pass input via the .StdIn descriptor, not via SendKeys() (which is a rather unreliable way of passing input anyway).
%COMSPEC% is a system environment variable with the full path to cmd.exe and the /c option makes cmd.exe exit after the command (date /t in the example) is finished.
If the command indicates success/failure with an exit code, you can check the ExitCode property after the command finished.
If p.Status <> 0 Then WScript.Echo p.ExitCode
Edit2: Instead of using atprogram interactively, can you construct commandlines that will perform particular tasks without user interaction? With non-interactive commandlines something like this might work:
prompt = "C:\>"
atprogram_cmdline_1 = "atprogram.exe ..."
atprogram_cmdline_2 = "atprogram.exe ..."
'...
Function ReadOutput(p)
text = ""
Do Until Right(text, Len(prompt)) = prompt
text = text & p.StdOut.Read(1)
Loop
ReadOutput = text
End Function
Set cmd = CreateObject("WScript.Shell").Exec("%COMSPEC% /k")
ReadOutput cmd ' skip over first prompt
cmd.StdIn.WriteLine(atprogram_cmdline_1)
WScript.Echo ReadOutput(cmd)
cmd.StdIn.WriteLine(atprogram_cmdline_2)
WScript.Echo ReadOutput(cmd)
'...
cmd.Terminate ' exit CMD.EXE
%COMSPEC% /k spawns a command prompt without running a command. The /k prevents it from closing. Because it isn't closing automatically, you can't use the While p.Status = 0 loop here. If a command needs some time to finish, you need to WScript.Sleep a number of seconds.
Via cmd.StdIn.WriteLine you can run commandlines in the CMD instance. The function ReadOutput() reads the output from StdOut until the next prompt appears. You need to look for the prompt, because read operations are blocking, so you can't simply say "read all that's been printed yet".
After you're finished you quit CMD.EXE via cmd.Terminate.
Related
When writing a script in sh or in cmd you can put a > at the end of a line to have the output of that line redirected to a file. If not, it is sent to the standard output.
Also, both have the echo command to produce output to the standard output (which can, in turn, be redirected too).
How to perform those two things in a VBS script?
Nothing different. You only need to make sure your scripts are run with the console based script host cscript.
myscript.vbs:
' WScript.Echo is a host-aware hybrid method.
' in cscript, prints the message with final a new line feed, also accepts vary arguments (0 or more).
' in wscript, shows a message dialog window
WScript.Echo "test1", "arg2"
' WScript.Stdout.Write on the other hand is a more traditional way to write to standard output stream
' print the message as is with no new line feeds
WScript.Stdout.Write "test"
WScript.Stdout.Write "2"
Command:
cscript myscript.vbs
Output:
Microsoft (R) Windows Script Host Version 5.812
Copyright (C) Microsoft Corporation. All rights reserved.
test1 arg2
test2
There's also an option to prevent to display banner on the output.
cscript //NoLogo myscript.vbs
Output:
test1 arg2
test2
Redirection:
cscript //NoLogo myscript.vbs>output.txt
PS: cscript is the default script interpreter only on Windows Server operating systems. Otherwise the default is wscript. Therefore it is a good practice to run the scripts with a specific script host.
To change the default script host have a look at Running Your Scripts
Useful Links:
Echo Method
Write Method
Running Your Scripts
I am trying to use exec to run a command such as dir with cmd using tcl code, however the terminal window opens up and I am unable to store the result, when the command has run, into a variable ?
This is what I've been trying so far,
set res [exec cmd.exe /c "dir" &];
When I print out the variable using,
puts $res
I get back just three or four digit codes instead of the actual result when the command was run.
Any help is appreciated.
set res [exec cmd.exe /c "dir" &]
The & at the end of the exec indicates that the command will be processed in the background. The result returned is the process id of the command.
To do what you want, use:
set res [exec cmd.exe /c "dir"]
It would be far more efficient and less resource hungry to use the built-in glob command to get a list of files or search for a file.
set res [glob *.txt]
set res [glob -directory {C:/Program Files} *]
References: exec glob
I have this kind of batch file
start /b ruby script.rb && echo done
...
However, it write 'done' immediately after i run the batch file, which is incorrect, as the script took about 5 mins.
So, how to echo done only after the bg task succesfully end?
thank you!
note: I think that && operator work this way if it is not used in batch file nor in usage to run bg task.
start "" /b cmd /c "ruby script.rb && echo done"
Without the quotes the conditional execution command is seen as the continuation of the start command instead of continuation of the ruby command.
As the && is an operator handled by cmd we need to start a new instance.
The "" at the start are needed as the first quoted argument to start is handled as a window title.
note: && is an conditional execution operator. If the previous command does not generate an error then the following command is executed. In this case with the process running in background, probably, &, the command concatenation operator, should be used to know that the script ended.
I wrote a function in Ruby that hibernates, restarts, or shuts down the system based on the argument. Here's how it looks:
def sysaction(action)
sleep 0.2
if action == "h"
countdown(60)
`shutdown.exe /h`
elsif action == "r"
countdown(60)
`shutdown.exe -r -f t 00`
elsif action == "s"
countdown(60)
`shutdown.exe -s -f t 00`
end
end
I want to add a piece of code that would exit the parent CMD windows instead. I couldn't find any solution without running the ruby script through a batch file. I tried the following commands:
`exit`
exec `exit`
system('exit')
`cmd /C exit`
But neither seems to work. Any way I can close the window from within Ruby?
Maybe you can use the FreeConsole function:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683150(v=vs.85).aspx
http://www.ruby-doc.org/gems/docs/w/win32console-1.3.1/Win32/Console/API.html#method-c-FreeConsole
For example:
require 'win32console'
puts 'Hello, world!
# free console so it can be shut after the program terminates.
Win32::Console::API.FreeConsole
One way is to kill all cmd.exe applications:
taskkill /f /im cmd.exe
I'm using a solution like the one mentioned here run bat file in background but the bat file in question runs a Bitcoin GPU miner in the background. Sometimes I want to stop the miner, but since I am trying to run it invisibly (because I don't want it in my taskbar) I can't stop the process. I can't even find it in my process manager (no cmd.exe or conhost.exe). [I'm not even sure it's running.] Any help?
edit: It is most definitely running; opening the process with a window shows that the miner was running at half capacity, which in the past indicated the miner was open twice.
edit2: here are the contents of the batch files, if it helps.
batch file I run to start everything:
wscript.exe "D:\Desktop\invisible.vbs" "C:\Program Files (x86)\Bitcoin\DiabloMiner\bpm.bat"
bpm.bat:
cd "C:\Program Files (x86)\Bitcoin\DiabloMiner"
java -cp target\libs\*;target\DiabloMiner-0.0.1-SNAPSHOT.jar -Djava.library.path=target\libs\natives\windows com.diablominer.DiabloMiner.DiabloMiner -u <username> -p <password> -o <pool> -p 8332 -w 64 -f 1000
invisible.vbs:
set args = WScript.Arguments
num = args.Count
if num = 0 then
WScript.Echo "Usage: [CScript | WScript] invis.vbs aScript.bat <some script arguments>"
WScript.Quit 1
end if
sargs = ""
if num > 1 then
sargs = " "
for k = 1 to num - 1
anArg = args.Item(k)
sargs = sargs & anArg & " "
next
end if
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run """" & WScript.Arguments(0) & """" & sargs, 0, False
Without seeing the contents of the batch my guess is the CMD.exe runs your batch which launches your bitcoin process and then ends. This would explain why you're not seeing CMD.exe.
If you want to see an example when you would see cmd.exe you can create a batch that never ends like so.
:TOP
REM FOO
GoTo TOP
Then run inivisible.vbs with this batch and you'll see the cmd.exe in your task. If you use process explorer you'll be able to see the batchfile's name in the command line for the image. Which would look something like this
`cmd /c ""C:\Whaterver\Looptest.bat" "
UPDATE
As Harry Steinhilber already pointed out the process will be java.exe
If you run process explorer and select the Java.Exe you should see this in the command prompt
java -cp target\libs\*;target\DiabloMiner-0.0.1-SNAPSHOT.jar -Djava.library.path=target\libs\natives\windows com.diablominer.DiabloMiner.DiabloMiner -u <username> -p <password> -o <pool> -p 8332 -w 64 -f 1000
This will allow you to identify the DataMiner from other java applcations (if any) that you are running.
You can use VBScript.
set shell=createobject("wscript.shell")
dim cmdline
cmdline="C:\path\to\yourprogram.jar" ' HERE
set wmi=getobject("winmgmts:{impersonationLevel=impersonate}!\\"&shell.expandenvironmentstrings("%computername%")&"\root\cimv2")
for each process in wmi.instancesof("Win32_process")
if process.name="java.exe" and instr(process.commandline,cmdline)>0 then
process.terminate
end if
next
Sorry about the long line. Change the text where it says HERE to the location of your jar file and it will terminate it.