Форум: "Основная";
Текущий архив: 2007.08.05;
Скачать: [xml.tar.bz2];
ВнизКак дождаться запуска приложения ? Найти похожие ветки
← →
BFG9k © (2007-05-23 15:33) [0]Как запустить программу и дождаться ее запуска ? Обращаю внимание: не завершения работы, а именно запуска, то есть когда она до конца загрузится.
← →
clickmaker © (2007-05-23 15:36) [1]WaitForInputIdle()?
← →
Сергей М. © (2007-05-23 15:46) [2]
> BFG9k © (23.05.07 15:33)
> Как запустить программу и дождаться..когда она до конца загрузится
Никак.
WinAPI не предоставляет польз.интерфейса для мониторинга выполнения именно этого этапа.
← →
BFG9k © (2007-05-23 16:27) [3]clickmaker, спасибо.
Сергей М., сколько уверенности ..... :)
← →
Kedge © (2007-05-23 20:32) [4]>[0] BFG9k © (23.05.07 15:33)
>то есть когда она до конца загрузится.
http://delphimaster.net/view/2-1178820436/
← →
antonn (work) (2007-05-23 20:50) [5]если запускаемая программа своя и мониторящая своя, то в запускаемой в "момент окончательной загрузки" можно создавать семафор и искать его переодически в мониторящей
← →
Юрий Зотов © (2007-05-23 21:19) [6]> BFG9k © (23.05.07 16:27) [3]
А зря упрекаете. WaitForInputIdle может и не помочь, так что Сергей М. вполне может оказаться не менее правым, чем clickmaker.
← →
Сергей М. © (2007-05-24 08:20) [7]
> BFG9k © (23.05.07 16:27) [3]
Куда ж без нее)
← →
SpellCaster (2007-05-24 11:25) [8]> [6] Юрий Зотов © (23.05.07 21:19)
> WaitForInputIdle может и не помочь
А в каких случаях это может случиться?
← →
clickmaker © (2007-05-24 11:31) [9]да может и не помочь. Это всего лишь означает, что приложение запустило цикл обработки сообщений и в очереди нет необработанных, т.е. оно готово к приему информации извне.
Для консольных и без цикла выборки сообщений функция вообще смысла не имеет.
Так что уточнения требует момент "когда она до конца загрузится" - что под этим понимать?
Формально, если WinMain / main() стартовала, это значит, что приложение уже загрузилось
← →
Юрий Зотов © (2007-05-24 13:34) [10]> SpellCaster (24.05.07 11:25) [8]
См. описание функции в справке Win32 SDK или [9].
← →
Leonid Troyanovsky © (2007-05-24 18:04) [11]
> antonn (work) (23.05.07 20:50) [5]
> семафор и искать его переодически в мониторящей
Удобней взять событие (наследуемое) и пускать
дочерний процесс с наследованием хендлов.
Значение хендла можно передать, например в комстроке.
Тогда дочернему процессу достаточно сделать SetEvent
в числе первого выполняемого кода.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2007-05-24 18:10) [12]
> clickmaker © (24.05.07 11:31) [9]
> Для консольных и без цикла выборки сообщений функция вообще
> смысла не имеет.
Для некоторых консольных - имеет.
> Формально, если WinMain / main() стартовала, это значит,
> что приложение уже загрузилось
Во-ще-то, в [4] есть верная ссылочка, бо уважаемая Riply ©
недавно с этим воевала и могла б про это рассказать.
Но, видимо, просматривает она только "Начинающих".
--
Regards, LVT.
← →
Riply © (2007-05-25 07:40) [13]>[12] Leonid Troyanovsky © (24.05.07 18:10)
> Riply © недавно с этим воевала и могла б про это рассказать.
> Но, видимо, просматривает она только "Начинающих".
Заглядываю и сюда. Вот объявилась :)
Что рассказыать не знаю, т.к. в http://delphimaster.net/view/2-1178820436/
весь процесс попытки поймать "момент окончания инициализации процесса" разобран по косточкам.
Можно только более подробно расписать схему поимки, предложенную Leonid Troyanovsky,
и поделиться результатами тестирования.
Подготавливаем APCProc, примерно такого вида:
procedure APCProc(dwParam: Dword); stdcall;
var
OldState: Boolean;
begin
with PInjectInfo(dwParam) do
begin
...............................
LastStatus := _NtSetEvent(hReadyEvent, @OldState);
if LastStatus <> STATUS_INVALID_HANDLE then
begin
LastStatus := _NtClose(hReadyEvent);
hReadyEvent := 0;
end;
end;
end;
"Требования к коду APCProc такие же, как в случае с CRT."
Создаем процесс:
CreateProcess(..., CREATE_SUSPENDED, ..., Proc_Info);
Создаем hEvent, сигнал котрого будем ожидать:
hEvent := CreateEvent(nil, True, False, nil);
"Дупликатим" его :)
DuplicateHandle(GetCurrentProcess, hEvent, Proc_Info.hProcess, @hDupEvent, 0, False, DUPLICATE_SAME_ACCESS)
Пишем в адресное пространство жертвы структуру TInjectInfo, содержащую
1. Адреса функций, которые будем использовать в APCProc
2. hDupEvent - дубликат нашего hEvent
3. Всякие полезные мелочи :)
4. и сам код нашей APCProc
Proc_WriteMemory(Proc_Info.hProcess, pInjectInfo, TmpSize, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE, pRemoteData)
У меня она выглядит, примерно так:
type
PInjectInfoBase = ^TInjectInfoBase;
TInjectInfoBase = packed record
......
NtFuntionsTable: TNtFunctTable;
hReadyEvent: THandle;
LastStatus: NTSTATUS;
RetResult: DWord;
......
function pInjectTreadCode: Pointer;
end;
function TInjectInfoBase.pInjectTreadCode: Pointer;
begin
Result := Pointer(DWord(@Self) + SizeOf(TInjectInfoBase));
end;
Где TNtFunctTable - стуктура, содержащая адреса Nt или kernel32 - функций.
TNtFunctTable = packed record
_RtlGetLastNtStatus: function: NTSTATUS; stdcall;
_NtSetEvent: function(EventHandle: THANDLE; OldState: PBOOLEAN): NTSTATUS; stdcall;
................................... и т. д.
Создаем нить в теле жертвы:
QueueUserAPC(PInjectInfoBase(pRemoteData).pInjectTreadCode, Proc_Info.hThread, DWord(pRemoteData))
Будим целевой процесс:
ResumeThread(Proc_Info.hThread)
И ждем срабатывания нашего hEvent - а.
WaitArr := Make_Int64(Proc_Info.hProcess, hEvent);
WaitResult := WaitForMultipleObjects(2, @WaitArr, False, TimeOut);
Вот, вроде, и все.
У меня все работает "на ура". Тестировала на самых разных(специально для этого созданных) процессах.
Как и говорил Leonid Troyanovsky:
"APCProc срабатывает _непосредственно_после_инициализации процесса, но _до_выполнения main & etc" :)
>[0] BFG9k © (23.05.07 15:33)
Будут вопросы - задавай.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2007.08.05;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.041 c