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

三世轮回 提交于 2019-12-12 03:58:01

问题


I have a script that uses Ctrl+j to run

  1. mongod (the mongo server)
  2. mongo (the mongo database)
  3. npm start (starts node's web server)
  4. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!