Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.117.196.184] |
|
Страницы: (3) [1] 2 3 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Господа вопрос такой. Есть процесс.
Как узнать процесс родителя. Тоесть узнать имя процесса запустившего мою программу. Хотел написать плагин для Internet explorer'а, где если бы программа запускалась с параметром -d то сразу программа определяла что программу запустил Internet explorer,ан нет оказываеться нет. Там в ветви Software\Microsoft\Internet Explorer\Extensions, добавляються программы на исполнение, без дополнительных параметров, то есть не гибкий однако Internet explorer. Вопрос: Может есть у кого наработки на узнавание родителя процесса. Спросите вы, что мне лень. Да нет с TlHelp32 работал, просто чьйто наработки могут быть полезны для меня, и для других, кто дальше столкнеться с данной проблемой... Добавлено Я люблю, когда появляються задачи по программированию.. Но тут немного в невиддении насчет родителя.. |
Сообщ.
#2
,
|
|
|
Да в плагины гораздо логичнее передавать какой-то интерфейс (не обязательно в прямом смысле слова) основного приложения, а не хаками это определять.
Цитата SOLON7 @ то есть не гибкий однако Internet explorer Да что вы говорите, с каких это пор динамические библиотеки (DLL) стали запускаться с параметрами коммандной строки? Добавлено Где в LoadLibrary вы увидели параметры коммандной строки? |
Сообщ.
#3
,
|
|
|
Ничего не поняла насчет "плагин для Internet explorer'а" и "не гибкости Internet explorer"
Посему, попробую ответить на "Тоесть узнать имя процесса запустившего мою программу." Раз любишь задачки, то вот для затравки набросала ф-ию поиска ID родителя: (не тестировала) function GetMyParentID(var ParentID: DWord): DWord; var ProcEntry: TProcessEntry32; hSnapshot: THandle; CurrID: DWord; _OK: Boolean; begin hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if hSnapshot <> INVALID_HANDLE_VALUE then try ProcEntry.dwSize := SizeOf(ProcEntry); _OK := Process32First(hSnapshot, ProcEntry); if _OK then begin CurrID := GetCurrentProcessId; SetLastError(ERROR_SUCCESS); while _OK do if ProcEntry.th32ProcessID = CurrID then begin ParentID := ProcEntry.th32ParentProcessID; Break; end else _OK := Process32Next(hSnapshot, ProcEntry); end; Result := GetLastError; finally CloseHandle(hSnapshot); end else Result := GetLastError; end; Ну а чуть-чуть ее видоизменить для нахождения имени родителя по его ID оставляю в качестве домашего задания P.S. Только проку от данной методики, как от козла молока. Процесса родителя уже может и не быть в помине, пока мы тут соизволяем его искать И полученный нами ID, можно выбрасывать на помойку. Гораздо лучше использовать NtQuerySystemInformation с параметром SystemProcessesAndThreadsInformation - можно обойтись одним "снимком". Правда и с CreateToolhelp32Snapshot можно, но придется запоминать ProcEntry`ы. P.S.S. >Да нет с TlHelp32 работал >Я люблю, когда появляються задачи по программированию.. >Но тут немного в невиддении насчет родителя.. Ой как "не вяжутся" эти три фразы (особенно учитывая, что в Help`е есть пример Забыла еще одну неприятную вещь: Может получиться так, что к моменту нашего поиска, родитель уже умрет, и будет создан другой процесс с такм же ID, как и у родителя. А вот чтобы не попасть впросак с этим, придется использовать NtQuerySystemInformation и сравнивать времена создания найденого нами родителя и наше. |
Сообщ.
#4
,
|
|
|
Цитата Riply @ Забыла еще одну неприятную вещь: Может получиться так, что к моменту нашего поиска, родитель уже умрет, и будет создан другой процесс с такм же ID, как и у родителя. Да вы что, а разве PID не растет с каждым новым запуском нового процесса, как-то не вяжется, чтобы PID был одинаков у процессов, это было по крайне мере глупо со стороны MICROSOFT делать такое. Процесса может быть уже убит, но чтобы pid были одинаковы не вериться... Добавлено Я нашел пожалуй самый легкий метод определения, как узнавать запущенна ли прога из интернет експлорер. При запуске из ИНтернет Експолера не передаеться параметр "Рабочий каталог". То есть можно проверить если рабочий каталог неравен Extractfilepath(paramstr(0)) то значит его запустил ИНтернет Експолера. Да твик не гибкий, но простой и не требующих мозломства. RIPLY, а вы что преподователь, изложили все в такой форме, красиво. Мне кажеться вы преподователь, или по крайне мере имеете его задатки... ВСЕМ СПАСИБО ПЛАН РАБОТЫ НАМЕЧЕН, БУДЕМ РАБОТАТАТЬ. |
Сообщ.
#5
,
|
|
|
Цитата SOLON7 @ Да вы что, а разве PID не растет с каждым новым запуском нового процесса Нет. В общем случае это не так. Цитата SOLON7 @ как-то не вяжется, чтобы PID был одинаков у процессов У двух процессов, существовавших одновременно в некий момент времени, одинаковых ID быть не может. Но эта ситуация вполне реальна, для процессов, разнесенных во времени. Кстати, вероятность этого не так уж мала, как кажется. Цитата SOLON7 @ Я нашел пожалуй самый легкий метод определения, как узнавать запущенна ли прога из интернет експлорер. При запуске из ИНтернет Експолера не передаеться параметр "Рабочий каталог". То есть можно проверить если рабочий каталог неравен Extractfilepath(paramstr(0)) то значит его запустил ИНтернет Експолера Этот способ определения череват ошибками, imho. Ибо из факта "если рабочий каталог неравен Extractfilepath(paramstr(0))" отнюдь не следует, что нас запустил IE. |
Сообщ.
#6
,
|
|
|
Цитата Да вы что, а разве PID не растет с каждым новым запуском нового процесса, как-то не вяжется, чтобы PID был одинаков у процессов Riply абсолютно права. Я к сожелению не смог найти прямого ответа в MSDN, там весьма уклончиво отвечают на этот вопрос - "The identifier is valid from the time the process is created until the process has been terminated." Эту фразу, в принципе, можно понять по разному. Зато недвусмысленно это описано у Рихтера, так что сошлемся на его авторитет: Подчеркну ещс один чрезвычайно важный момент система способна повторно использовать идентификаторы процессов и потоков. Например, при создании про цесса система формирует объект "процесс", присваивая ему идентификатор со зна чением, допустим, 122 Создавая новый объект "процесс", система уже не присвоит ему данный идентификатор. Но после выгрузки из памяти первого объекта следу ющему создаваемому объекту "процесс" может быть присвоен тот же идентификатор — 122. Эту особенность нужно учитывать при написании кода, избегая ссылок на невер ный объект "процесс" (или "поток"). Действительно, затребовать и сохранить иден тификатор процесса несложно, но задумайтесь, что получится, ссли в следующий момент этот процесс будет завершен, а новый получит тот же идентификатор: сохра ненный ранее идентификатор уже связан совсем с другим процессом. |
Сообщ.
#7
,
|
|
|
Узнать родителя любого процесса можно и без перебора процессов в снимке. Например вот так:
type PROCESS_BASIC_INFORMATION = packed record ExitStatus: DWORD; PebBaseAddress: Pointer; AffinityMask: DWORD; BasePriority: DWORD; uUniqueProcessId: Ulong; uInheritedFromUniqueProcessId: Ulong; end; function NtQueryInformationProcess( ProcessHandle : THandle; ProcessInformationClass : Byte; ProcessInformation : Pointer; ProcessInformationLength : ULONG; ReturnLength : PULONG ): DWORD; stdcall; external 'ntdll.dll'; function GetOwnedProcessID(const dwProcessHandle: DWORD): DWORD; const ProcessBasicInformation = 0; var Info: PROCESS_BASIC_INFORMATION; begin Result := 0; if NtQueryInformationProcess(dwProcessHandle, ProcessBasicInformation, @Info, SizeOf(Info), nil) = NO_ERROR then Result := Info.uInheritedFromUniqueProcessId; end; Вот так будет выглядеть получение родителя от текущего процесса: procedure TForm1.Button1Click(Sender: TObject); var dwProcessHandle: DWORD; begin DuplicateHandle(GetCurrentProcess, GetCurrentProcess, GetCurrentProcess, @dwProcessHandle, 0, False, DUPLICATE_SAME_ACCESS); Caption := IntToStr(GetOwnedProcessID(dwProcessHandle)); end; |
Сообщ.
#8
,
|
|
|
Rouse_
DuplicateHandle не обязательно. NtQueryInformationProcess прекрасно съедает и псевдохэндл. |
Сообщ.
#9
,
|
|
|
Rose, согласен...
|
Сообщ.
#10
,
|
|
|
Цитата Rouse_ @ Узнать родителя любого процесса можно и без перебора процессов в снимке. Например вот так: А мы не привыкли искать легкие пути А если серьезно, то мне это просто не пришло в голову. Спасибо. |
Сообщ.
#11
,
|
|
|
НУ родителя мы то узнаем, а как узнать является ли процесс Internet Explorer....
|
Сообщ.
#12
,
|
|
|
GetModuleFileNameEx очевидно
|
Сообщ.
#13
,
|
|
|
А какой же быстрый способ узнать по ПИДУ имя процесса.
Какую функцию по обьему кода посоветуете???? Чтоб поменьше кода было.... |
Сообщ.
#14
,
|
|
|
Тэкссс... тебе уже много насоветовали. Давай сначала посмотрим, понял ли ты все это. Выкладывай аттачем код, с которым сейчас эксперементируешь...
|
Сообщ.
#15
,
|
|
|
Вобщем если я правильно понял автору нужно что-то врое этого:
const ProcessBasicInformation = 0; CSIDL_PROGRAM_FILES = $0026; IExplorePath: string = '\Internet Explorer\IEXPLORE.EXE'; type PROCESS_BASIC_INFORMATION = packed record ExitStatus: DWORD; PebBaseAddress: Pointer; AffinityMask: DWORD; BasePriority: DWORD; uUniqueProcessId: Ulong; uInheritedFromUniqueProcessId: Ulong; end; function NtQueryInformationProcess( ProcessHandle : THandle; ProcessInformationClass : Byte; ProcessInformation : Pointer; ProcessInformationLength : ULONG; ReturnLength : PULONG ): DWORD; stdcall; external 'ntdll.dll'; function GetModuleFileNameExA( hProcess: DWORD; hModule: DWORD; lpFilename: PAnsiChar; nSize: DWORD ): DWORD; stdcall; external 'PSAPI.dll'; function OwnerProcessIs_IExplore: Boolean; var lInfo: PROCESS_BASIC_INFORMATION; lParentProcHandle: THandle; lpFileName, lPFPath: PAnsiChar; dwProcessHandle: DWORD; begin Result := False; ZeroMemory(@lInfo, SizeOf(PROCESS_BASIC_INFORMATION)); DuplicateHandle(GetCurrentProcess, GetCurrentProcess, GetCurrentProcess, @dwProcessHandle, 0, False, DUPLICATE_SAME_ACCESS); if NtQueryInformationProcess(dwProcessHandle, ProcessBasicInformation, @lInfo, SizeOf(PROCESS_BASIC_INFORMATION), nil) = NO_ERROR then begin lParentProcHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, lInfo.uInheritedFromUniqueProcessId); if lParentProcHandle > 0 then begin lpFileName := GetMemory(MAX_PATH); ZeroMemory(lpFileName, MAX_PATH); lPFPath := GetMemory(MAX_PATH); ZeroMemory(lPFPath, MAX_PATH); if SHGetSpecialFolderPath(0, lPFPath, CSIDL_PROGRAM_FILES, False) and (GetModuleFileNameExA(lParentProcHandle, 0, lpFileName, MAX_PATH) > 0) then Result := lPFPath + IExplorePath = lpFileName; FreeMemory(lpFileName); FreeMemory(lPFPath); end; CloseHandle(lParentProcHandle); end; CloseHandle(dwProcessHandle); end; Добавлено Цитата DuplicateHandle не обязательно. NtQueryInformationProcess прекрасно съедает и псевдохэндл. Кстати пока отлаживал, псевдохендл не всегда отрабатывал(закономерности не понял), и NtQueryInformationProcess выкидывало с "неверный декриптор". Пришлось DublicateHandle все-таки оставить. |