серверянин писал(а):Это не проблема.
Если не проблема, то просто используй START.
серверянин писал(а):Просто хочется знать: как написать такую прогу, которая позволяла бы просто ставить себя в .BAT .
Любая программа и так позволяет просто вставить свой вызов в .BAT.
серверянин писал(а):Для пользователя удобнее.
Как раз таки для большинства пользователей удобно, чтобы программы из батника работали в порядке очередь — одна отработала, запускается другая, затем следующая. Если вторая команда будет запущена до того, как отработает предыдущая, в большинстве случаев бывает черт знает что, потому что обычно последующая программа использует результат работы предыдущей.
Поэтому то, что программы запускаются по порядку — это не фишка запускаемой программы и не недостаток запускаемой программы, это фишка интерпрератора BAT-файлов. Это на уровне интерпретатора заложена такая логика работы. Нет чего-то такого, что можно было бы сделать внутри программы, чтобы на это повлиять Нет чего-то такого, что можно было бы наоборот не делать внутри программы, чтобы на это повлиять.
И это то, что нужно и удобно 99% людей. Так, во-первых, если программы выводят что-то в консоль/stdout, то они могут свои сообщения об успехе, прогрессе или ошибках выводить по очереди: а в твоём случае они все будет одновременно выводить текст и он превратится в мешанину. Во-вторых, если какая-то программа отработала с ошибкой, это позволяет не запускать последующие шаги.
серверянин писал(а):Поэтому я хотел выяснить - не существует ли каких-нибудь других путей, может с API что-нибудь.
Кроме как «породить другой процесс, а самому скоропостижно умереть» — других подходов нет и быть не может. Другой вопрос, что при порождении другого процесса (дочернего) в качестве сигнала ему, что он дочерний, можно вместо ключа командной строки пользоваться другими средствами.
серверянин писал(а):Ведь сама утилита START это как-то же делала.
Нет такой утилиты. Это встроенная команда интерпретатора BAT-файлов, а не отдельная утилита. Тем не менее, если бы это была утилита, суть её работы заключалась бы просто в том, чтобы породить
серверянин писал(а):неизбежен ли перезапуск вторым экземпляром (с параметром или иными способами), или можно освободить текущий процесс, не закрывая его?
Ни малейшего шанса. Нет никакого «освобождения» — это целиком частная инициатива CMD.EXE — ждать, пока порождённый ею процесс не завершится и ничего не делать дальше, пока этого не произойдёт. CMD.EXE порождает новый процесс для твоей команды с помощью
CreateProcess, а затем вызывает
WaitForSingleObject, чтобы дождаться его перехода в терминированное состояние. Учитывая это, даже используя грязный хак и внедрившись из дочерней команды (то есть твоей программы) в адресное пространство CMD.EXE и делая там что угодно, никак нельзя прервать или отменить ожидание. Учитывая, что WaitForSingleObject переходит в режим ядра и оттуда не вернётся, пока процесс (идентифицируемый переданным хендлом) не перейдёт в нужное состояния, нет абсолютно никакого способа ни из вызванного процесса, ни из самого CMD.EXE прервать это ожидание. Даже таким грязным хаком, как
SetThreadContext, поменяв EIP, не получится ровным счётом ничего, потому что это, во-первых, контекст пользовательского режима, и на контекст потока в режиме ядра это вообще никак не повлияет, а во-вторых, сам поток, вызвавший
WaitForSingleObject, находится в состоянии
wait:executive — это значит, что до перехода ожидаемого объекта в нужное состояния поток вообще не рассматривается планировщиком задач, планировщик задач вообще не переключается на этот поток, не даёт ему квантов процессорного времени. И поскольку
WaitForSingleObject (в отличие от
WaitForSingleObjectEx) не позволяет делать alertable wait, то и попытка прислать APC этому потоку, чтобы заставить его начать делать что-то другое (вместо ожидания), не сработает.
В общем, абсолютно никаких шансов и технических решений, кроме как твоей программе запускать какую-то другую программу (включая саму себя), а самой тут же умирать.
получилась страшная дребедень и я бросил тот вариант.
Значит, как-то криво делал.