I'm not a batch coder, but I'm trying to create a script that does the following once executed:
enables the dedicated video card (laptop NVIDIA card)
runs a specific video game and waits for its end
once the game is terminated, disables the dGPU
The following code works great with simple programs like notepad.exe, since they start immidiatly:
// enable dedicated GPU
devcon enable "#PCI\VEN_10DE&DEV_1C8C&SUBSYS_8259103C&REV_A1\4&3455E2C8&0&0008"
// start notepad and wait for its termination
start /b /wait "" "C:\Windows\notepad.exe" || goto QUIT
:QUIT
// disable dedicated GPU
devcon disable "#PCI\VEN_10DE&DEV_1C8C&SUBSYS_8259103C&REV_A1\4&3455E2C8&0&0008"
exit
The problem is that if I change "notepad.exe" for some heavy video game (BF1 for example) which takes some time to start, the script doesn't wait for game's actual launch and proceeds with other command. So the result is:
GPU is turned on
GPU is turned off (script exit)
After some time game starts (using Intel Graphics)
Is there a way to make the second command (start /wait) wait for game's actual launch?
The reason I need this script is: NVIDIA Optimus + Windows 10 = micro freezes
PS: sorry for my english.
// start game launcher
start /b /wait "" "launcherexecutable"
:wait
timeout 5 >nul
tasklist |findstr /i /L /c:"launcherexecutable" /c:"gameexecutable" >nul
if not errorlevel 1 goto wait
:QUIT
which should repeatedly delay for (5 seconds) then see whether either the launcher or the game executable is running and repeat the loop if so.
Hence, should proceed to quit once the game executable finishes.
Obviously, change the 5 to some other value or add intermediate executablenames as appropriate.
Related
I have searchewd a few posts here, but I cannot find one that is exactly what I am looking for. In simple terms I am trying to send a character to my Arduino via bluetooth Automatically.
I have tried both Putty and Plink, but neither work automatically. Here is the commands I have tried so far:
command.bat | putty -serial com3 -sercfg 9600
Command.bat:
#echo off
timeout /t 5
echo 2
and
plink -load Arduino echo 2
This connects to the bluetooth adapter on the Arduino, but opens an Interactive console. I can hit the number 2 on the keyboard it is sends it correctly. However I want that to be sent automatically. I have timeout in there because it takes a few seconds to connect to the bluetooth.
Is there a way to do this so I can just run a bat file and have it send the commands automatically?
If the interactive console opens up and is the most present item, you can use the following code upon the interactive console startup...
#if (#CodeSection == #Batch) #then
#echo off
set SendKeys=CScript //nologo //E:JScript "%~F0"
rem wait for interactive console to appear before pressing 2 to initialize
timeout /t 5
%SendKeys% "{2}"
goto :EOF
#end
// JScript section
var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.SendKeys(WScript.Arguments(0));
Call it a cheap fix if you will, the code will call a javascript to press 2 for you. Im not sure how to tie it with your absolute program but this will run it automatically as the computer will simulate the input for you.
I'm using a network management tool to apply updates to software and I have an issue where if a users is already using the program you want to update the update will fail as you would expect.
I have been trying to put together a batch script that will detect whether the the program is running and if it is the script will wait until the user closes down the program and the apply the msi update.
I've pretty much scoured google but can only really find previous scripts that kill the program first before proceeding and I don't want that to happen as the user may lose work.
Hope someone can help!
#echo off
start "" notepad.exe
:loop
(tasklist | find /i "notepad.exe" && ( ping -n 2 localhost & goto loop)) >nul
echo Notepad closed
This just starts notepad.exe (the running program) and waits until it is closed. Adapt according to your needs
`tasklist |find "programname"`
will tell you if the programm is running:
if %errorlevel%==0 echo running
put just a little loop around it:
:loop
tasklist |find "programname" >nul
if %errorlevel%==0 (
echo prgram running
timeout 2>nul
goto loop
)
echo program not running
I hope that makes sense. I want to create a batch file or anything similar that will cycle through a few Processing applications for a presentation. Is there a way I can do this that will execute an application by time intervals, close before executing the next one, and then cycle back to the first application?
Certainly.
#ECHO OFF
SETLOCAL
:loop
FOR %%i IN ("process1.exe 20" "process2.exe 30" "process3.exe 10") DO CALL :cycle %%~i
GOTO loop
:cycle
START %1
timeout /t %2 >nul
TASKKILL /im %1 >nul
GOTO :eof
runs process1 for 20 sec, process2 for 30 - Got the pattern? The processes are terminated unceremoniously.
Press control-C and reply Y to terminate - will leave the last process invoked running.
Addendum:
TASKKILL knows nothing about "paths" - only the executable name.
hence, on the line after after the setlocal add
set path=C:\Users\MyName\Documents\School\Processing\Sketch_8\application.windows32;%path%
and specify the executable only in the FOR statement.
If there's more than one directoryname involved, just string them together with ; separators and ;%path% at the end.
Windows picks up the executable from the path by looking first in the current directory, then each directory on the path in turn until it finds the required executable. Adding the extra directories occurs only for the time this batch is running, and applies only to the batch's instance - it's not transmitted to any other process.
I would like to start a program with a windows batch file. But the program should stop after a certain timeout value. For example: Run the program 60 seconds and stop it after 60 seconds.
Under Linux, there is this nice timeout command to do what I want. Windows has also a timeout command, but its just to pause a command, to delay its execution. Is there something else under Windows to do so ?
Setup: Windows 7, 64 Bit, Professional
start yourprogram.exe
timeout /t 60
taskkill /im yourprogram.exe /f
Bali C gave a concise and to the point answer.
I needed something a little more featureful and reusable.
Based on Bali C's Example. I came up with this.
If anyone should need the same as me.
your.bat
REM...
CALL STARTwaitKILL..bat /relative/path/your_program.exe
REM...
STARTwaitKILL.BAT
#ECHO OFF
IF[%1]==[] GOTO EOF
IF NOT EXIST %1 GOTO EOF
REM SET PRIORITY=/NORMAL
REM ADJUST PRIORITY, BELOWNORMAL LETS BATCH FILE RUN MORE SMOOTHLY
REM WITH A PROGRAM THAT CONSUMES MORE CPU. SEE ABOUT MAXWAIT BELLOW
SET PRIORITY=/BELOWNORMAL
REM SET PRIORITY=/LOW
REM 0 NORMAL WINDOW :: 1 NO WINDOW :: 2 MINIMIZED WINDOW
SET /A HIDDEN=1
REM MAXWAIT HERE IS MORE LIKE MINIMUM WAIT IN WINDOWS.
SET MAXWAIT=10
SET WAITCOUNT=0
SET ARGS=/I %PRIORITY%
IF %HIDDEN% EQU 1 SET ARGS=%ARGS% /B
IF %HIDDEN% EQU 2 SET ARGS=%ARGS% /MIN
START %ARGS% %1
:WAIT
IF %WAITCOUNT% GEQ %MAXWAIT% GOTO KILL_IT
TIMEOUT /T 1 > NUL
SET /A WAITCOUNT+=1
FOR /F "delims=" %%a IN ('TASKLIST ^| FIND /C "%~nx1"') DO IF %%a EQU 0 GOTO RUN_DONE
GOTO WAIT
:KILL_IT
TASKKILL /IM %~nx1 /F > NUL
:RUN_DONE
Could be fleshed out ore to take more arguments for priority and such, but I don't have the need for it. Shouldn't be hard to add.
Don't exist any command in Windows to delay an app or to set a timeout for an app
Timeout in Windows is for Delay the execution process of CMD/Batfile, nothing more utility.
You can use external tools for that, I don't remember the name of any now, so many underground software, sorry, but I remember that in the autoit official forum exists a similar commandline tool to launch an app setting the timeout,
and maybe in the tool NIRCMD, or ps2exec, check their help files, or someone inside the WAIK Kits.
This is the only you can do:
#Echo OFF
:: First launch the app in background mode, because some applications stops the execution of CMD.
Start /B ".\Dir\Your app.exe"
:: Then stay in background for a certain time
Timeout /T "Seconds"
:: Continue your code...
Pause&Exit
The start+timeout+taskkill waits exactly the given time. Since I needed to stop waiting if the process exits earlier, I created my own solution in C++.
The tuxliketimeout program mimics the GNU timeout. Feel free to download&compile from
https://github.com/cernoch/tuxliketimeout
In windows 10 the easiest way is with scriptrunner:
Demonstrate the timeout by running a pause command (this will kill the called process):
ScriptRunner.exe -appvscript cmd "/c" "pause" -appvscriptrunnerparameters -wait -timeout=20
I'm using a batch file to stop a Windows service. I'm using the sc command, but I'm open to other ideas, given the question below. The problem is that the batch file proceeds while the service is stopping (the stop argument to sc seems only to request the stop -- it doesn't wait for the stop).
How can I modify the batch file to not proceed until the stop is complete?
You can use NET stop, which is synchronous, i.e it will wait until the service stops.
See
- NET stop
sc stop webdriveservice
:loop
sc query webdriveservice | find "STOPPED"
if errorlevel 1 (
timeout 1
goto loop
)
Another version with a repetition count limit:
sc stop webdriveservice
set count=1
set limit=10
:loop
sc query webdriveservice | find "STOPPED"
if errorlevel 1 (
timeout 1
set /a count += 1
if %count% lss %limit% goto loop
)
As mentioned above, NET STOP will send a stop command to the service, but, if the service takes more than a certain time (20 seconds or so is my observation), NET STOP will NOT wait for the service to actually stop before returning.
To actually pause the batch file until the service stops, you need to use an approach like those outlined in these threads:
How to check if a service is running via batch file and start it, if it is not running?
Stopping/Starting a remote Windows service and waiting for it to open/close
I believe net stop [Service] should wait until the service has fully stopped before moving on. sc stop [Service] simply sends a "stop" message to the service.
I had a similar issue with net stop. It returns when the service is indeed stopped, but the executable may still be running.
For upgrade reasons, this is not good enough, we need to wait until the process has finished.
I've used a simple loop to wait until the service executable has actually finished:
net stop "ServiceName"
:loop1
set _CmdResult=""
for /f "tokens=1" %%a in ('TASKLIST ^| FINDSTR ServiceName.exe') do set _CmdResult=%%a
if not %_CmdResult% == "" (
timeout 5
goto loop1
)
Once the the executable finishes, the loop will break.
This is a bit crude but it worked for me in order to ensure that I could schedule a daily batch file to essentially RESTART a service.
NET STOP [Service]
:TryAgain
TIMEOUT /T 10 /NOBREAK
NET START [Service]
IF %ERRORLEVEL% NEQ 0 GOTO TryAgain
I realize with this code snippet that this could result in an endless loop if the service was to not successfully start. I just wanted to basically show how to get around the issue using TIMEOUT where a service may take longer to stop than what the NET STOP command allows.
Use the && symbol between commands. The && symbol waits to finish the previous command before proceed to next command.
All commands must be at the same command row. You can use as many commands you want in a row.
You can use also the pause command. With this, asks to press any key, before proceed to next procedure.
For example:
sc qdescription "MyServiceName" && echo. && sc stop "MyServiceName" && echo. && echo [ "MyServiceName" service stopped ] && echo. && pause