Sendkeys from command prompt - cmd

Is there a way to use sendkeys (or something equivalent) from (not to) the command prompt?

Here is a one line solution:
This line will type "Testing 123" and then hit Enter.
echo >script.vbs set shell = CreateObject("WScript.Shell"):shell.SendKeys "Testing 123{ENTER}" & script.vbs

You can use vbscript. For example, this script will mute the speakers.
set shell = CreateObject("WScript.Shell")
shell.run"Sndvol"
WScript.Sleep 1500
shell.SendKeys"{TAB}"
shell.SendKeys" "
shell.SendKeys"%{F4}"
You launch it from the console with
cscript mute.vbs
More infos here

Without creating temporary files.
The 'loop' was shown only so that you could open a notebook for output. Remove it after.
#echo off
:loop
::------------begin main code------------
set command=new ActiveXObject('WScript.Shell').SendKeys('WoW{ENTER}{ENTER}');
for /f "delims=" %%i in ('mshta "javascript:%command%close(new ActiveXObject('Scripting.FileSystemObject'));"') do set "var=%%i"
::-------------end main code-------------
timeout /t 1 /nobreak >nul
goto :loop

Related

Batch File calling Console Application - Leaves CMD window open

I am calling a C# Console Application via batch file, in order to send the application output into a text file, with the date/time etc.
The problem I have is that when the console application completes, it leaves the batch window open, because there is a PAUSE (the C# equivalent), so a key must be pressed for the window to close. This means I do not know when the job has finished.
Is there a way I can make the CMD window close when the application finished, without having to change the C# Application code?
#ECHO================================================================================
#ECHO The Application is currently running and may take some time. Please wait...
#ECHO================================================================================
#ECHO OFF
C:\Applications\Job\Job.exe > C:\Applications\Job\Job_Output\"Output_%date:/=-% %time::=-%.txt"
Try this (note the collated dot after echo):
echo.| C:\Applications\Job\Job.exe > C:\Applications\Job\Job_Output\"Output_%date:/=-% %time::=-%.txt"
I have tried with pause and it works well:
echo.| pause
echo. is not echo. It just prints a newline, just what you need to trigger the pause.
Not sure whether will it work if your console app already have a Console.ReadLine() or Console.ReadKey() method but instead of just calling the *.exe use the Start command which will run the executable in a separate window like
start "MyConsoleTask" C:\Applications\Job\Job.exe > C:\Applications\Job\Job_Output\"Output_%date:/=-% %time::=-%.txt"
If you have not access to the console app source code, you may try a workaround
#echo off
#echo================================================================================
#echo The Application is currently running and may take some time. Please wait...
#echo================================================================================
set "timeStamp=%date:/=-%_%time::=-%
set "timeStamp=%timeStamp:~0,-3%" & rem remove ,centiseconds.
set "logFile=C:\Applications\Job\Job_Output\Output_%timeStamp%.txt"
rem start the exe in the same cmd window
start /B "" """C:\Applications\Job\Job.exe" > "%logFile%"""
rem wait for process startup
ping 1.1.1.1 -n 1 -w 750 >NUL
rem wait for logFile to be closed. This may flag that job.exe has ended
:wait
ping 1.1.1.1 -n 1 -w 50 >NUL & rem this avoids processor load
2>nul (>>"%logFile%" call )||goto :wait
rem send a key to the console. This may be captured by the exe file
set "_vbs_file_=%TEMP%\sendConsole.vbs"
(
echo/ set oWS ^= CreateObject^("wScript.Shell"^)
echo/ wScript.Sleep 50
echo/ oWS.SendKeys "{ENTER}"
)>"%_vbs_file_%"
if exist "%TEMP%\sendConsole.vbs" (set "_spawn_=%TEMP%\sendConsole.vbs") else (set "_spawn_=sendConsole.vbs")
ping 1.1.1.1 -n 1 -w 50 >NUL
start /B /WAIT cmd /C "cls & "%_spawn_%" & del /F /Q "%_spawn_%" 2>NUL"
#echo================================================================================
#echo Process completed. I guess...
#echo================================================================================
exit/B
so,
start /B ...
starts the job.exe executable in the same cmd window.
:wait
ping 1.1.1.1 -n 1 -w 50 >NUL & rem this avoids processor load
2>nul (>>"%logFile%" call )||goto :wait
waits until logfile is closed, so it may indicate that the previous proccess has ended.
set "_vbs_file_=%TEMP%\sendConsole.vbs"
(
echo/ set oWS ^= CreateObject^("wScript.Shell"^)
echo/ wScript.Sleep 50
echo/ oWS.SendKeys "{ENTER}"
)>"%_vbs_file_%"
if exist "%TEMP%\sendConsole.vbs" (set "_spawn_=%TEMP%\sendConsole.vbs") else (set "_spawn_=sendConsole.vbs")
ping 1.1.1.1 -n 1 -w 50 >NUL
start /B /WAIT cmd /C "cls & "%_spawn_%" & del /F /Q "%_spawn_%" 2>NUL"
send the enter key to the console, so the process waiting a keystroke may capture it.
NOTE: the ping wait trick works fine only if the IP is unreachable.
NOTE: the call and/or goto trick is discussed here
we gotta simulate a key press here, therefore we should toy with the keyboard buffer.
I am no Batch expert and this is the answer I found searching how to press keys with a batch:
#if (#CodeSection == #Batch) #then
#echo off
set SendKeys=CScript //nologo //E:JScript "%~F0"
rem Open the command here
start "" /B Job.exe > JobOutput.txt
rem sends the keys composing the string "I PRESSED " and the enter key
%SendKeys% "I PRESSED {ENTER}"
goto :EOF
#end
// JScript section
WScript.CreateObject("WScript.Shell").SendKeys(WScript.Arguments(0));
source:
Press Keyboard keys using a batch file
GnuWin32 openssl s_client conn to WebSphere MQ server not closing at EOF, hangs

Can I run a windows batch file with hidden cmd window but see the programs started by the batch?

I want to start a batch file in a hidden way.
This discussion describes very well how it can be done: by using the CreateProcess API function. Using this method my started batch script is not visible.
The problem is though that the programs (exes) called inside of the batch are hidden, too!
My goal is to hide the started batch windows but show the windows of the applications called inside the batch.
Is it possible? If so, how? Can I use the CreateProcess function for it or do I need another one?
Next commented batch script shows possible approach to run visibly
another batch script:
cliParser.bat simply lists all supplied parameters;
cliParseArg.bat does the same and sets errorlevel to parameters count (zero-based so never returs 0) by exit /b %i%;
a GUI application: exercised common calc and notepad executables;
a Win32 console application: cliParser.exe is cliParser.bat rewritten in C++;
from within an invisible command line window. Examples given how-to run above asynchronously as well as synchronously (i.e. waiting until called app ends).
#ECHO OFF
SETLOCAL EnableExtensions
rem STDOUT output is invisible if this script runs in a hidden window
wmic OS get LocalDateTime
rem another batch script asynchronously => visible
start "batch asyn" cmd /K ""D:\bat\cliParser.bat" par1 %* "par 3""
rem errorlevel clear: by virtue of Dave Benham in reply to http://superuser.com/a/649329/376602
(call )
rem another batch script synchronously => visible
start "batch synchr" /WAIT cmd /K "("D:\bat\cliParseArg.bat" par1 %* "par 3"&pause&exit /B %%%%errorlevel%%%%)"
rem `pause` command in above line is merely for debugging purposes to ensure that window is visible
echo cliParseArg.bat parameter count=%errorlevel%
echo(
rem a GUI application asynchronously => visible
start "" calc.exe
rem a GUI application synchronously => visible
notepad.exe
rem a console application asynchronously => visible
start "CApp asyn" cmd /K ""D:\bat\cliParser.exe" rap1 %* "rap 3""
rem a console application synchronously => visible
start "CApp synchr" /WAIT cmd /K "("D:\bat\cliParser.exe" arg1 %* "arg 3"&exit /B)"
rem STDOUT output is invisible if this script runs in a hidden window
cmd /C wmic OS get LocalDateTime
Output if called from a visible cmd window first and then in a hidden window::
==> D:\bat\SO\37181230.bat "xx yy"
LocalDateTime
20160512195221.499000+120
cliParseArg.bat parameter count=4
LocalDateTime
20160512195244.958000+120
==> Wscript D:\VB_scripts\runhidden.vbs "D:\bat\SO\37181230.bat" "A1 B2"
==>
The runhidden.vbs is adapted from Rob van der Woude's script where
strArguments = strArguments & " " & WScript.Arguments(i) line was changed to
strArguments = strArguments & " """ & WScript.Arguments(i) & """"
This should do the trick, use this code in your batch file to start your EXEs.
#echo off
title GEO-START v2
REM #############################################################
REM ## GEO-START ## starts any file any location with variables. ##
REM #############################################################
REM ##
REM "start-and-wait-yes-no" variable, Y is yes, N is no.
REM ##
REM "var" variable, "/silent" or "/y". ## The /y variable is grait for "ms self extracting cabinet files" CAB.exe.
REM ##
REM "silent" variable, 0 will set the "var" variable to true and trys to run hidden.
REM "silent" variable, 1 will set the "var" variable to false.
REM ##
REM "GEO-START" variable, the name and location of the file you want to start.
REM ################################################
set Y=true
set N=Wscript.Quit
REM ##############
REM #####################
REM ## variables to set ##
set start-and-wait-yes-no=%Y%
set var=/silent
set silent=1
set GEO-START=Winamp3 v9.1.exe
echo Set WshShell = WScript.CreateObject("WScript.Shell") > GEO-START.vbs && echo WSHShell.Run chr(34) + "%GEO-START%" + chr(34) + " %var%",%silent%,%start-and-wait-yes-no% >> GEO-START.vbs && cscript GEO-START.vbs && del GEO-START.vbs
Exit

Run batch CODE in a vbscript file

I am trying to make a vbscript file that can run batch code (Note: Not a batch file, but batch code)
The code, which works in a batch file:
IF EXIST "%appdata%\Microsoft\Windows\Start Menu\Programs\MyManufacturer\MyClickOnceApp.appref-ms" (
"%appdata%\Microsoft\Windows\Start Menu\Programs\MyManufacturer\MyClickOnceApp.appref-ms"
) ELSE (start /b "" cmd /c del "%~f0"&exit /b)
I can make the vbscript code almost do what I want using:
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run chr(34) & "C:\myscript.bat" & Chr(34), 0
Set WshShell = Nothing
Now I would like to combine these two pieces of code into one file, so something along the lines of:
Set WshShell = CreateObject("WScript.Shell" )
WshShell.Exec "IF EXIST ""%appdata%\Microsoft\Windows\Start Menu\Programs\MyManufacturer\MyClickOnceApp.appref-ms"" (""%appdata%\Microsoft\Windows\Start Menu\Programs\MyManufacturer\MyClickOnceApp.appref-ms"") ELSE (start /b """" cmd /c del ""%~f0""&exit /b)"
Set WshShell = Nothing
However when I run this code I get The system cannot find the file specified. This is expected, since Exec (or Run, or Execute) runs a batch file and not batch code. So, is there a command similar to Exec that will run batch code and not a batch file?
Some extra info that I don't think is necessary to a solution (But included for the sake of completedness):
This code is placed in the startup folder
The code is created in C# in order to run a ClickOnce application on startup
The reason I want to use vbscript is that the batch file opens a cmd window for a second, which is undesirable. My understanding is that the line Set WshShell = Nothing will make the command run invisibly
I have tried including >nul at the end of each line of the batch file, since I read that it will stop the output. This did not work for me.
It is theoretically possible for this to work by using both a .bat and a .vbs file, but this would require putting the .bat file in some other directory and feels generally hackish
I am open to other solutions besides vbscript, provided they can check if the .appref file exists, run the file if so, and delete itself if the file doesn't exist. This may be trivial in vbscript but I've never used vbscript before.
EDIT:
According to #Jason's comment, I have modified the code as follows. Now it runs with no output and without running my app (AKA it doesn't do $#!+)
Set WshShell = CreateObject("WScript.Shell" )
WshShell.Run "cmd.exe /C ""IF EXIST ""%appdata%\Microsoft\Windows\Start Menu\Programs\MyManufacturer\MyClickOnceApp.appref-ms"" (""%appdata%\Microsoft\Windows\Start Menu\Programs\MyManufacturer\MyClickOnceApp.appref-ms"") ELSE (start /b """" cmd /c del ""%~f0""&exit /b)", 0
Set WshShell = Nothing
The problem are the string in the path ! like this it work :
Dim objShell
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "cmd /c if exist test1.txt (echo ok & del test1.txt & pause) else (echo ko & pause)"
Try to work with 8.3 format. To resolve the composed-name and don't use string.
But if you're programming in VBS why do you want to use batch code in it ?
If you want to use both make a .BAT file. Or generate it from you're VBS and call it.
Here is a example:
you have a batch called regex.bat :
#echo off &setlocal
for /f "tokens=1* delims=:" %%i in (
'netsh wlan show interfaces ^| findstr /rxc:"[ ]* SSID [ ]*: ..*"'
) do for /f "tokens=*" %%k in ("%%j") do set "SSID=%%k"
echo %SSID% > regex.txt
the vbs looks like this:
Set WshShell = WScript.CreateObject( "WScript.Shell" )
WshShell.Run "regex.bat",0,True
This works for me fine. No cmd-Windows comes up. Hope this helpes you

Windows batch: analogue for `timeout` command

I'm trying to find out how to limit a program execution time within a Windows batch file. Is there something like Unix timeout command?
Please advise.
To limit the time a program has to run you could do something like this
start yourprogram.exe
timeout /t 10
taskkill /im yourprogram.exe /f
That starts yourprogram.exe, waits 10 seconds, then kills the program.
I just installed Cygwin and use unix-style timeout command from the distribution.
I don't think there is a timeout command. However, you can start executing a task in the background and sleep (using ping) for the timeout duration then kill the task.
This code waits 60 seconds, then checks to see if %ProgramName% is running.
To increase this time, change the value of WaitForMinutes.
To decrease the interval between checks, set WaitForSeconds for the number of seconds you want it to wait.
#echo off
set ProgramName=calc.exe
set EndInHours=2
:: How Many Minutes in between each check to see if %ProgramName% is Running
:: To change it to seconds, just set %WaitForSeconds% Manually
set WaitForMinutes=1
set /a WaitForSeconds=%WaitForMinutes%*60
:: How many times to loop
set /a MaxLoop=(%EndInHours%*60*60) / (%WaitForMinutes%*60)
REM Use a VBScript popup window asking to terminate %ProgramName%
echo set WshShell = WScript.CreateObject("WScript.Shell") > %tmp%\tmp.vbs
echo Wscript.Quit (WshShell.Popup( "Click 'OK' to terminate %ProgramName%." ,10 ,"Terminate %ProgramName%", 0)) >> %tmp%\tmp.vbs
start %ProgramName%
set running=True
:: Give time for %ProgramName% to launch.
timeout /t 5 /nobreak > nul
setlocal enabledelayedexpansion
for /l %%x in (1,1,%MaxLoop%) do (
if "!running!"=="True" for /l %%y in (1,1,%WaitForMinutes%) do (
if "!running!"=="True" (
set running=False
REM call Pop-Up
cscript /nologo %tmp%\tmp.vbs
if !errorlevel!==-1 (
for /f "skip=3" %%x in ('tasklist /fi "IMAGENAME EQ %ProgramName%"') do set running=True
) else (
taskkill /im %ProgramName%
)
)
)
)
if exist %tmp%\tmp.vbs del %tmp%\tmp.vbs
This code uses VBScript to make a pop-up box. Clicking OK will cause %ProgramName% to be killed via taskkill.
If you do not want to use a pop-up window, you can use timeout by removing...
REM Use a VBScript popup window asking to terminate %ProgramName%
echo set WshShell = WScript.CreateObject("WScript.Shell") > %tmp%\tmp.vbs
echo Wscript.Quit (WshShell.Popup( "Click 'OK' to terminate %ProgramName%." ,10 ,"Terminate %ProgramName%", 0)) >> %tmp%\tmp.vbs
...and replacing this...
REM call Pop-Up
cscript /nologo %tmp%\tmp.vbs
if !errorlevel!==-1 (
...with this:
REM Use CTRL+C to kill %ProgramName%
timeout /t %WaitForSeconds% /nobreak
if !errorlevel!==0 (
Using /nobreak is necessary because timeout does not distinguish between pressing a key or timing out. This will allow you to terminate %ProgramName% by pressing CTRL+C , but that causes your batch file to ask Terminate batch job (Y/N)? when you do. Sloppy/Messy/Nasty IMHO.
You could instead use CHOICE by replacing the above mentioned code with this:
REM Using choice, but choice can get stuck with a wrong keystroke
Echo [K]ill %ProgramName% or [S]imulate %WaitForSeconds% Seconds
Choice /n /c sk /t %WaitForSeconds% /d s
if !errorlevel!==1 (
But choice brings it's own set of limitations to the table. For one thing, it will stop it's countdown if a key that is not among it's choices (in this case s and k) has been pressed, essentially locking up until a correct choice is made. Second, the SPACEBAR cannot be a choice.

>> Login screen : From Batch to VBscript and again to Batch <<

I am running a batch script and somewhere the user has to access a database.
At this moment, a window made in vbscript would prompt asking the user to type in the login and password. (OK, Cancel buttons)
If the credentials are correct after the OK, the batch would continue according to planA, otherwise the batch would do something else going to planB. If (Cancel), it would return to the batch and the menu above.
#echo off
:Ini
echo [1] Access database
echo [2] Main menu
echo:
set /p Quest= What do you prefer (1 / 2)?
if not '%Quest%'=='' set Quest=%Quest:~0,1%
if '%Quest%'=='1' goto VBS
if '%Quest%'=='2' goto BATCH
echo Invalid option, please try again
cls
goto Ini
:BATCH
echo Heading for main menu ...
goto Main
:VBS
cscript login.vbs
(...)
-- How to continue and make the vbs?
-- How to capture the user information, validate it and go back to the batch for the planA or planB ...
-- How to mask that password with ** ** ?
Help will be greatly appreciated !
Better switch to vbscript entirely (or since you seem new to vbscript another language more recent and powerfull while keeping it easy like Ruby). Everything you start from the batch can also be done in Vbscript, you can use prompt for the menu and inputbox for the password and if it has to be masked use a the browser as UI like the script from Rob Vanderwoude here http://www.robvanderwoude.com/vbstech_ui_password.php
Using this technique you can do all the UI/GUI in Internet Explorer and the logic in Vbscript.
If you decide to keep the batch approach, you can exit a vbs script with Wscript.Quit X, where x is the errorlevel you pass to windows when the script finishes, you can then trap that errorlevel in the batch. Alternative is to set or change an environment variable to do the trasfer of data, and last you can write data to textfiles easily in script and batch but the parsing of this in batch is more difficult.
I have found an intersting alternative as described below
http://www.computerhope.com/forum/index.php?topic=103686.0
VBSscript embeded in BATCH
#echo off
:wscript.echo InputBox("Enter your password","VBScript-Batch")
findstr "^:" "%~sf0" | findstr /i /v ":Label" >temp.vbs
for /f "delims=" %%N in ('cscript //nologo temp.vbs') do set pass=%%N
del temp.vbs
echo You entered %pass%
:Label1
echo continue from here
If %pass%=="ok" echo Valid Password ! & goto EOF
If %pass%=="ok" echo Invalid Password !! & goto EOF
:EOF
pause
As you see, if we eliminate the "& goto EOF" the script works well. It sends the VBS input "pass" to the batch and the batch echoes "continue from here", from where the rest of your code goes.
However, it is not working as it should. Any help to make this really work ?
Another alternative is ....
I have added in the existing VBSscript for "Internet Explorer version" the code :
VBS SCRIPT - named Password.vbs (see full script in the above link from Peter)
strPw = GetPassword( "Please, type your password:" )
WScript.Echo "Your password is: " & strPw
Sub Submit_OnClick
dim filesys, filetxt, FormContent
Set FormContent = document.getElementById("strPw")
Set filesys = CreateObject("Scripting.FileSystemObject")
Set filetxt = filesys.OpenTextFile("C:\\temp.txt", 8, True)
filetxt.WriteLine(FormContent.value)
filetxt.Close
End Sub
BATCH SCRIPT
#echo off
cscript Password.vbs
findstr /B /E /M %strPw% temp.txt
If %ERRORLEVEL% EQU 0 echo Password matched! & goto EOF
If not %ERRORLEVEL% EQU 0 echo Invalid Password !! & goto EOF
:eof
pause
The file temp.TXT should be sent to the c:\ with the information the user typed on the inputbox. The batch would read this input and compare to a set password and continue the coding...
How can I make this work?? the temp.TXT is not generated an so forth ...
BATCH and VBS gurus out there, any help to solve these problems is really welcomed !

Resources