问题
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.
回答1:
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
回答2:
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
来源:https://stackoverflow.com/questions/41617671/how-to-wait-until-a-cmd-command-ends-until-performing-the-next-task