How to wait until a cmd command ends until performing the next task? - mean-stack

I have a script that uses Ctrl+j to run
mongod (the mongo server)
mongo (the mongo database)
npm start (starts node's web server)
Opens localhost:3000 in Chrome.
Each task must be ready before the next one can start. For instance, mongod is the mongo server, so if mongo starts before the server is ready, an error will occur.
Here's my script:
// Start or stop mongod, mongo, node
^j::
IfWinNotExist, npm // start everything up. This must be done in order, but the timing varies.
{
// Start the mongo server
Run, mongod.exe
WinGet, active_id, ID, A // Get the id of the window
GroupAdd, One, ahk_id %active_id% // Add the window to a new Group so we can minimize them all later
Sleep 1000 // This works, but the time varies. I'd like to replace it
// Start the mongo database
Run, mongo.exe
WinGet, active_id, ID, A
GroupAdd, One, ahk_id %active_id%
Sleep 1000 // I'd like to replace this
// Start the node server
Run, cmd.exe
Sleep 100
send, cd webroot{\}{enter}
Sleep 300
send, npm start{enter}
WinGet, active_id, ID, A
GroupAdd, One, ahk_id %active_id%
Sleep 1000 // I'd like to replace this
// Minimize all the cmd windows
WinMinimize, ahk_group One
// Always opens a new tab - but that's for another question...
Run, chrome.exe http://localhost:3000
} else { // shut everything down if they're already running
SetKeyDelay, 400
ControlSend, ,^cy{enter}, npm
SetKeyDelay, -1
Sleep 1000
WinClose, ahk_class ConsoleWindowClass
SetTitleMatchMode 2
ControlSend, ,^c, mongo
Sleep 1000
WinClose, ahk_class ConsoleWindowClass
ControlSend, ,^c, mongod
SetKeyDelay, 200,
Sleep 1000
WinClose, ahk_class ConsoleWindowClass
}
Return
// Bonus for anyone that's interested in using this script.
// Recycle the node server in the background
!`::
SetKeyDelay, 200
ControlSend, ,^c y{enter} npm start{enter}, npm
Return
Is there a way to wait until the services are completely started before moving to the next task?
Edit: Changed the structure of the code to put the important section closer to the top.

Per my comment, try:
...
SetKeyDelay, 400
ControlSend, ,^cy{enter}, npm
SetKeyDelay, -1
Sleep 1000
WinClose, ahk_class ConsoleWindowClass
WinWaitClose, ahk_class ConsoleWindowClass, , 3
SetTitleMatchMode 2
ControlSend, ,^c, mongo
Sleep 1000
WinClose, ahk_class ConsoleWindowClass
WinWaitClose, ahk_class ConsoleWindowClass, , 3
...
Hth

In AutoHotkey scripts, some methods to replace Sleep are:
- WinWaitActive or WinWait ('win wait exist').
- Retrieving a process's PID on creation via the Run command.
e.g.
DetectHiddenWindows, On
Run, mongod.exe, , , vPID1
WinWaitActive, ahk_pid %vPID1%
WinGet, hWnd1, ID, ahk_pid %vPID1%
Run, mongod.exe, , , vPID2
WinWaitActive, ahk_pid %vPID2%
WinGet, hWnd2, ID, ahk_pid %vPID2%
;then later
WinMinimize, ahk_id %hWnd1%
WinMinimize, ahk_id %hWnd2%
AutoHotkey is good at doing everything that bat files do,
for example if can retrieve StdOut.
Generally speaking you should not need to open cmd.exe and type things in.
You can use cmd.exe (ComSpec) and specify a path/target.
This example selects a file in a folder.
(Tested on Windows 7.)
vPathNotepad = C:\Windows\System32\notepad.exe
Run, %ComSpec% /c explorer.exe /select`, "%vPathNotepad%",, Hide
Note: literal commas need to be escaped in a Run command with a backtick,
but not when a variable is assigned, notice the backtick after the word 'select' above, but not below.
Or an easier to follow rewrite:
vPathNotepad = C:\Windows\System32\notepad.exe
vTarget = %ComSpec% /c explorer.exe /select, "%vPathNotepad%"
Run, %vTarget%,, Hide
If you want a process to run, and wait for it to terminate,
before doing anything else you can use RunWait instead of Run.
e.g.
vPath = C:\webroot\npm.exe ;or whatever the path is
RunWait, %vPath%
It is also possible to start a process with the windows hidden/minimised.
e.g.
Run, %vPath%, , Hide
Run, %vPath%, , Min
RunWait, %vPath%, , Hide
RunWait, %vPath%, , Min
Are mongo and mongod, command line, or GUI?
If they are GUI there may be other things that one can detect,
to determine what to do, such as retrieve text from controls.
[EDIT:]
Useful links:
Run a command line tool on every files and (sub)folders even those containing spaces - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=26819
Regarding Chrome, 'Always opens a new tab - but that's for another question...', some functions that I wrote:
Firefox/Chrome, get tab names/focus tab - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=26947&p=126248#p126248

Related

Spawning processes on Windows with Rust

I'm on Windows 10, and trying to spawn processes with std::process::Command. There are some apps that I want to open with Command::new("cmd"), and then pass in an argument. For example, I want to pass in start ms-settings:windowsupdate as well as start ms-settings:appsfeatures, which would open "Windows Update" and "Apps & Features" in "Windows Settings". However, as it stands, you cannot have more than one instance of "Windows Settings" open at a time. So, I want to open those specific processes one at a time, and when I close one process, I want the other one to spawn. The only way I've managed to do it is by doing:
let processes = [
"start ms-settings:windowsupdate",
"start ms-settings:appsfeatures"
]
for process in &processes {
Command::new("cmd")
.arg("/K")
.arg(&process)
.creation_flags(0x00000010) // CREATE_NEW_CONSOLE
.status()
.expect("Process could not be spawned.");
}
which works, but it will open a command prompt when the first process spawns, and the only way to spawn the next process is to close the command prompt that the first process opens (opposed to just closing the window itself). I've tried other flags in .creation_flags(), but the other flags will open all processes at once, so only the last start ms-settings: process will be opened, since there can't be more than one instance. Is there a way to spawn these processes one at a time, without having a command prompt also spawn?

Windows Task Scheduler - Run task nonstop

I have a task/script, that I need to run nonstop.
However, I have set up the task, and I keep trying to run it. It does run, but after I refresh the tasks, it stops, says "Ready," and also says "Task Completed."
The thing is, I was able to do this before, and it continued running.
My question is, how can I make Task Scheduler continue to run nonstop? Any help would be appreciated.
The Task-Scheduler can not automatically wait on every derived process / application beeing executed. Once the main handle "finishes", the task is considered completed, and it's status turns to ready, even if there is still stuff running in the Background.
Example:
Consider two tasks, with the following actions:
Program cmd.exe, Parameters: /c pause
Program cmd.exe, Parameters: /c "start cmd.exe /c pause"
In case 1, the taskscheduler will say "running", until the cmd window closes. (Which is what you are asking for?) Case 2 invokes an action from within the first cmd window. So, even if the SECOND cmd-window remains open, the process created by the taskscheduler itself terminates - hence it considers the execution completed and switches back to "ready".
So: Make sure, your main-process started by the task scheduler (and maybe invoking other processes) does not end, before all the work is done.
in the above example, this could be achived like
Program cmd.exe, Parameters: /c "start /wait cmd.exe /c pause"
window 2 will be "paused" and window 1 waits for window 2 to close, leaving that process in an active state. So, the task scheduler keeps displaying "running".
to provide a less generic answer, you should update your question with more information: What task are you executing? What kind of script is it? What are you task settings, and what is your expected behaviour?

Command prompt started from batch file closes when operation is stopped

I am using a batch file to open a number of command prompts while I do some development work, however, I often need to restart 1 or more of the programs, while I'm debugging.
Is it possible to change the code to keep the window open to allow me to restart the application?
C:\
cd /d "C:\Users\me\mydir"
start redis-server
start celery worker -A celery_worker.celery --loglevel=info
start python manage.py runserver
I'd like to be able to kill and restart the celery worker / webserver whenever I make a change to the code.
START attempts to start the program directly; if the program uses stdin and stdout, this will invoke the console host to handle it. If you want a window that will remain open, instead of using START, try CMD /K - for the celery command line specifically, change start celery ... to CMD /K celery .... This starts a command prompt and runs the specified command; if the command terminates, the command prompt will remain, waiting for input (and will remain open until you exit it). Look at the output of CMD /?, or the page on cmd at SS64 for more information.

openining xterm and sending commands from xinitrc

In my xinitrc file, how can I execute commands after the xterm has opened so that I can use xdotool to move the mouse etc ?
xterm -geometry 132x45+0+0
xdotool windowfocus
xdotool mousemove 100 100
xdotool click 1
In this example, the xdotool command only execute when xterm quits, I can't add & to the command line for xterm as it will not remain open ?
.xinitrc is a shell script and usually exits with an exec to start your the last application or window manager. When this last application quits, the X session finishes.
Any application started before reaching the end of the script must be stated asynchronously by using a trailing &.
You could end the script with a sleep forever statement (for example this one) to keep the X session open.
Your overall plan is error prone, however, as there is no guarantee that Xterm will be fully stated before the ancillary operations are executed.

Setup timeout for commands in Windows .bat file

I wrote a windows .bat script. To run a list of commands and then shut down the computer.
such as:
c:\someapplication.exe
c:\someapplication2.exe
Shutdown -s -t 0
Sometimes, "c:\someapplication.exe" freezes and do not respond. How can I setup timeout for my command "c:\someapplication.exe", so that after a certain amount of time, I want windows to force close the application and continue the rest of the commands?
You could use a combination of ping and taskkill to do this.
start c:\someapplication.exe
ping 127.0.0.1 -n seconds
taskkill /im someapplication.exe /f
start c:\someapplication2.exe
ping 127.0.0.1 -n seconds
taskkill /im someapplication2.exe /f
Shutdown -s -t 0 /f
Just replace seconds in the ping command with the number of seconds you want to wait before attempting to close the process (enough time so if it's still running it must have crashed). Then the rest of the app can continue until it is forced to shutdown.
if you may afford that all someapplications run in parallel try this
start someapplication
start someapplication2
wait n secons
shutdown
choose your value of n so that it does not proceed with shutdown while someapplications still run legit
or alternatively
start someapplication
wait n seconds
start someapplication2
wait m seconds
shutdown
for wait there are many solutions around, google some bat wait timeout
You can run your exe program and the shutdown command at once and put the timeout in shutdown options [-t].
To run multiple command at once, use "start" command ("start [yourProgram.exe]").
To do force shutdown use [-f] option.
good luck

Resources