Выполнение EXE из EXE из EXE
У меня есть 3 программы, App1.exe, App2.exe и App3.exe. Каждый из них может запускаться независимо друг от друга, но App2.exe может запускать App3.exe с помощью ShellExecuteEx, а App1.exe может запускать App2.exe с помощью ShellExecuteEx (который, в свою очередь, может запускать App3). App3 имеет необязательные параметры командной строки, если при их использовании графический интерфейс не будет отображаться, но будет автоматически генерировать выходной файл и закрываться. Когда App2 запускает App3, передавая параметры командной строки, он работает просто отлично, но когда App1 запускает App2, который запускает App3, передавая параметры командной строки, ShellExecuteEx из App3 возвращает значение true, но GUI отображается и не создает выходной файл.
У вас есть идеи, почему это произойдет? Он работает в Windows XP, но не в Vista или 7. Я также попытался использовать CreateProcess(), который дал тот же результат. Все 3 приложения находятся в одной папке.
FillChar( exInfo, Sizeof(exInfo), 0 );
with exInfo do
begin
cbSize:= Sizeof( exInfo );
fMask := SEE_MASK_NOCLOSEPROCESS;
lpVerb:= 'open';
lpFile:= PChar('App3.exe');
lpParameters := PChar('/Param1 Param2 "' + folderpath + 'outputfile.txt"');
nShow := SW_HIDE;
end;
if ShellExecuteEx( @exInfo ) then
begin
repeat
Sleep( 500 );
GetExitCodeProcess( exinfo.hProcess, exitcode )
until (exitcode <> STILL_ACTIVE);
end;
CloseHandle( exinfo.hProcess );
1 ответ
Когда App2 запускает App3, App3 запускается точно так же, независимо от того, был ли App2 запущен напрямую или App1. Таким образом, приложение App1 под управлением App2 никак не может повлиять на то, как приложение App3 запускается приложением.
На что МОЖЕТ повлиять начальный рабочий каталог App2 и, следовательно, начальный рабочий каталог App3. Поэтому вы всегда должны использовать абсолютные пути, не только для значений параметров, но и для путей.exe. Вы также должны рассмотреть возможность использования SHELLEXECUTEINFO.lpDirectory
поле для указания начального рабочего каталога. Просто так нет никакой возможности, что ваши приложения ищут неправильные каталоги, выполняя свою работу.
При этом, если у вас все еще есть та же проблема, то я предлагаю вам App3 вывести фактические параметры командной строки, которые он получил (MessageBox()
, OutputDebugString (), файл и т. Д.). Возможно, он получает что-то отличное от ожидаемого или неправильно анализирует параметры.
Наконец, на заметку, вы можете заменить Sleep()+GetExitCodeProcess()
цикл с одним вызовом WaitForSingleObject()
(или же MsgWaitForMultipleObjects()
если вам нужно запустить цикл обработки сообщений во время ожидания), а затем вызвать GetExitCodeProcess()
один раз после этого, чтобы получить окончательный результат, если необходимо:
if ShellExecuteEx( @exInfo ) then
begin
if WaitForSingleObject(exinfo.hProcess, INFINITE) = WAIT_OBJECT_0 then
GetExitCodeProcess( exinfo.hProcess, exitcode );
CloseHandle( exinfo.hProcess );
end;