Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  

Показать сообщение отдельно

Модер


Сообщения: 1716
Благодарности: 17

Профиль | Сайт | Отправить PM | Цитировать


mj
Цитата:
не спорь если не знаешь...
Давай подискутируем на тему, "необходимо ли вызывать CloseHandle если удачно вызвался OpenProcess". Идем на msdn.microsoft.com и не путаем остальных.

Итак.

Так как ВСЕ объекты ядра (в том числе процесы) поддерживают подсчет ссылок, то для корректного уничтожения объекта в памяти необходимо для каждого открытия его вызывать фукнцию ZwClose (она вызывается из CloseHandle).

Если процесс создан, то после удачного вызова TerminateProcess он не перестает существовать. В этом легко убедиться, так как после этого хэндл этого процесса продолжает быть валидным, то есть, можно, например, вызвать некоторые классы информации для ZwQueryInformiationProcess (вышележащие функции ее вызывают, например, для получения ExitCode для процесса и времен создания/ работы в UserMode/ KernelMode/ завершения). Если бы объекта ядра "процесс" не существовало, такое получение информации было бы невозможным. Система может узнать, что сам объект можно уничтожить, только если счетчик ссылок на него обнулится. Именно поэтому и надо вызывать CloseHandle независимо от результата TerminateProcess (иначе эта ссылка вычтется только при завершении процесса, который этот хэндл открыл).

Цитата:
Есть и другие более точные методы поисха handle
Ага, особено если и искать не надо. А если есть 2 нотепада, у обоих заголовок - "Untitled-notepad", как ты выберешь, какой прибить, если прибить надо ровно один (например, задача не позволить запускать более одного блокнота)? Необходимо в начальной постановке указывать, например, что он запущен под тем же пользователем, или родитель у него- текущий процесс. Тем более что FindWindow ни при каких обстоятельствах не ищет окна, принадлежащие другой пользовательской сессии (то есть, на другой оконной станции, например, если зашел терминальный юзер или служба выполняется под выделенной учетной записью или системной неинтерактивной), а неименованный десктоп может создать ЛЮБОЙ пользователь в системе, и FindWindow тут обломается найти окно по полной программе. Короче, 2 балла за матчасть.

Цитата:
Если бы он его создавал сам, то и закрыть было бы не проблема...
Проблема, если бы запускал через WinExec или ShellExecute. Они не возвращают хэндл процесса.

Цитата:
услышал где то, что есть функция TerminateProcess, значит теперь всё можешь ей убивать?
Нет. Ей можно завершить процесс, если удастся открыть его с правом TERMINATE и если он не завис на любом системном примитиве синхронизации в ядре. Если процесс работает и есть привилегия отладки, завершить ей можно любой процесс кроме псевдопроцесса SYSTEM (его с указанным правом не открыть) и IDLE (его вообще не открыть, так как у него нулевой идентификатор). А то что кому-то кажется, что там не так все просто - это личные проблемы каждого, а мне все же интересно, что же там может быть такого сложного, что необходимо отказываться от правильной системы подсчета ссылок.

Цитата:
и делаю SENDMESSAGE
В общем случае неверно. Ты такой командой закрываешь окно. А если у программы несколько равнозначных окон (или, по другому, нет главного) - то тебе придется посылать WM_CLOSE им всем.
В зависимости от постановки задачи, может быть можно вызвать GetWindowThreadProcessId и потом OpenProcess/ TerminateProcess/ CloseHandle, а может надо после GetWindowThreadProcessId вызывать EnumWindows и для каждого из них вызывать GetWindowThreadProcessId чтобы каждому не дочернему окну в этом процессе посылать WM_CLOSE. Короче, это уже от задачи зависит. А может будет точнее идентифицировать процесс по имени файла, образ которого он исполняет? Например, не "Untitled-notepad", а notepad.exe?

-------
Васкецов Сергей
http://registry.oszone.net


Отправлено: 00:37, 21-07-2003 | #8