Показать полную графическую версию : запуск в свернутом виде (start /min, cmd /K, exit)
CyberMuesli
12-06-2012, 01:43
В Win9x команда start была отдельным исполняемым модулем start.exe
В WinXP/server START стала командой CMD.EXE со следующими нюансами:
даже если указан ключ /MIN все равно кратковременно мигает черное окошко, в котором запускается сам CMD.EXE, выполняющий команду START.
если с помощью START запускается BAT-файл, то он запускается с использованием CMD /K, при этом окно CMD после завершения BAT-файла не закрывается
последнее обстоятельство приводит к весьма существенным затруднениям.
Если ваши сценарии простые, проблема покажется несущественной и надуманной. В таком случае пост не для вас. Почувствовать проблему можно только, если ваши сценарии достаточно сложны и взаимосвязаны, могут запускаться непосредственно, из других сценариев, а также могут запускаться из планировщика (также непосредственно или косвенно).
Допустим, есть BAT, который прекрасно работает. Мы его решили запускать через start /min из планировщика. Всего-то изменение способа запуска повлечет неприятную необходимость менять код: все goto :eof придется заменить на EXIT + поставить EXIT в конце (иначе окно не закроется и со временем накопится столько незакрытых черных окон, что сервер упадет). При этом BAT станет непригоден для использования, если он вызывается из другого BAT (т.к. завершится весь процесс CMD). Получается, если ставить цель написать сценарий, корректно работающий в различных вариантах запуска, необходимо следовать правилу, согласно которому, каждому сценарию должна в параметрах передаваться информацию о способе его запуска, а этот сценарий, в свою очередь, должен снабжать этой же информацией другие сценарии в цепочке, передавая ее параметрах вызова.
Все это крайне неприятно, если не иметь отдельный исполняемый EXE модуль (как в Win9x), выполняющий запуск процесса/сценария в свернутом виде.
Я решил проблему такой программкой на дельфи. Это снимает все негативные моменты + дает дополнительный бонус в виде отсутствия мелькания черных окон и/или сбивания фокуса при запуске из планировщика. Первый параметр - имя процесса (можно указывать EXE и также непосредственно BAT, без полного пути и расширения), остальные - параметры запускаемого процесса. Например:
startmin cmd /c dir c:\*.*
startmin "c:\Admin scripts\daily backup.bat" "\\server\common files\*.*"
program startmin;
uses
SysUtils, Windows,ShellAPI;
var Param,ProgCmdLine:AnsiString; i:integer;
begin
ProgCmdLine := '';
for i:= 2 to ParamCount do begin
if i >= 3 then
ProgCmdLine := ProgCmdLine +' ';
Param := ParamStr(i);
if Pos(' ',Param) <> 0 then
Param := '"'+Param+'"';
ProgCmdLine := ProgCmdLine + Param;
end;
ShellExecute(0,nil,PChar(ParamStr(1)),PChar(ProgCmdLine),nil,SW_SHOWMINNOACTIVE);
end.
Было бы интересно послушать мнения по данному вопросу.
выложите скомпилированную программу, а то скачивать delphi ради одной программы не хочется
CyberMuesli
12-06-2012, 01:55
выложите скомпилированную программу, а то скачивать delphi ради одной программы не хочется »
Моё мнение таково:
* лично я всегда использую «exit /b», а не «goto :eof», так что, «придётся менять» — мимо;
* не вижу никакого смысла в сворачивании окон консоли командного процессора, ни из планировщика, ни интерактивно.
CyberMuesli
12-06-2012, 08:18
лично я всегда использую «exit /b», »
exit /b не закроет окно CMD, только exit
не вижу никакого смысла в сворачивании окон консоли командного процессора, ни из планировщика, ни интерактивно. »
Пара примеров.
Вы сидите в редакторе и занимаетесь копипастой. Неожиданно в планировщике срабатывает скрипт, перехватывает фокус ввода (что само по себе неприятно) и натыкается на Ctrl-C, предназначенное редактору (что неприятно вдвойне)
Скрипт вызывает несколько скриптов (например 255), которые могут быть выполнены как последовательно (что долго), так и параллельно и запускаются через start. Чтобы не прерывалось наблюдение за основным скриптом удобно запускать не просто через start, а через start /min
Как ни странно, программы могут вызывать скрипты, при этом такие вызовы могут происходить даже в диалоговом окне. Сбивание фокуса ввода и мелькание окон по ходу расстановки галок весьма неприятная вещь.
Foreigner
12-06-2012, 08:30
Надуманная проблема, имхо. Что легче использовать сторонний бинарник или прописать exit в батнике?
CyberMuesli
12-06-2012, 08:54
Надуманная проблема, имхо. Что легче использовать сторонний бинарник или прописать exit в батнике? »
Я написал, в чем затруднения с exit. Если проблема кажется надуманной - просто пройдите мимо.
и натыкается на Ctrl-C, »
Не-а ;). Я использую Ctrl-Insert.
Скрипт вызывает несколько скриптов (например 255), которые могут быть выполнены как последовательно (что долго), так и параллельно и запускаются через start. Чтобы не прерывалось наблюдение за основным скриптом удобно запускать не просто через start, а через start /min »
Логично. Но, простите, что Вы собираетесь наблюдать в основном скрипте, если он при этом теряет всякую связь с дочерними?
CyberMuesli
12-06-2012, 09:14
что Вы собираетесь наблюдать в основном скрипте, если он при этом теряет всякую связь с дочерними? »
почему он теряет связь? он ждет результатов
почему он теряет связь? он ждет результатов »
Каким образом? Поясните.
CyberMuesli
12-06-2012, 11:19
Каким образом? Поясните. »
Поясните, каким образом он теряет связь?
результатом может быть наличие-отсутствие файлов-семафоров, доступность ресурсов, состояние аппаратуры - что угодно
То бишь, чтобы организовать связь, дочерний пакетный файл всё одно придётся править.
CyberMuesli
12-06-2012, 14:53
То бишь, чтобы организовать связь, дочерний пакетный файл всё одно придётся править. »
Вы явно про что-то своё
Связь может быть организована в обратном направлении: родительский скрипт может проверить результаты работы параллельных дочерних скриптов, которые не надо ни коим образом подправлять.
Так или иначе любые действия приходится программировать. Мне кажется, Вы не уловили основную мысль: речь не о том, что startmin волшебным образом позволяет ничего не делать, а о том, что дочерний скрипт можно писать, не думая о том, каким способом он вызван и как обеспечить закрытие окна CMD.
Foreigner
12-06-2012, 15:39
Я написал, в чем затруднения с exit. Если проблема кажется надуманной - просто пройдите мимо. »
Я высказал свое мнение. Так что не хамите.
Чтобы не прерывалось наблюдение за основным скриптом удобно запускать не просто через start, а через start /min »
Запускайте через start /b и не будут мелькать окна.
CyberMuesli
12-06-2012, 15:46
Я высказал свое мнение. Так что не хамите. »
Поскольку буквы не передают интонации, значит Вы их выдумали сами.
Мнение немного поверхностное, я написал в чем трудности с EXIT. start /b забавный ключ, но не запускает программу в свернутом виде, а так же не избавляет от необходимости предпринимать специальные меры для закрытия окна CMD после завершения скрипта. Все это следствие того, что проблема кажется Вам надуманной и Вы не хотите в нее вникнуть.
Foreigner
12-06-2012, 15:56
так же не избавляет от необходимости предпринимать специальные меры для закрытия окна CMD после завершения скрипта »
ЧЯДНТ? У меня все отрабатывает и закрывается основное окно ( назовем main.cmd ), после того, как отработали все экземпляры запускаемых из него батников. Пример:
:: main.cmd
@echo off
start /b cmd /c "2.cmd"
start /b cmd /c "3.cmd"
echo 1 2 3
exit /b
:: 2.cmd и 3.cmd
@echo off
echo.
for /l %%i in (0,1,3) do echo %%i
1>nul ping -n 3 ya.ru
echo exit
exit /b
Второй и третий батник одинаковые
CyberMuesli
12-06-2012, 17:47
ЧЯДНТ? У меня все отрабатывает и закрывается основное окно ( назовем main.cmd ), после того, как отработали все экземпляры запускаемых из него батников. »
Вы все делаете не так. В предыдущем сообщении я сказал, что start /b не запускает программу параллельно в свернутом виде (т.е. в отдельном свернутом окне), а так же не избавляет от необходимости предпринимать специальные меры для закрытия окна CMD после завершения скрипта. Вы это проигнорировали и настаиваете, что start /b решает эти проблемы.
Кроме того, ключ /B приводит к полному хаосу в стандартном вводе и выводе, потому что окно одно на всех.
Кроме того, вы не видите, что main.cmd заканчивает свою работу РАНЬШЕ 2.cmd и 3.cmd, а не наоборот, как вы утверждаете.
Кроме того, вы не поняли, что моя цель - вовсе не закончить 2 и 3 раньше, чем main.
Итого, вы уводите беседу очень далеко и совсем в другую сторону.
Foreigner
12-06-2012, 18:23
start /b не запускает программу параллельно
Запускает параллельно, а не последовательно, иначе пауза длилась бы не 2 секунды, а 4.
а так же не избавляет от необходимости предпринимать специальные меры для закрытия окна CMD после завершения скрипта
Запускаю главный батник, он отрабатывает и закрывается, затем, после того, как отработают остальные, закрывается само окно хоста.
http://storage5.static.itmages.ru/i/12/0612/s_1339509751_3562857_9c04253548.png (http://itmages.ru/image/view/552411/9c042535)
main.cmd заканчивает свою работу РАНЬШЕ 2.cmd и 3.cmd, а не наоборот, как вы утверждаете.
В нем нет паузы, понятно, что он заканчивает раньше. Он запустил, и все, работу выполнил.
ключ /B приводит к полному хаосу в стандартном вводе и выводе
Зато не надо открывать много окон, что тоже плюс. Если есть необходимость смотреть вывод только главного батника, то можно скрывать вывод в запускаемых:
start /b cmd /c "1>nul 2.cmd"
моя цель - вовсе не ожидание не закончить 2 и 3 раньше, чем main.
Не совсем понял. Они заканчивают свою работу, как только отработают свой код. Какой раньше, а какой позже зависит только от этого.
CyberMuesli
12-06-2012, 18:55
Цитата:
start /b не запускает программу параллельно
Запускает параллельно, »
Цитируйте полностью! "Было бы величайшей ошибкой думать" В.И.Ленин, ПСС, т.4
Не запускает параллельно в свернутом окне.
Не совсем понял »
Вот! Именно с этого я и начал.
Вы не уловили основную мысль: цель - чтобы дочерний скрипт можно писать, не думая о том, каким способом он вызван и как обеспечить закрытие окна CMD. Ваш способ start /b имеет дополнительные недостатки с выводом + не обеспечит закрытие окна в случае запуска из планировщика задач через start /b или start /min. Если же Вы замените exit /b на exit в main.cmd, вы сделаете этот скрипт непригодным для вызова в качестве дочернего из другого родительского скрипта.
Foreigner
12-06-2012, 19:31
Если же Вы замените exit /b на exit в main.cmd, вы сделаете этот скрипт непригодным для вызова в качестве дочернего из другого родительского скрипта. »
Ничего не изменится. Можно смело убрать из всех exit ключ /b . Или вообще убрать exit из дочерних, cmd /c лишнего не отработает, только батник.
Не запускает параллельно в свернутом окне. »
А оно надо? Я вообще запускаю в фоне. Ну раз вам не нравится, то рассматривайте, как альтернативу. Или вообще не рассматривайте, дело ваше.
не обеспечит закрытие окна в случае запуска из планировщика задач через start /b или start /min. »
Попробовал, запускает и закрывает окно без лишних движений. Но надо в планировщик, например:
schtasks /create /sc once /tn test /tr "cmd /c start /min c:\path\to\1.cmd" /st 19:29
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.