Как запустить файл bat в фоновом режиме из другого файла bat?

92

У меня есть сценарий «установки», который я запускаю утром, он запускает все программы, которые мне нужны. Теперь некоторым из них требуется дополнительная настройка среды, поэтому мне нужно обернуть их небольшими сценариями BAT.

Как запустить такой скрипт в Windows XP в фоновом режиме?

CALL env-script.bat запускает его синхронно, т.е. сценарий установки может продолжаться только после завершения команды в сценарии env.

START/B env-script.bat запускает другой экземпляр CMD.exe в той же командной строке, оставляя его в очень беспорядочном состоянии (я вижу вывод вложенного CMD.exe, клавиатура некоторое время не работает, сценарий не выполняется).

START/B CMD env-script.batдает тот же результат. Кажется, что ни один из флагов в CMD не соответствует моему счету.

Аарон Дигулла
источник

Ответы:

72

На самом деле, у меня отлично работает и создает новые окна:

test.cmd:

@echo off
start test2.cmd
start test3.cmd
echo Foo
pause

test2.cmd

@echo off
echo Test 2
pause
exit

test3.cmd

@echo off
echo Test 3
pause
exit

Объедините это с параметрами start, например /min, как указал Моше, если вы не хотите, чтобы новые окна появлялись перед вами.

Джоуи
источник
1
Хорошо, это работает, но не на 100% идеально: после того, как я нажимаю «ВОЗВРАТ» в «Тесте 2», это окно не закрывается. Любые идеи?
Аарон Дигулла,
Вы можете добавить «exit» к порожденным партиям, чтобы потом снова закрыть их. Извините, так далеко не тестировал :)
Joey
на самом деле мне было достаточно start script1.bat \ n start script2.bat \ n start scriptN.bat
andrej
142

Два года, но для полноты ...

Стандартный встроенный подход: (т.е. поведение, которое вы получите при использовании &в Linux)

START /B CMD /C CALL "foo.bat" [args [...]]

Примечания: 1. CALLсоединен с файлом .bat, потому что он обычно идет туда .. (т.е. это просто расширение CMD /C CALL "foo.bat"формы, чтобы сделать ее асинхронной. Обычно требуется правильно получить коды выхода, но это не проблема Вот.); 2. Двойные кавычки вокруг файла .bat необходимы только в том случае, если имя содержит пробелы. (Имя может быть путем, и в этом случае вероятность этого больше.)

Если вам не нужен вывод:

START /B CMD /C CALL "foo.bat" [args [...]] >NUL 2>&1

Если вы хотите, чтобы летучая мышь запускалась на независимой консоли: (т.е. в другом окне)

START CMD /C CALL "foo.bat" [args [...]]

Если вы хотите, чтобы потом оставалось другое окно:

START CMD /K CALL "foo.bat" [args [...]]

Примечание. На самом деле это плохая форма, если только у вас нет пользователей, которые специально хотят использовать открытое окно как обычную консоль. Если вы просто хотите, чтобы окно оставалось на месте, чтобы видеть результат, лучше поставить PAUSEв конце файла bat. Или еще, добавьте ^& PAUSEпосле командной строки:

START CMD /C CALL "foo.bat" [args [...]] ^& PAUSE
антак
источник
10
&является оператором «а затем» (терминология?). (например , cmd1 & cmd2средство сделать «CMD1» , а затем «Cmd2». В отличие от &&оператора, выполнение «Cmd2» не зависит от успешного выхода «cmd1») . В ^избежит &таким образом , что он переходит в аргументы CMD вместо того , чтобы быть потребляется и запускается той же консолью, на которой был запущен START.
antak
Это очень полезно, спасибо. Я был просто в порт скрипты для Linux, потому что другие путеводители по startи cmdне дают полной функциональности я искал. Ваш ответ прибивает.
Iterator
3
Если вам не нужен вывод, то перенаправление должно быть экранировано, чтобы оно было передано в CMD. Также ЗВОНОК не нужен:START /B "" CMD /C "foo.bat" [args [...]] ^>nul 2^>^&1
dbenham
1
@dbenham: Хотя то, что вы говорите, имеет смысл, START /B "" CMD /C PING 127.0.0.1 >NULпохоже, работает независимо и ничего не выводится. (Вероятно, потому что CMDнаследует STARTдескрипторы ввода-вывода.) Я полагаю, разница в том, если вы хотите сохранить STARTнетронутым вывод (ошибки), что, вероятно, является хорошей идеей. CALLпросто потому, что я чувствовал, что это хорошая практика. (т.е. неиспользование CALLдля синхронных вызовов летучих мышей приведет к непредсказуемым кодам выхода, поэтому я последовательно объединяю вызовы летучих мышей, CALLдаже если это не строго применяется, например, в этом случае.)
antak
7

Поскольку START - это единственный способ выполнить что-то в фоновом режиме из сценария CMD, я бы рекомендовал вам продолжать его использовать. Вместо модификатора / B попробуйте / MIN, чтобы вновь созданное окно вас не беспокоило. Кроме того, вы можете установить более низкий приоритет с помощью / LOW или / BELOWNORMAL, что должно улучшить отзывчивость вашей системы.

Моше
источник
-1 Проблема в том, что START не создает новое окно при запуске BAT-файла; вместо этого он повторно использует текущее окно и смешивает ввод / вывод двух процессов CMD.
Аарон Дигулла,
4
Это не создает новое окно, потому что вы используете флаг / B. Убери это.
Моше
5

За исключением термина переднего плана / фона. Другой способ скрыть рабочее окно - использовать vbscript, если он все еще доступен в вашей системе.

DIM objShell
set objShell=wscript.createObject("wscript.shell")
iReturn=objShell.Run("yourcommand.exe", 0, TRUE)

назовите его как sth.vbs и вызовите его из bat, поместите в запланированную задачу и т.д. Лично я отключу vbs без спешки на любой системе Windows, которой я управляю :)

Моя вина
источник
Для моего конкретного случая использования это было фактически единственное решение, которое я мог заставить работать ...
Бен
0

Создайте новое приложение Windows на C # и вызовите этот метод из основного:

public static void RunBatchFile(string filename)
{
    Process process = new Process();

    process.StartInfo.FileName = filename;

    // suppress output (command window still gets created)
    process.StartInfo.Arguments = "> NULL";

    process.Start();
    process.WaitForExit();
}
ЛегендаДлина
источник
2
Эээ ... Я надеялся, что что-то такое простое не потребует установки Visual Studio ...
Аарон Дигулла,
1
Пока PowerShell не станет доступным на все 100% - C # действительно избыточен.
jim
2
Аарон: Компилятор C # включен в .NET Framework 2, так что вы можете просто отредактировать код в текстовом редакторе и скомпилировать его. Тем не менее, поскольку это вполне возможно в пакетном файле, я бы также сказал, что C # избыточен.
Joey
0

Это работает с моей установкой Windows XP Home, способом Unix:

call notepad.exe & 
MiiToo
источник
7
Я думаю, что это работает только случайно, и знак & не нужен.
Сэм Уоткинс
2
Да, notepad.exe изначально является асинхронным.
antak
0

На самом деле это довольно просто с этой опцией в конце:

c: \ start BATCH.bat -WindowStyle Hidden

user8832474
источник
команда Windows startне имеет -WindowStyleопции.
Стефан
@ Стефан Аррид. C:` instead of Странный путь ( C: \ Windows`) предполагает, что он нашел инструмент где-то в Интернете и скопировал его на свой жесткий диск.
Аарон Дигулла