Запустите внешнее приложение с ShellExecuteEx и дождитесь его инициализации - PullRequest
7 голосов
/ 01 июля 2011

У меня есть приложение, которое должно запускать несколько других приложений в цепочке.Я запускаю их через ShellExecuteEx.Порядок запуска каждого из приложений очень важен, потому что они зависят друг от друга.Например:

Start(App1);

If App1.IsRunning then
  Start(App2);
If App2.IsRunning then
  Start(App3);
.........................
If App(N-1).IsRunning then
  Start(App(N));

Все работает нормально, но есть одна возможная проблема: ShellExecuteEx запускает приложение и возвращает почти сразу.Проблема может возникнуть, когда, например, App1 запущен правильно, но не завершил некоторые внутренние задачи, он еще не готов к использованию.Но ShellExecuteEx уже запускается App2, что зависит от App1, и App2 не запустится должным образом, потому что требуется полная инициализация App1.

Обратите внимание, что я нехочу дождаться завершения App(N-1) и затем запустить AppN.

Я не знаю, возможно ли это решить с помощью ShellExecuteEx, я пытался использовать

SEInfo.fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_NOASYNC;

но без эффекта.

После запуска приложения AppN у меня есть дескриптор процесса.Если я предполагаю, что приложение инициализируется после создания его основного окна (все приложения имеют окно), могу ли я каким-то образом перехватить его очередь сообщений и подождать, пока не появится WM_CREATE или, возможно, WM_ACTIVATE?При наличии такого сообщения мое приложение будет знать, что оно может двигаться дальше.

Это просто идея.Однако я не знаю, как поставить такой крючок.Так что, если вы могли бы помочь мне в этом, или у вас есть лучшая идея, которая была бы отличной:)

Кроме того, решение должно работать на Windows XP и выше.

Спасибо за ваше время.

Отредактировано

@ Космический Прунд: Я не понимаю, почему вы удалили свой ответ?Я мог бы попробовать вашу идею ...

Ответы [ 3 ]

12 голосов
/ 01 июля 2011

Вероятно, вы можете достичь того, что вам нужно, вызвав WaitForInputIdle() для каждого дескриптора процесса, возвращаемого ShellExecute().

Ожидает, пока указанный процесс завершит обработку своего начального ввода, и ожидает ввода пользователя без ожидающего ввода или пока не истечет интервал времени ожидания.

3 голосов
/ 01 июля 2011

Если в вашем приложении есть какая-то пользовательская логика инициализации, которая не выполняется в потоке пользовательского интерфейса, тогда WaitForInputIdle может не помочь.В этом случае вам понадобится механизм для оповещения предыдущего приложения о том, что вы завершили инициализацию.

Для сигнализации вы можете использовать именованные каналы, сокеты, некоторый механизм RPC или простую блокировку на основе файлов.

0 голосов
/ 01 июля 2011

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

...