Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.118.136.46] |
|
Сообщ.
#1
,
|
|
|
Прошу помочь. Много лет пользуюсь загрузчиком для оперы собственной разработки, но появилась проблема. Раньше запускал опера.exe функцией CreateProcess, получал хендл дочернего процесса и его контролировал. Но теперь Опера нахимичила и получается что после запуска процесса опера.ехе похоже запускает дочерний процесс и сама убивается. В результате родителем дерева процессов Опера становится десктоп. Как мне гарантировано отследить это и остаться родительским процессом имея хендл процесса, которого я напрямую не создавал??
Просто желающие помочь скачайте с сайта оперы последнюю версию и запустите ее через CreateProcess и сами поймете, посмотрев дерево процессов. Последняя нормально запускаемая версия оперы - 44.0.2510.1449. |
Сообщ.
#2
,
|
|
|
Имхо, разве что хукать CreateProcess.
|
Сообщ.
#3
,
|
|
|
пример можешь?
|
Сообщ.
#4
,
|
|
|
Неа, сам никогда не делал. Гугли, и обрящешь
|
Сообщ.
#5
,
|
|
|
Цитата avlid @ после запуска процесса опера.ехе похоже запускает дочерний процесс и сама убивается. Как мне гарантировано отследить это и остаться родительским процессом имея хендл процесса, которого я напрямую не создавал?? Отследить самоубийство - просто (по WaitForSingleObject и/или GetExitCodeProcess). После самоубийства можно найти дочерний процесс по известному имени и\или пути к исполняемому файлу (или подгружаемым им dll), используя ToolHelp АПИ (CreateToolhelp32Snapshot, Process32First\Next, Module32First\Next). Найдя процесс, можно его открыть и получить хэндл (через OpenProcess). Вот только "остаться родительским процессом" при этом (просто так) не получится. Да и нужно ли тебе это? |
Сообщ.
#6
,
|
|
|
Все правильно, только вот проблема - если я остаюсь родитель, я без труда его прибиваю. В ином случае это не гарантируется. По крайней мере у меня. Я делаю так:
procedure CreateWin9xProcessList(List: TstringList); var hSnapShot: THandle; ProcInfo: TProcessEntry32; begin if List = nil then Exit; hSnapShot := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapShot <> THandle(-1)) then begin ProcInfo.dwSize := SizeOf(ProcInfo); if (Process32First(hSnapshot, ProcInfo)) then begin List.Add(ProcInfo.szExeFile); while (Process32Next(hSnapShot, ProcInfo)) do List.Add(ProcInfo.szExeFile); end; CloseHandle(hSnapShot); end; end; procedure CreateWinNTProcessList(List: TstringList); var PIDArray: array[0..1023] of DWORD; cb: DWORD; I: Integer; ProcCount: Integer; hMod: HMODULE; hProcess: THandle; ModuleName: array[0..300] of Char; begin if List = nil then Exit; EnumProcesses(@PIDArray, SizeOf(PIDArray), cb); ProcCount := cb div SizeOf(DWORD); for I := 0 to ProcCount - 1 do begin hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PIDArray[I]); if (hProcess <> 0) then begin EnumProcessModules(hProcess, @hMod, SizeOf(hMod), cb); GetModuleFilenameEx(hProcess, hMod, ModuleName, SizeOf(ModuleName)); List.Add(ModuleName); CloseHandle(hProcess); end; end; end; procedure GetProcessList(var List: TstringList); var ovi: TOSVersionInfo; begin if List = nil then Exit; ovi.dwOSVersionInfoSize := SizeOf(TOSVersionInfo); GetVersionEx(ovi); case ovi.dwPlatformId of VER_PLATFORM_WIN32_WINDOWS: CreateWin9xProcessList(List); VER_PLATFORM_WIN32_NT: CreateWinNTProcessList(List); end end; function TerminateProgram(dwPID: DWORD; dwTimeout: DWORD): DWORD; const TA_FAILED = 0; TA_SUCCESS_CLEAN = 1; TA_SUCCESS_KILL = 2; TA_SUCCESS_16 = 3; var hProc: THandle; function TerminateProgramEnum(Window: HWND; lParam: LPARAM): Bool; stdcall; var dwID: DWORD; begin GetWindowThreadProcessId(Window, @dwID); if dwID = DWORD(lParam) then PostMessage(Window, WM_CLOSE, 0, 0); Result := True; end; begin hProc := OpenProcess(SYNCHRONIZE or PROCESS_TERMINATE, FALSE, dwPID); if (hProc <> 0) then try EnumWindows(@TerminateProgramEnum, dwPID); if WaitForSingleObject(hProc, dwTimeout) <> WAIT_OBJECT_0 then begin if TerminateProcess(hProc, 0) then Result := TA_SUCCESS_KILL else Result := TA_FAILED end else Result := TA_SUCCESS_CLEAN finally CloseHandle(hProc) end else Result := TA_FAILED end; function KillTask(ExeFileName: string): integer; const PROCESS_TERMINATE = $0001; var ContinueLoop: BOOL; FSnapshotHandle: THandle; FProcessEntry32: TProcessEntry32; begin result := 0; FSnapshotHandle := CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); FProcessEntry32.dwSize := Sizeof(FProcessEntry32); ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); while integer(ContinueLoop) <> 0 do begin if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then result := TerminateProgram(FProcessEntry32.th32ProcessID, 0); ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32); end; CloseHandle(FSnapshotHandle); try WinExec(PANsiChar('TASKKILL /F /IM ' + ExeFileName), SW_HIDE); except end; end; И еще. Я запускаю оперу с разными профилями, в том чисте на шифрованный контейнер. Мне нужно четко понимать какой экземпляр оперы я запустил. По имени файла это не получится. Надо тогда что то мутить в командной строке, и потом у процесса ее раскладывать наверно... |
Сообщ.
#7
,
|
|
|
avlid,
M Используем тег [code] для добавления текста программы в пост! Устное предупреждение! Читаем правила! |